言語理論とコンパイラ

第八回: yacc 系ツールの使い方

2007 年 6月 8日

http://www.sw.it.aoyama.ac.jp/2007/Compiler/lecture8.html

Martin J. Dürst

duerst@it.aoyama.ac.jp, O 棟 529号室

AGU

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

今日の予定

flex の演習の正解例

読みやすさのため、コメントを /x x/ にし、スペースを使用

第一案: /x .* x/ 問題: /xx/ /xx/ をまとめて認識

第二案: /x [^x]* x/ 問題: /xxx/ を認識しない

第三案: /x ([^x]|x[^/])* x/ 問題: /x xx/ /x x/ をもとめて認識

第四案: /x ([^x]|x+[^/])* x/ 問題: 以前と同様

第五案: /x ([^x]|x+[^/x])* x/ 問題: /x xx/ を認識しない

第六案: /x ([^x]|x+[^/x])* x+/ 完成!

参考: Mastering Regular Expressions, Jeffrey E.F. Friedl, pp. 168,...

先週の宿題

(提出不要)

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

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

E → E '*' E

E → '(' E ')'

E → integer

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

高校とかで覚えた「項」と「因子」を使う。

先週の宿題の正解例

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

T → T '*' F (Term, 項)

F → '(' E ')' (Factor, 因子)

F → integer

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

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

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

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

左再帰の問題と解決

左再帰の例:

E → E '-' integer | integer

間違った解消 (結合規則が違う):

E → integer '-' E | integer

解消の結果:

E → integer EE

EE → '-' integer EE | ε

これに相当する EBNF:

E → integer ('-' integer)*

文法規則と BNF

文法規則には色々な書き方がある:

  1. 一番単純な書き方: 矢印だけ
  2. 左側に同じ被終端記号を持つものを複数組み合わせて | で選択を表す
    ⇒ 根本的に 1. と変わらない (syntactic sugar/糖衣構文)
  3. 正規表現の ? の様なもの (あり/無し) の追加 (よく [...] で書く)
    ⇒ 二つの構文規則に分けることが可能
  4. 正規表現の * の様なもの (よく {...} で書く)
    ⇒ 書き換えが可能

上記の拡張を含む文法規則の書き方は BNF (Backus-Naur Form), EBNF (Extended...), ABNF (Augmented...) などという

EBNF の書き換え

D → a E* b

D → a F b
F → F E | ε

導出の順番: 最左導出と最右導出

簡単な例:

E → F '+' F
F → integer

最左導出の場合に、いつもできるだけ左の終端記号を置き換える

文法の種類の呼び方

LALR 構文解析の原理

スタックを使って読んだトーケンや途中の非終端記号を蓄積

オートマトンを使って出来るだけ簡単な操作で次のステップを決める

(LA)LR 構文解析の二つのオペレーション

属性文法

(attribute(d) grammar(s))

bison とは

flex と bison の資料

flex と bison の使い方の概要

make の活用

演習例: 簡単な電卓

スタートのためのファイル: makefile, calc.y, calc.lex