編譯原理語法分析-自上而下分析
語法分析的過程包括自上而下的推導和自下而上的規約。
遞迴下降分析器的設計(LL分析,自上而下的推導)
語法分析器的自動生成(LR分析,自下而上的規約)
自上而下面臨的問題:
文法的左遞迴問題
回溯的不確定性,要求我們將已經完成工作推倒從來,
虛假匹配的問題
不能準確地確定輸入串中出錯的位置
效率低
LL(1)分析法:
******消除直接左遞迴******
產生式
P→Pα|β(1)
其中β不以P開頭,α不為ε。那麼,我們可以把P的規則改為如下的非直接左遞迴形式:
P →βP’
P’→αP’|ε(2)
產生式
P→Pα1|Pα2|…|Pαm|β1|β2|…|βn
其中每個βi不以P開頭,每個αi不為ε
消除P的直接左遞迴性就是把這些規則改寫成:
P→β1P’|β2P’|…|βnP’
P’→α1P’| α2P’|…|αmP’| ε
間接左遞迴
例題如下:
消除回溯:
FIRST集
令文法G是不含左遞迴的文法,對G的非終結符的候選α,定義它的開始符號(終結首符)集合:
特別地,如果α ε,則ε∈FIRST(α)
如果非終結符A的任意兩個候選式αi和αj的開始符號集滿足FIRST(αi)∩FIRST(αj)=Φ,則A可以根據所面臨的第一個輸入符號,準確地指派一個候選式α去執行任務,α是那個FIRST集含a的候選式,即 a ∈FIRST(α)
改造文法: 消除公共左因子
FOLLOW集
對文法G的任何非終結符A,定義它的後繼符號集合:
特別地,如果S …A,則#∈FOLLOW(A)
FOLLOW(A)集合是所有句型中出現在緊接A之後的終結符號或#所組成的集合
當非終結符A面臨輸入符號a,且a不屬於A的任意候選式的FIRST集但A的某個候選式的FIRST集包含ε時,只有當a ∈FOLLOW(A),才可能允許A自動匹配
******不帶回溯的自上而下分析的文法條件(LL(1)文法)
(1)文法不含左遞迴
(2)對於文法中每一個非終結符A的各個產生式的候選式的FIRST集兩兩不相交。即,若
A→α1|α2|…|αn
則FIRST(αi)∩FIRST(αj)=Φ (i≠j)
(3)對於文法中的每個非終結符A,若它的某個候選首符集包含ε,則
FIRST(A)∩FOLLOW(A)=Φ
如果一個文法G滿足以上條件,則稱該文法G為LL(1)文法(第1個L代表從左到右掃描輸入串,第2個L代表最左推導,1表示分析時每一步只看1個符號)
******預測分析程式
執行程式
1.把#和文法起始符號E推進棧,並讀入輸入串的第一 個符a,重複下述過程直到正常結束或出錯.
2.測定棧頂符號X和當前輸入符號a,執行如下操作:
(1)若X=a=#,分析成功,停止。E匹配輸入串成功.
(2)若X=a≠#,把X推出棧,再讀入下一個符號。
(3)若X∈Vn,查分析表M。
a) M[X,a]= X→UVW
則將X彈出棧,將UVW壓入
注:U在棧頂 (最左推導)
b) M[X, a] = error 轉出錯處理
c) M[X, a] = X-〉ε ---a為X的後繼符號則將X彈出棧 (不讀下一符號)
繼續分析。
預測分析表的構造:FIRST(X)
若X終結符,則FIRST(X)={X}
若X為非終結符,且有X->a …的產生式,則把a加入到FIRST(X)中;
若X->Y…是一個產生式,且Y為非終結符,則把FIRST (Y)-ε加入到FIRST(X)中;
若X->Y1Y2Y3….YK,是產生式, Y1Y2Y3….Yi-1是非終結符,而且ε屬於 FIRST (Yj)(1<=j<=i-1),則把FIRST (Yj)-ε加入到FIRST(X)中;
如果ε屬於所有的FIRST (Yj),則ε加入到FIRST(X)中
預測分析表的構造:FOLLOW(S)
對於文法的開始符,置#於FOLLOW(S)中
若A->αBβ, 則把FIRST (β)-ε加入到FOLLOW(B)中,
若A->αB 是一個產生式,或 A->αBβ是一個產生式,而β-> ε,則把FOLLOW(A)加入到FOLLOW(B)中
預測分析表的構造:
對文法G的每個產生式, A->α,進行下面的處理
對每個終結符a,如果a屬於FIRST(α),則把該產生式寫入到M[A,a]
若ε屬於FIRST(α),則對任何b屬於FOLLOW(A), 把該產生式加入到M[A,b]
所有無定義的M[A,a]標上出錯標誌
*********************************************課 後 題*********************************************************
感想:
定義類的東西結合例項才能夠充分更好的理解,同時用自己通俗理解的方式詮釋定義在正確的條件下更容易理解記憶