R → R '|' Q | Q Q → Q P | P P → P '*' | O O → '(' R ')' | ALPHAを左再帰のない形に書き換えよ。(教科書 p.57参照)
注: この文法は正規表現の式を表わす文法
R → R '|' R | R R | R '*' | '(' R ')' | ALPHAの優先順位を考慮したものである。 (BNFに使われるメタ記号としての「|」と、 構文の一部の「'|'」(シングルクウォートで囲んである)の区別に注意せよ。 )
答はここにありますが、 まずは自分で考えてみてください。
答はここにありますが、 まずは自分で考えてみてください。
Expr → CON | FunCall FunCall → FID '(' Expr ',' Expr ')' -- 以下は終端記号: 字句解析部で処理 EOL → '\n' -- End Of Line CON → '0' | '1' | ... | '9' -- 一桁の数のみ FID → '+' | '-' | '*' VID → 'a' | 'b' | ... | 'z' |
に対する再帰下降構文解析プログラムの例 を参考にして、1.の文法に対して、再帰下降構文解析プログラムを作成せよ。 (教科書 p.63参照)
入力が文法的に正しければ "Correct!"(または「正しい!」)と表示し、 間違っていれば、適当なエラーメッセージを出力するようにせよ。 (文法的に正しいかどうかを判断するのみで、 それ以上のこと(計算結果を求めるなど)はする必要はない。)
ただし、「終端記号に対応するマクロの定義」の部分は代わりに
#define ALPHA 256 #define EOL 257 |
「簡易字句解析ルーチン」は代わりに
/* 簡易字句解析ルーチン */ int yylex(void) { int c; do { c = getchar (); } while (c == ' ' || c == '\t'); if (isalpha(c)) { yylval = c; return ALPHA; } if (c == '\n') { return EOL; } if (c == EOF) { exit(0); } /* 上のどの条件にも合わなければ、文字をそのまま返す。*/ return c; /* '(', ')', '*'など */ } |