リスト4.4に倣って以下のプログラムを作成し、ast.c, printast.cならびにbisonが出力したpicoc1.tab.cファイルとともにコンパイルする。yydebugが未定義であるという内容のエラーが出た場合には、-t -dオプションをつけてbisonを実行しなおす。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ast.h"
#include "gen.h"
#include "printast.h"
/* bison -d -t が出力したヘッダーファイルをインクルードする */
#include "picoc1.tab.h"
FILE *af;
ExprNodePtr ex;
typedef struct Tokens {
int sort;
int ival;
char *name;
} Ttokens;
#define T_T(t) { t, 0, NULL }
#define T_INT(k) { NUM, k, NULL }
#define T_ID(n) { ID, 0, n }
#define T_CH(c) { c, 0, NULL }
/* (-3*k)%4==3&&x<k-k/7 を表すトークンの配列 */
Ttokens thetokens[]={
T_CH('('),T_T(SUB),T_INT(3),T_T(MUL),T_ID("k"),T_CH(')'),
T_T(MOD),T_INT(4),T_T(BEQ),T_INT(3),T_T(LAND),T_ID("x"),
T_T(BLT),T_ID("k"),T_T(SUB),T_ID("k"),T_T(DIV),T_INT(7),
T_CH(0) };
int yylex() {
static int i=0;
Ttokens *p = thetokens + i;
i++;
if(p->sort ==NUM)
yylval.ival = p->ival;
else if(p->sort==ID)
yylval.name = p->name;
return p->sort;
}
/* もし、bisonへの入力ファイル、例えばpicoc1.yでyyerror()の中身を定義していなければ、
リンク時にundefined reference to yyerrorといった内容のエラーが出る。
その場合は次の行の #if 0 を #if 1 に書き換えてyyerrorの定義を有効化する */
#if 0
int yyerror( char *msg ){
fprintf( stderr, msg );
exit( 1 );
}
#endif
int main( int argc, char **argv ){
/* もし、コンパイル時にyydebugが未定義である内容のエラーが出たら、
bisonをbison -t -d picoc1.yのように実行しなおしてみる。
それでもダメだったら、下の行の#if 1を#if 0に書き換える */
#if 1
int i;
for( i=1; i<argc; i++ ){
if( strcmp( argv[i], "-d" )==0 ) yydebug = 1;
}
#endif
/* 以下にthetokensに記述した関数と変数の定義を記述 */
symAdd( SYM_VAR, "k", 0, 0, 0, NULL );
symAdd( SYM_VAR, "x", 1, 0, 0, NULL );
/* 構文解析を実行 */
if( yyparse() ) return EXIT_FAILURE;
/* 結果を出力 */
printASTExpr( argc, argv, ex );
return EXIT_SUCCESS;
}