編譯原理 規範LR方法

2021-10-06 11:16:22 字數 1961 閱讀 2516

我們之前學習了slr技術,包括lr(0)文法和slr(1)文法,不過我們還是遇到了移進-歸約衝突(slr(1)、lr(0))和歸約-歸約衝突(lr(0))的問題。其原因就是我們的項集構造不夠精確,如果能在狀態中包含更多的狀態資訊,在建表的時候就能排除掉一些不可能出現的歸約動作。

通過使用lr(1)項集,充分利用向前看(lookahead)符號,構建規範lr(1)語法分析表來實現。

對增廣文法:

(1) s』 -> s

(2) s -> cc

(3) c -> cc | d

構造lr(1)項集

i0= closure( ) =

//對照閉包的求法,對項[s』 -> •s, $],這產生式是s -> cc,並且first($)只能是$。對項[s -> •cc, $],產生式是c -> cc和c -> d,first(c$)是。

i1= goto(i0, s) = closure( ) =

i2= goto(i0, c) = closure( ) =

i3= goto(i0, c) = closure( ) =

i4= goto(i0, d) = closure( ) =

//以上,完成了**i0**上的goto函式。同理,如果手工繪製的話可以直接畫dfa轉換圖。

i5= goto(i2, c) = closure( )=

i6= goto(i2, c) = closure( ) =

i7= goto(i2, d) = closure( ) =

i8= goto(i3, c) = closure( ) =

//goto(i3, c) =i3,不產生新狀態

i9= goto(i6, c) = closure( ) =

//goto(i6, c) =i6,不產生新狀態

dfa轉換圖如下:

仍然以上面的文法為例。

在這裡主要看一下歸約的部分。我們看到,同樣是當•符號移到最右側的時候要進行歸約,但此時我們不必像slr(1)文法一樣去求左邊符號follow集了,只要根據lookahead符號,就可以在相應的**中標記了。

如何判斷:

1.判斷是不是lr(0)文法:(1)構造lr(0)自動機 (2)如果自動機中有任何衝突,則不是lr(0)文法。沒有衝突就是lr(0)文法。

2.如何判斷是不是slr(1)文法: (1)構造lr(0)自動機 (2)構造slr(1)分析表 (3)如果分析表中有任何衝突,則不是slr(1)文法。沒有衝突就是slr(1)文法。

3.如何判斷是不是lr(1)文法: (1)構造lr(1)自動機 (2)構造lr(1)分析表 (3)如果分析表中有任何衝突,則不是lr(1)文法。沒有衝突就是lr(1)文法。

【注】:移進/歸約衝突:同乙個項內,點號後面既有終結符號,點號又是某產生式最右邊。

歸約/歸約衝突:同乙個項內,點號出現在兩個或更多產生式的最右邊。

編譯原理中LR 0 專案集規範族的構造

此文略長。我也沒想到這寫起來這麼多,但對構造過程絕對清楚,一步步慢慢看吧。lr的第乙個l和ll的第乙個l含義相同,即從左到右掃瞄句子 第二個r表示right most最右推導。在通常的描述中,後面還有乙個括號裡面的數字如,lr 0 lr 1 這樣,括號裡面的數字表示用於決策所需的後續token分詞數...

編譯原理LR 0 專案集規範族的構造詳解

學編譯原理的時候,感覺什麼ll 1 lr 0 slr 1 lalr 1 思想滿天飛。而且做題的時候,一不留意,一道題就寫了三頁紙了。就拿今天這個玩意兒來講,我真的是考試前花了最多的時間,搞懂了 差不多搞懂了 這是個什麼玩意兒。以下內容,做題的話應該夠了而且很!容!易!理!解!其他學術情況恕博主也是個...

編譯原理中LR 0 專案集規範族的構造

lr的第乙個l和ll的第乙個l含義相同,即從左到右掃瞄句子 第二個r表示right most最右推導。在通常的描述中,後面還有乙個括號裡面的數字如,lr 0 lr 1 這樣,括號裡面的數字表示用於決策所需的後續token分詞數。首先看一下lr分析器的模型圖 可惜看出,lr分析器最關鍵的部分就是 lr...