nofx @Wiki
LL(1)文法
最終更新:
匿名ユーザー
-
view
α : 記号列(空列εを含む) α∈(N∪Σ)*
First(α) : αの始動記号の集合
First(α) : αの始動記号の集合
- First(α) = { a | a∈N, α⇒a…}
A : 非終端記号
Follow(A) : Aの追随記号の集合
Follow(A) : Aの追随記号の集合
- Follow(A) = { a | a∈N, S⊥⇒…Aa…}
(開始記号S、Follow(S)は文末記号⊥を含む)
生成規則
A→α (A:非終端記号、 α:記号列)
に対して、
Director(A,α) : 生成規則 A→α の引率記号の集合h
A→α (A:非終端記号、 α:記号列)
に対して、
Director(A,α) : 生成規則 A→α の引率記号の集合h
Director(A,α) | = | First(α) | (α⇒εでないとき) |
First(α) ∪ Follow(A) | (α⇒εのとき) |
文法G=(N,Σ,P,S)において、右辺だけ異なる任意の生成規則
A→α
と
A→β
に対して
Director(A,α)∩Director(A,β)=Φ
が成り立つとき、GはLL(1)文法であるという。
与えられた文法がLL(1)文法であれば、入力トークン列の先頭の終端記号を見れば、次にAのどの生成規則を使用すべきかが決定できる。
■非終端記号Xに対してXが空列を生成しうるか否かを判定するアルゴリズム
(X⇒εか否か?)
(X⇒εか否か?)
配列ary[]を用意し、Xに対応するary[X]は次のような値を持つものとする。
yes | (Xが空列を生成すると決定したとき) | ||
ary[X] | = | no | (Xが空列を生成しないと決定したとき) |
u | (未定) |
- まず、全ての非終端記号Xに対して
ary[X]= u
とする - 右辺に終端記号を含む全ての生成規則をチェックする。
この結果、ある終端記号Xに対して全ての生成規則がチェックされたら
ary[X]= no
とする - 右辺に ε を持つ生成規則であれば、チェックし、その生成規則の左辺の非終端記号Xに対して
ary[X]= yes
とする - この時点で ary[X]= u であるXが残っているならば、次を ary[X]= u が無くなるまで以下を繰り返す。
① 右辺に ary[X]= no を満たす非終端記号を持つ全ての生成規則をチェックする。
この結果、ある非終端記号Yに関して全ての生成規則がチェックされたなら
ary[X]= no
とする
② 右辺に ary[X]= yes を満たす非終端記号を持つ全ての生成規則からXを削除する。
この結果、生成規則の右辺が空になったら、この生成規則をチェックしその左辺の非終端記号Yに関して
ary[X]= yes
とする
■非終端記号Xに対して、始動記号の集合S(X)を求める手順
- S(X)=φで初期化
S(X)が変化しなくなるまで以下を繰り返す。
- X→aαなる生成規則があれば
S(X)=S(X) ∪ { a } - X→Yαなる生成規則があれば
① Y⇒ε なら
S(X)=S(X) ∪ S(Y) ∪ S(α)
S(α)の求め方は下に示す。
② そうでないなら
S(X)=S(X) ∪ S(Y)
■記号列αに対して、始動記号の集合S(α)を求める手順
- α=εのとき
S(α)=φ - αの先頭が終端記号aのとき
S(α)={ a } - α=Yβのとき
① Y⇒ε なら
S(α)=S(Y) ∪ S(β)
② そうでないなら
S(α)=S(Y)
■非終端記号Bに対して追随記号の集合F(B)を求める手順
- B:開始記号なら F(B)={⊥} (⊥:文末記号)
- B:開始記号以外なら F(B)=φ で初期化
F(B)が変化しなくなるまで以下を繰り返す。
右辺にBを含む生成規則を A→αBβで表す
- β=ε (Bが最後の記号)のとき
B≠Aなら F(B)=F(B)∪F(A)
B=Aなら 何もしない - βの先頭が終端記号aのとき
F(B)=F(B)∪{ a } - 1.、2.以外の場合
① β⇒εのとき
F(B)=F(B)∪S(β)∪F(A)
② それ以外のとき
F(B)=F(B)∪S(β)