←課題4.3の確認 | ↑目次 | →課題4.4の確認

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

第4回

4.4.4節までの結果を確認する方法

printast.tgzに、構文木をテキスト、グラフ、またはCプログラムとして出力するプログラムを載せる。これを用いて4.4.4節までの結果を確認する手順を示す。
  1. 課題4.3で作成したpicoc1.yのlineの部分を次のように書き換えてpicoc2.yとして保存する。
    line
    	: st_list { extern StmtNodePtr st; st = $1; }
    	;
    
    このようにしてできたファイルを
    bison -t -d picoc2.y
    
    で処理する。
    picoc.y: 警告: 1 shift/reduce conflict [-Wconflicts-sr]
    
    というエラーが出てもよい。ただし、shift/reduceの前の数が2以上だったら修正が必要である。
  2. リスト4.4に倣って以下のプログラムを作成し、ast.c, printast.cならびにbisonが出力したpicoc2.tab.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 "picoc2.tab.h"
    FILE  *af;
    StmtNodePtr st;
    
    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 }
    
    /* 
    	if( k<2 ){ return 1; }
    	return fib(k-2)+fib(k-1);
    を表すトークンの配列 */
    
    Ttokens thetokens[] = {
    	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(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
    	/* 以下にthetokensに記述した関数と変数の定義を記述 */
    	symAdd( SYM_FUNC, "fib", 1, 1, 0, NULL );
    	symAdd( SYM_VAR, "k", 0, 0, 0, NULL );
    
    	/* 構文解析を実行 */
    	if( yyparse() ) return EXIT_FAILURE;
    	/* 結果を出力 */
    	printASTStmt( argc, argv, st );
    	return EXIT_SUCCESS;
    }
    
  3. その結果できたファイル(この例ではkadai43bと仮定する)を実行するときに、

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

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