←4.4.4節の確認 | ↑目次 | →bisonの警告

情報科学実験II コンパイラ作成

第4回

課題4.4の結果を確認する方法

printast.tgzに、構文木をテキスト、グラフ、またはCプログラムとして出力するプログラムを載せる。これを用いて課題4.4の結果を確認する手順を示す。
  1. 4.4.4節で作成したpicoc2.yのルール部からlineの部分を削除する。4.4.5節、4.4.6節の内容にしたがって書き加えてpicoc.yとして保存する。programから始まる部分をルール部の先頭に書くか、あるいは、定義部の末尾辺りに、
    %start program
    
    を加える。これをしないと大量の警告が出されるだろう。このようにしてできたファイルを
    bison -t -d picoc.y
    
    で処理する。
    picoc.y: 警告: 1 shift/reduce conflict [-Wconflicts-sr]
    
    というエラーが出てもよい。ただし、shift/reduceの前の数が2以上だったら修正が必要である。
  2. リスト4.4を補って以下のプログラムを作成し、ast.c, gen.c, printast.cならびにbisonが出力したpicoc.tab.cファイルとともにコンパイルする。ただし、main()関数内でelse genCode()を削除すれば、gen.cは不要。
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "ast.h"
    #include "gen.h"
    #include "printast.h"
    #if YYDEBUG
    extern int yydebug;
    #endif
    /* bison -d -tが出力したヘッダーファイルをインクルードする */
    #include "picoc.tab.h"
    extern DefNodePtr sourcedefs;
    FILE  *af;
    
    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 }
    
    Ttokens thetokens[]={
    	T_T(TINT),T_ID("in"),T_CH('('),T_CH(')'),T_CH(';'),
    	T_T(TINT),T_ID("out"),T_CH('('),T_T(TINT),T_ID("x"),T_CH(')'),T_CH(';'),
    	T_T(TINT),T_ID("fib"),T_CH('('),T_T(TINT),T_ID("k"),T_CH(')'),T_CH('{'),
    	T_T(IF),T_CH('('),T_ID("k"),T_T(BLT),T_INT(2),T_CH(')'),T_CH('{'),T_T(RETURN),T_INT(1),T_CH(';'),T_CH('}'),
    	T_T(RETURN),T_ID("fib"),T_CH('('),T_ID("k"),T_T(SUB),T_INT(2),T_CH(')'),
    		T_T(ADD),T_ID("fib"),T_CH('('),T_ID("k"),T_T(SUB),T_INT(1),T_CH(')'),T_CH(';'),
    	T_CH('}'),
    	T_T(TINT),T_ID("main"),T_CH('('),T_CH(')'),T_CH('{'),
    	T_T(TINT),T_ID("v"),T_CH(';'),
    	T_ID("v"),T_T(ASSIGN),T_ID("in"),T_CH('('),T_CH(')'),T_CH(';'),
    	T_ID("out"),T_CH('('),T_ID("fib"),T_CH('('),T_ID("v"),T_CH(')'),T_CH(')'),T_CH(';'),
    	T_T(RETURN),T_INT(0),T_CH(';'),
    	T_CH('}'),
    	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への入力ファイル、例えばpicoc.yでyyerror()の中身を定義していれば、
    multiple definition of `yyerror'などのコンパイルエラーが出る。その場合は
    ここでの定義は不要なので、mainの前までを削除する */
    int yyerror( char *msg ){
    	fprintf( stderr, msg );
    	exit( 1 );
    }
    
    int main( int argc, char **argv ){
    #if YYDEBUG
    int i;
    	for( i=1; i<argc; i++ ){
    		if( strcmp( argv[i], "-d" )==0 ) yydebug = 1;
    	}
    #endif
    	af = stdout;
    	/* 構文解析を実行 */
    	if( yyparse() ) return EXIT_FAILURE;
    	/* 結果を出力 */
    	if( argc > 1 ) printASTDef( argc, argv, sourcedefs );
    	else genCode();
    	return EXIT_SUCCESS;
    }
    
  3. その結果できたファイル(この例ではkadai44と仮定する)を実行するときに、

リスト4.4の構文解析を他のプログラムに対しても実行するには

以下のボックスにリスト3.8のようなCのプログラムを入力してOkボタンをクリックすると、Ttokens thetokens配列の内容が出力されます。
Ttokens出力
トップページ