←課題4.1,4.2のヒント | ↑目次 | →4.4.4節の確認

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

第4回

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

printast.tgzに、構文木をテキスト、グラフ、またはCプログラムとして出力するプログラムを載せる。これを用いて課題4.3の結果を確認する手順を示す。
  1. bisonの入力ファイルpicoc1.yを作成する。ファイル名は適宜つけること。リスト4.2の電卓プログラムの1~36行目までからなる部分をもとにして、4.4.1節と4.4.3節の記述に従って修正する。ast.hをインクルードするように記載すること。また、
    #define YYSTYPE double
    
    を削除する。さらに、ルール部の先頭にある非終端記号lineについてのルールを次のように変更する。
    line
        : expr { extern ExprNodePtr ex; ex=$1; }
        ;
    
    このようにしてできたファイルを
    bison -t -d picoc1.y
    
    で処理する。bisonが警告を出した場合の対応
  2. リスト4.4に倣って以下のプログラムを作成し、ast.c, printast.cならびにbisonが出力したpicoc1.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 "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 }
    
    /* fib(k-2)+fib(k-1)*in()+binom(k,2) を表すトークンの配列 */
    Ttokens thetokens[]={
    	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_T(MUL),T_ID("in"),T_CH('('),T_CH(')'),
    	T_T(ADD),T_ID("binom"),T_CH('('),T_ID("k"),T_CH(','),T_INT(2),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()の中身を定義していなければ、
    undefined reference to yyerrorコンパイルエラーが出る。その場合は
    ここでの定義は不要なので、mainの前までを削除する */
    #if 0
    int yyerror( char *msg ){
    	fprintf( stderr, msg );
    	exit( 1 );
    }
    #endif
    
    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, "in", 1, 0, 1, NULL );
    	symAdd( SYM_FUNC, "fib", 2, 1, 0, NULL );
    	symAdd( SYM_FUNC, "binom", 3, 2, 0, NULL );
    	symAdd( SYM_VAR, "k", 0, 0, 0, NULL );
    
    	/* 構文解析を実行 */
    	if( yyparse() ) return EXIT_FAILURE;
    	/* 結果を出力 */
    	printASTExpr( argc, argv, ex );
    	return EXIT_SUCCESS;
    }
    
  3. その結果できたファイル(ここではkadai43という名前を仮定する)を実行するときに、

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

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