LR(1) 分析例子
本節介紹比SLR(1)功能更強的LR(1)分析法。 因此I5,I7中衝突不能用SLR(1)方法解決。只能考慮用下面將要介紹的LR(1)方法解決。 由於用SLR(1)方法解決動作衝突時,對於歸約專案A→α·,只要當前面臨輸入符為a∈FOLLOW(A)時,就確定採用產生式A→α進行歸約,但是如果棧中的符號串為βα,歸約後變為βA,再移進當前符a,則棧裡變為βAa,而實際上βAa未必為文法規範句型的活字首。 例如:在識別表示式文法的活字首DFA中,(見圖7.10)在專案集I2存在移進-歸約衝突,即{E→T· T→T·*F}若棧頂狀態為2,棧中符號為#T,當前輸入符為‘)’,而‘)’屬FOLLOW(E)中,這時按SLR(1)方法應用產生式E→T進行歸約,歸約後棧頂符號為#E,而再加當前符‘)’後,棧中為#E)不是表示式文法規範句型的活字首。 因此這個歸約是多餘的。因此可以看出SLR(1)方法雖然相對LR(0)有所改進,但仍然存在著多餘歸約,也說明SLR(1)方法向前檢視一個符號的方法仍不夠確切,LR(1)方法恰好是要解決SLR(1)方法在某些情況下存在的無效歸約問題。 若[A→α·Bβ]∈專案集I,則[B→·γ](B→γ為一產生式)也包含在I中,不妨考慮,把FIRST(β)作為用產生式B→γ歸約的搜尋符,稱為向前搜尋符,作為歸約時檢視的符號集合,用以代替SLR(1)分析中的FOLLOW集,把此搜尋符號的集合也放在相應專案的後面,這種處理方法即為LR(1)方法。(SLR(1)和LR(1)的區別在於LR(1)多使用了一個預判資訊,即專案後面的符號如A →·e,c中的c,這個預判資訊是用first集而非follow集得出的 1. LR(1)專案集族的構造 構造LR(1)專案集的閉包函式CLOSURE(I)按如下方式構造: 2.構造LR(1)分析表:
I0:S'→.S S →.BB B →.aB B →.b 例:G(S):S → BB B→aB B →b 對於該例題,只要仔細分析該文法的LR(1)每個專案集的專案,不難發現,即使不考察搜尋符,它的任何專案都沒有衝突,因此它實際上是一LR(0)文法,可以構造一個LR(0)專案集.可以得知它的LR(0)分析器只含7個狀態,而現在LR(1)分析器卻含有10個狀態,其中I3和I6,I4和I7,I8和I9分別為同心集。 |