←Marsの使い方 | ↑目次 | →第2回のヒント

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

第1回

写経がつらい方へ

手で入力することで多少なりともプログラムを理解する手助けになると考えていますが、以下の長いリストについては、ファイル( zip | tar gz ) を用意しました。なお、指導書をコピー&ペーストすると、空白や一部の記号が文字化けして思いもよらないエラーが発生することがあります。

中置記法から後置記法への変換

式を入力して、変換ボタンをクリックすると、後置記法に変換します。構文木も出力します。

[後置記法]

[構文木]

構文木の表示

今回の課題1.7で、構文木も表示したい場合、次のようにする。

テキストで表示したい場合

  1. infix2postfix.cに次の関数を加える。
    void toText( NodePtr t, int indent ){
    int i;
    	for( i=0; i<indent; i++ ){ printf( "  " ); }
    	if( t->left == NULL ){
    		printf( "[%d]\n", t->val );
    	} else {
    		printf( "[%c]\n", t->val );
    	}
    	if( t->left != NULL ){
    		toText( t->left, indent + 1 );
    	}
    	if( t->right != NULL ){
    		toText( t->right, indent + 1 );
    	}
    }
    
  2. main関数の末尾(return 0;の前)に以下を加える。
    	puts("");
    	toText( z );
    

グラフィカルに表示したい場合

  1. infix2postfix.cに次の関数を加える。
    void toDot( NodePtr t ){
    	printf( "N%p [label=\"", t );
    	if( t->left == NULL ){
    		printf( "%d\"];\n", t->val );
    	} else {
    		printf( "%c\"];\n", t->val );
    	}
    	if( t->left != NULL ){
    		printf( "N%p -> N%p;\n", t, t->left );
    	}
    	if( t->right != NULL ){
    		printf( "N%p -> N%p;\n", t, t->right );
    	}
    	if( t->left != NULL ){
    		toDot( t->left );
    	}
    	if( t->right != NULL ){
    		toDot( t->right );
    	}
    }
    
  2. main関数の末尾(return 0;の前)に以下を加える。
    	printf( "\ndigraph { graph [ordering=\"out\"];\nnode [shape=\"circle\"];\nedge [arrowhead=\"none\"];\n" );
    	toDot( z );
    	printf( "}\n" );
    
  3. コンパイルしてできたファイルを実行すると後置記法の式の下にdigraph...と表示されるので、その部分を適当なファイル名(ここではhoge.dotとする)で保存する。 演習室のLinux環境では、次のように実行すると木が表示される。
    dot -Tx11 hoge.dot
    
    画像ファイルとして保存したければ、次のようにする。pdf以外で保存したければ、2か所あるpdfはpngやjpgに変更すればよい。
    dot -Tpdf hoge.dot > fuga.pdf
    
    自宅などで実施するのであれば、hoge.dotを以下から読み込ませる。
    あるいは、hoge,dotの内容をすべて下のボックスにコピー&ペーストして、変換ボタンをクリックする。

    [グラフ]

    上のグラフをsvgファイルとして保存できます。
    ファイル名:
トップページ