第七回: 下向き構文解析
2010 年 5月 21日
http://www.sw.it.aoyama.ac.jp/2010/Compiler/lecture7.html
© 2005-10 Martin J. Dürst 青山学院大学
[都合により削除]
C プログラム言語など知っている言語やデータ形式の文法を調べなさい (提出不要):
C プログラム言語の文法の例 (yacc
形式; typedef
に要注意)
Java プログラム言語の文法 (BNF 形式)
Ruby プログラム言語の文法 (図)
文法:
E → E '+' E
(Expression, 式)
E → E '*' E
E → '(' E ')'
E → integer
入力の例:
5 + 3 * (7 + 2)
バックトラックの遅さへの対策:
次のトークンしか見なくてよい文法に限定したい
A → variable '=' A |
integer
プログラム: scanner.h, scanner.c, parser1.c, parser.c
5 + 3 * 7
は (5+3) * 7
か 5 +
(3*7)
か問題の例:
E → E '-' E | integer
入力 4 - 5 - 7
に対して複数の解析木が作れる
解析木によって計算結果が違う
解決方法: 文法の書き換え
E → E '-' integer | integer
左再帰の例:
E → E '-' integer | integer
間違った解消 (結合規則が違う):
E → integer '-' E | integer
解消の結果:
E → integer EE
EE → '-' integer EE | ε
これに相当する EBNF:
E → integer ('-' integer)*
文法規則には色々な書き方がある:
|
で選択を表す?
の様なもの (あり/無し) の追加
(よく [
...]
で書く)*
の様なもの (よく
{
...}
で書く)上記の拡張を含む文法規則の書き方は BNF (Backus-Naur Form), EBNF (Extended...), ABNF (Augmented...) などという
M → a N* b
⇒
M → a b | a L b
L → L N
=
とか ::=
[]
で囲む (応用正規表現の
?
に相当){}
で囲む
(正規表現の *
に相当)|
で区切るこういう風な記述は EBNF (Extended Backus Naur Form) という
様々な種類 (方言) が存在
文法:
正規表現:
正規表現の (簡単な) 規則は文法の (複雑な) 規則一つに相当する
factor → functioncall | variable | arrayelement functioncall → identifier '(' parameters ')' variable → identifier arrayelement → identifier '[' expression ']'
factor
でどこの規則を選べば良いのか分からない⇒ 文法は言語を定義するだけでは不十分
(提出不要)
次の文法の曖昧性を除去し、曖昧性のない文法を作りなさい。曖昧性がないことを複数の例で確認してください。
E → E '+' E
(Expression, 式)
E → E '*' E
E → '(' E ')'
E → integer
ヒント: 非終端記号の追加が必要