言語理論とコンパイラ
第九回:
yacc 系ツールの演習
2005 年 6月23日
© 2006 Martin
J. Dürst 青山学院大学
下向き構文解析の実装: 簡単な手作りコンパイラ
プログラム: scanner.h, scanner.c, parser.c
下向き構文解析の問題点
上向き構文解析の概要
- 解析を下から上へ向いて作成
- それぞれの文法規則に合わせて小さいオートマトンを活用
- 複数の可能性があるときに、複数のオートマトンを組み合わせる
- 下向き解析より対応できる文法が多い
- それでも対応できる文法に限界がある
- 手作りが無理で、プログラムで作るしかない
最左導出と最右導出
簡単な例:
E → F '+' F
F → integer
最左導出の場合にはいつもできるだけ左の終端記号が置き換えられている
文法の種類の呼び方
- LL: 左から入力を読んで、最左導出
- LR: 左から入力を読んで、最右導出
- LL(1): LL で、一つトークンを先読み
- LR(1): LR で、一つトークンを先読み
- LALR: LR (1) の一種で、yacc など幅広く使われる
LALR 構文解析の原理
スタックを使って読んだトークンや途中の非終端記号を蓄積
オートマトンを使って出来るだけ簡単な操作で次のステップを決める
(LA)LR 構文解析の二つのオペレーション
- shift:
トークンを一個読んで、そのトークンをスタックにステートと一緒に詰める
- reduce:
スタックの上部にあるトークンや非終端記号を文法規則を使って一つの終端記号に変換する
属性文法
(attribute(d) grammar(s))
- 解析木の葉と節に属性を追加
- 文法規則に、葉の属性から節の属性を計算する規則を追加
- 例 1:
電卓みたいな直接計算する文法の場合、属性は式の評価の値
- 例 2:
一般のプログラムの場合、属性は構文木や型情報
bison とは
- yacc: yet another compiler compiler
- Unix の普及とともに広がった
- compiler compiler: コンパイラを作るコンパイラ
- yet another: もう一つ、できた当時に compiler compiler
が流行りで、他に名前が浮かんで来なかった
- bison: yacc の gnu 版
flex と bison の資料
flex と bison の使い方の概要
- bison でトークンの種類を記述:
%token NUM PLUS ASTERISK
...
- bison で属性値の型の定義
#define YYSTYPE int
- flex でそれぞれのトークン用のルールの定義
- bison で文法規則の定義
- bison で文法の属性の規則の定義
- コンパイルとテスト
(全項目と合わせて行った方がよい)
make の活用
- flex, bison, gcc などを忘れす使うのが難しい
- make コマンドは makefile
の指定に従い、必要最小限の処理を実行
- 必要に応じて、make コマンドを cygwin で追加
- make ファイルの書き方 (→はタブの意味):
target: input1 input2
input3 ...
→target 作成命令
- make だけ打つと makefile 内の最初の target
が作られる
演習例: 簡単な電卓
スタートのためのファイル: makefile, calc.y, calc.lex
宿題: 複素数の電卓
提出: 再来週の金曜日 (7月7日) 10時45分、O 棟
529号室の前
簡単な電卓を複素数の電卓に拡張してください。複素数の表し方は
5i
で虚数を表し、[実部,虚部]
で複素数を表すようにして下さい。[]
内には実数演算は許されるが 5i
みたいなものが来ないように文法を設計してください。
complex.lex と complex.y を提出ください。