Transcript Compilers

Compilers
Chapter5 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
高次の表現法で実装の詳細を隠す

PRODUCTION
SEMANTIC RULE
T → T1 * F
T.val := T1.val × F.val
translation scheme
意味規則が評価される順番を示し、実装の詳細を明らかにする
{ SEMANTIC ACTION }
T → T1 * F { T.val := T1.val × F.val}
Synthesized Attribute
& Inherited Attribute
 統合属性
子ノードから値が計算される
 継承属性
親や兄弟ノードから値が計算される

A
B
C
依存関係グラフ
属性間の依存関係を
矢印で表したグラフ
D
E
Dependency Graph
 Circularity
依存関係グラフが循環性を持って
いると評価できない
E
i
s
t
依存関係グラフが循環性を持たず、
属性値の依存関係に(部分)順序が
あるとき、Strong Noncircular
Syntax-Directed Definition
と呼び、再帰的に評価をする関数を
作れる
i
E1 s
t
i E2 s
t
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;
T → int
T → real
L→
L1, id
L → id
{ L.in := T.type }
{ T.type := integer }
{ T.type := real }
{ L1.in := L.in }
{ addtype(id.entry, L.in) }
{ addtype(id.entry, L.in) }
Bottom-upでの評価(2)
INPUT

スタックの様子
スタックは下の図のように状態
と属性値の対でできているとする
A→XYZ の場合、XYZ がA に
置き換わる「縮小」が起こる
top →
state
val
・・・
・・・
X
X.x
Y
Y.y
Z
Z.z
・・・
・・・
state
PRODUCTION USED
real p,q,r p,q,r real
p,q,r T
T → real
,q,r T p
,q,r T L
L → id
q,r T L ,
,r T L ,q
,r T L
L → L ,id
r TL,
T L ,r
TL
L → L ,id
D
D→TL
Bottom-upでの評価(3)

スタックを考慮したコード
PRODUCTION
CODE FRAGMENT
D→TL;
T → int
val[ntop] := integer
T → real
val[ntop] := real
L → L ,id
addtype(val[top],val[top3])
addtype(val[top],val[top-
※top, ntop は
縮小前/後の
スタックのトップ
を表す
L → id
L→id が適用される時、id.entry
1]) はスタックのトップに、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→+TMR
M → e {print('+')}
Bottom-upでの評価(5)

属性値の位置
PRODUCTION SEMANTIC RULES
S → aAC
C.i := A.s
S → bABC
C.i := A.s
C→c
C.s := g(C.i)
PRODUCTION
SEMANTIC RULES
S → aAC
C.i := A.s
S → bABMC
C.i := A.s; C.i := M.s
C→c
C.s := g(C.i)
M →ε
M.s := M.i
1つ目/2つ目どちらの生成
規則を用いるかに関わらず
C.i は val[top-1]
スタックとレジスタ(1)
 コピールール
コピールールを特別に扱うことによってスタックの利用効率を改善する
ことができる
1つよりも多くのスタックを利用した方がその機会が多くなる
1スタック
2スタック
A
A.i
A.i
i
B1.i
A.s
B1.s
B2.i
B2.s
B1.s
A.s
B2.s
B1
i
i
B2
スタックとレジスタ(2)

レジスタ
一つのレジスタはスタックの特別な場合と考えられる
スタックに多くとも1要素のみが入る場合は代わりにレジスタを用いる
ことができる

Lifetime
属性値のLifetime は算出されたときに始まりそれに依存する全ての
属性が算出されたときに終わる
2つの属性のLifetime が重なっていないとき、それらの値は同じレジ
スタに格納することができる