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; /* '(', ')', '*'など */
}
|