言語理論とコンパイラ

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

2010 年 6 月 4 日

http://www.sw.it.aoyama.ac.jp/2010/Compiler/lecture9.html

Martin J. Dürst

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

AGU

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

AGU

今日の予定

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,...

前回の文法の発展

出発点 (parser2.c):
E → T '+' T | T
T → number
三つ以上の被演算子への対応 (parser3.c):
E → T '+' E | T
T → number
引き算の追加 (parser4.c):
E → T '+' E | T '-' E | T
T → number
右結合から左結合への変更 (parser5.c):
E → E '+' T | E '-' T | T
T → number
左再帰!

前回の宿題

(提出不要)

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

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

E → E '*' E

E → '(' E ')'

E → integer

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

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

左再帰の問題と解決

左再帰の例:

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 の書き換え

M → a N* b

M → a b | a L b
L → L N

bison とは

演習例: 簡単な電卓

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

flex と bison の使い方の概要

make の活用

bison の仕組みとデバッグ