言語理論とコンパイラ

第七回: 上向き構文解析と下向き構文解析

2009 年 5 月 29 日

http://www.sw.it.aoyama.ac.jp/2009/Compiler/lecture7.html

Martin J. Dürst

AGU

© 2005-9 Martin J. Dürst 青山学院大学

目次

前々回の宿題: Flex

(宿題の解答例)

前回の宿題

(提出不要)

C プログラム言語の文法の例 (yacc 形式; typedef に要注意)

Java プログラム言語の文法 (BNF 形式)

先週のまとめ

プッシュダウンオートマトンの例

プッシュダウンオートマトンの図

構文解析の結果: 解析木と構文木

解析木:
葉は終端記号と (分析の途中の場合) 被終端記号
節は非終端記号
文法や解析方法の研究に使われる
構文木:
葉は終端記号の一部 (識別子、定数など)
節は被終端記号の一部に相当するが、終端記号の一部 (演算子、予約語) などをラベルに使う
一部の終端記号は無視 (括弧類など)

解析木と構文木の例

文法:

E → E '+' E    (Expression, 式)

E → E '*' E

E → '(' E ')'

E → integer

入力の例:

5 + 3 * (7 + 2)

構文解析の目的

⇒ 文法は言語を定義するだけでは不十分

曖昧な文法

文法の曖昧性の除去

問題の例:

E → E '-' E | integer

入力 4 - 5 - 7 に対して複数の解析木が作れる

解析木によって計算結果が違う

解決方法: 文法の書き換え

E → E '-' integer | integer

解析の実装: 下向き解析と上向き解析

下向き構文解析 (top-down parsing):
解析木を上から (初期記号から) 作る
上向き構文解析 (bottom-up parsing):
解析木を下から (終端記号から) 作る
途中に複数の (小さな) 解析木がある

構文解析の単純な実装: Dynamic Programming

(bottom-up)

下向き解析の一般概要

バックトラックは時間がかかる上、避けた方がいいとされてきた

次のトークンしか見なくてよい文法に限定したい

再帰的下向き構文解析

下向き構文解析の実装: 簡単な手作りコンパイラ

プログラム: scanner.h, scanner.c, parser.c

下向き構文解析の問題点

来週への準備

宿題

(提出不要)

次の文法の曖昧性を除去し、曖昧性のない文法を作りなさい。曖昧性がないことを複数の例で確認してください。

E → E '+' E    (Expression, 式)

E → E '*' E

E → '(' E ')'

E → integer

ヒント: 非終端記号の追加が必要