編譯原理之LL(1) 、LR(0)、SLR、LR(1)、LALR文法的對比
考完編譯原理有一段時間了,記得當時都被以上這五種文法搞懵了,所以希望寫篇文章幫助那些正在學習的人。以下內容是依據龍書中文版講解的,由於老師不同可能某些地方大同小異,如有什麼紕漏之處還請指出,多謝~
以下文章參考了:LL LR SLR LALR 傻傻分不清。
首先來看張圖,上圖是四種文法的包含關係,即 LR(1)文法範圍最大,而 LR(0)文法範圍最小。同時也說明了四種文法分析過程的強弱,即 LR(1)文法分析最強,而 LR(0)最弱。
那為什麼沒有 LL(1)文法呢?因為它和上面的四種文法是不同的。
LL(1)分析法是自上而下的分析法。LR(0),LR(1),SLR(1),LALR(1)是自下而上的分析法。
自上而下:從開始符號出發,根據產生式規則推導給定的句子。用的是推導。
自下而上:從給定的句子規約到文法的開始符號。用的是歸約。
下面就主要來講解他們的不同點, LL(1)單獨講,其他四種文法分析過程基本有三大步:寫出自動機(即 LR(0)或 LR(1)項集族,後面都稱作自動機) -> 構造文法分析表-> 進行文法分析過程。其中後兩步都是類似或者說幾乎完全一樣的,第一步中的自動機有兩種: LR(0)自動機和 LR(1)自動機。LR(0) 和 SLR文法分析用的是 LR(0)自動機,LR(1)和 LALR文法用的是 LR(1)自動機。
一、LL(1)文法分析
分析過程:
LL(1)分析又稱預測分析,首先將文法拆分到最小,即不帶寫出“|”的產生式,並寫出每條產生式的 select集。 然後,針對輸入串寫出預測分析表,表的最左一列為非終結符,最上一行為輸入串中出現的終結符,注意要包括句子括號“#”。
然後就是進行預測分析了,由於上課老師是在黑板上畫的,我又懶得寫……so……大家自己動手吧。預測分析的過程和後面的 LR分析過程大體類似,最上一行應該有的項是:步驟、符號棧、剩餘串和動作。其中動作無非就是匹配和移近,當符號棧棧頂符號和剩餘串最左邊符號相同時則匹配,反之移近。由哪條產生式移近應根據上面的預測分析表來決定,即符號棧棧頂的非終結符和剩餘串最左部的終結符對應的產生式。如果沒有與之對應的產生式則匹配出錯,給出的輸入串不是該文法的句子,如果匹配完畢則 acc(接受)。
LL(1)文法判定:
主要有兩種方式,一是依靠 select集,如果對於產生式左部相同的任意兩條產生式的 select集相交為空 且 兩者不能同時推出空,則是LL(1)文法。二是如果預測分析表中沒有多重入口(即分析表的一格中只有一個產生式)則為LL(1)文法。
二、LR(0)文法分析
分析過程:
首先要拓廣文法,即如果文法開頭不是一個非終結符到另一個非終結符的產生式則需要加入,如加入 S'->S .
然後需要構造 LR(0)自動機,就是加入了一個圓點,圓點後的符號是即將處理的符號,如果圓點後是非終結符時,則要寫出該終結符為產生式左部的所有產生式。反覆以上過程,直到不再擴大。給它們編號並寫出讀入下一個符號(即圓點後的符號)會跳轉到哪。
然後構造 LR(0)分析表,左側為項集族編號,上部為終結符和非終結符。中間內容表示該編號的項集族遇到非終結符應該移近還是歸約,數字為跳轉到的項集族編號,如果圓點到了產生式的最右邊則應歸約,反之移近。遇到終結符填入相應的項集編號即可。
下一步就是分析過程了,由於沒有針對這個文法的分析過程,最後面會單獨講解,下面的文法就不提分析過程的表了。幾乎都是一樣的。
LR(0)文法判定:
如果文法對應的自動機中不存在移進-歸約衝突和歸約-歸約衝突則為 LR(0)文法。換句話說LR(0)文法分析不能解決這兩種衝突,所以範圍最小。移進-歸約衝突就是在同一個項集族中同時出現了可以移進的產生式和可以歸約的產生式。歸約-歸約衝突類似。
三、SLR文法分析
分析過程:
拓廣文法、寫自動機、分析過程表與 LR(0)文法相同。但是由於可能存在移進-歸約衝突,所以 SLR分析表可能存在多重入口(即同一格中既有移進又有歸約)。
SLR文法判定:
SLR文法不存在歸約-歸約衝突,有可能存在移進-歸約衝突,但是如果可以用 follow集解決則是 SLR文法。換句話說,SLR文法分析過程可以解決歸約-歸約衝突,但是不一定能解決移進-歸約衝突。用 follow集來處理即出現移進-歸約衝突的兩條產生式如果其 follow集相交為空則為 SLR文法,反之不是。當然,如果以上兩種衝突都不存在自然是了。
四、LALR文法分析
分析過程:
拓廣文法與前面一致。
在自動機這塊,我們需要構造的是 LR(1)自動機,與 LR(0)自動機的不同是多了向前搜尋符。感覺自己寫的太多了,搜尋符怎麼確定以後在評論裡說吧。LALR需要合併同心集,即合併產生式相同但是向前搜尋符不同的項集族。
由於合併了同心集,所以 LALR分析表也應該做出相應的改變,例如合併了 I3和 I6,則對應的格中應填 S36 .
LALR文法判定:
有個結論是合併同心集不會產生新的移進-歸約衝突,但是會產生新的歸約-歸約衝突,如果沒產生衝突就是 LALR 文法,反之不是。
五、LR(1)文法分析
分析過程與 LALR文法相同。
LR(1)文法判定:
因為 LR(1)文法的範圍比較大,所以文法幾乎都是 LR(1)的,現在知道的只有當合並同心集產生了歸約-歸約衝突時才是LR(1)文法。
注意,根據最開始的那張圖可以知道,是小的文法一定是大的文法。這一點需要注意。
分析過程表:
上面四種文法的分析過程可以說都是一模一樣的,根據狀態棧棧頂和剩餘串最左部符號查分析表,如果是移進就將數字和非終結符分別填入兩個棧中。如果是歸約,先將狀態棧棧頂和符號棧棧頂出棧,然後將非終結符入符號棧,根據當前狀態棧棧頂和剩餘串最左部符號查分析表,並將數字填入狀態棧。
---------------------
作者:棉花糖灬
來源:CSDN
原文:https://blog.csdn.net/zuzhiang/article/details/79047743
版權宣告:本文為博主原創文章,轉載請附上博文連結!