数式の評価を便利な道具で #12

YYSTYPEをdefineするのではなく%union宣言をわざわざ使っているのは、
defineでは字句定義のヘッダファイルにYYSTYPEの定義が挿入されないことにもある。

「にもある」と書いたように理由は他にもある。

#include <stdio.h>

typedef int int_t[1];

int main(void)
{
    int_t i, j;
    *i = 123;
    *j = 456;
    printf("%d %d\n", *i, *j);
    *j = *i;
    printf("%d %d\n", *i, *j);
    return 0;
}

このコードで定義したint_t型は1個のint型の要素からなる配列である。
iもjも配列の名前なので、

    j = i;

のような代入は当然許されない。
GMPのmpz_t型もこのint_t型と同じような形式で型が定義されている。
mpz_tではintの代わりに多倍長整数を実装するためのデータをまとめた構造体になっているだけである。
つまりmpz_t型として宣言されたものは1個の構造体を要素とする配列の名前となる。
ところが、単純にYYSTYPEをmpz_tとdefineしたのではBisonが出力するコード中に、
上述したものより複雑だが基本的に同じような代入を行うコードが生成されてしまう。
YYSTYPEの定義を工夫すればdefineする方法も可能だろうけれど、
%union宣言を使って共用体のメンバとして囲ってしまう方が簡単でいいと思う。