150 likes | 318 Views
Compilers Chapter5 Syntax-Directed Translation. 電子情報工学科 4 年 早津 政和. 概要. 文法指向翻訳 syntax-directed definition & translation scheme 統合属性と継承属性 依存関係グラフ L 属性定義と実装 Top-down での評価 Bottom-up での評価 スタックとレジスタ. Syntax-Directed Translation. 文法記号に「属性」を付け加えた言語を解釈
E N D
CompilersChapter5 Syntax-Directed Translation 電子情報工学科 4年 早津 政和
概要 • 文法指向翻訳 • syntax-directed definition & translation scheme • 統合属性と継承属性 • 依存関係グラフ • L属性定義と実装 • Top-downでの評価 • Bottom-upでの評価 • スタックとレジスタ
Syntax-Directed Translation • 文法記号に「属性」を付け加えた言語を解釈 • syntax-directed definition と translation schemeの2つの記法がある • parsing と同時に意味規則を評価できる方法は、コンパイル時間の効率の面で非常に重要 → L属性定義を用いると実行可能
Syntax-directed Definition & Translation Scheme • syntax-directed definition 高次の表現法で実装の詳細を隠す • translation scheme 意味規則が評価される順番を示し、実装の詳細を明らかにする { SEMANTIC ACTION } T → T1 * F { T.val := T1.val × F.val}
統合属性 子ノードから値が計算される 継承属性 親や兄弟ノードから値が計算される 依存関係グラフ 属性間の依存関係を 矢印で表したグラフ Synthesized Attribute & Inherited Attribute A B C E D
Circularity 依存関係グラフが循環性を持って いると評価できない 依存関係グラフが循環性を持たず、 属性値の依存関係に(部分)順序が あるとき、Strong Noncircular Syntax-Directed Definition と呼び、再帰的に評価をする関数を 作れる i s t i s t i s t Dependency Graph E E2 E1
L–Attributed Definitions • L(左)属性定義 A→X1・・・Xnにおいて、 Xjの属性値がX1~Xj-1の属性値とAの継承属性のみに依存する • translation schemeで表現する際の制限 1.Xの継承属性: その記号より前の動作で値が計算されていなければならない 2.Xの意味動作: その動作より右の記号の統合属性の値を用いてはならない 3.Aの統合属性: 参照している全ての記号の属性値が計算されて初めて計算できる
Top-downでの評価 • 左再帰の排除 等は省略 • translation scheme からpredictive translator を作るアルゴリズム 1.非終端記号Aに対応する関数(継承属性値をパラメタに取り、統合属性値を返す)を作成する 2.非終端記号Aに対応するコードは現在の入力記号に基づいて、どの生成規則を適用するかを決める 3.production の右側に対応するコードは以下の通り ⅰ)トークンX:属性値を変数に格納し、入力を一つ進める ⅱ)非終端記号B: c:=B(b1,b2,…,bk)を生成 c:統合属性 b:継承属性 ⅲ)意味動作:動作はそのままに、属性値に対応する変数を参照する
Bottom-upでの評価(1) • translation schemeでの表現 例)変数宣言 int p, q, r; の評価 D → T { L.in := T.type } L ; T → int { T.type := integer } T → real { T.type := real } L → { L1.in := L.in } L1, id { addtype(id.entry, L.in) } L → id { addtype(id.entry, L.in) }
Bottom-upでの評価(2) • スタックの様子 スタックは下の図のように状態 と属性値の対でできているとする A→XYZ の場合、XYZ がA に 置き換わる「縮小」が起こる top →
Bottom-upでの評価(3) • スタックを考慮したコード ※top, ntop は 縮小前/後の スタックのトップ を表す L→id が適用される時、id.entry はスタックのトップに、T.typeはその下に あるためaddtype(val[top],val[top-1])はaddtype(id.entry,T.type)と等価 このようにスタック中のT.typeの値を替わりに用いることで、L.inを含む コピールールが消える
Bottom-upでの評価(4) • 埋込み動作の排除 translation scheme の動作がproductionを終端するように マーカーを埋め込む R → + T {print('+')} R ⇒ R → + T M R M → e {print('+')}
Bottom-upでの評価(5) • 属性値の位置 1つ目/2つ目どちらの生成 規則を用いるかに関わらず C.i は val[top-1]
A B1 B2 スタックとレジスタ(1) • コピールール コピールールを特別に扱うことによってスタックの利用効率を改善する ことができる 1つよりも多くのスタックを利用した方がその機会が多くなる 1スタック 2スタック i i i
スタックとレジスタ(2) • レジスタ 一つのレジスタはスタックの特別な場合と考えられる スタックに多くとも1要素のみが入る場合は代わりにレジスタを用いることができる • Lifetime 属性値のLifetime は算出されたときに始まりそれに依存する全ての属性が算出されたときに終わる 2つの属性のLifetime が重なっていないとき、それらの値は同じレジスタに格納することができる