編譯原理slr1分析過程
❶ 關於LL(1)文法
(1)first(E)={(,i},first(D)={+,-,ε},first(T)={(,i},first(S)={*,/,ε}
first(F)={(,i}
follow(E)={#,)},follow(D)={#,)},follow(T)={+,-,#,)} follow(S)={+,-,#,)} follow(F)={*,/,+,-,#,)}
(2)select(E->TD)=FIRST(TD)={(,i}
SELECT(E->+TD)={+}
SELECT(E->-TD)={-}
SELECT(E->ε)={#,)}
SELECT(T->FS)={(,i}
SELECT(S->*FS)={*}
SELECT(S->/FS)={/}
SELECT(S->ε)={+,-,#,)}
SELECT(F->(E))={(}
SELECT(F->i)={i}
預測分析表:
+ - * / ( ) i #
E ->+TD ->-TD ->TD ->ε ->TD ->ε
D
T ->FS ->FS
S ->ε ->ε ->*FS ->/FS ->(E) ->ε ->ε
F ->i
(3)i/i-i的分析過程:
步驟 輸入串 剩餘串 移進或規約
1 # i/i-i#
2 #i /i-i# E->TD
3 #DT ......
...
剩餘的只要按照書上的步驟填就行了。
❷ 編譯器筆記13-語法分析-LR分析法概述
可以用LR分析法分析的文法可以稱為LR分析法。LR文法( Knuth ,1963)是最大的、可以構造出相應移入- 歸約語法分析器的文法類。
LR(k)分析,需要向前查看k個輸入符號的LR分析,k=0 和 k=1 這兩種情況具有實踐意義,當省略(k)時,表示k=1。而在LR(k)這樣的名稱中,k代表的是分析時所需前瞻符號(lookahead symbol)的數量,也就是除了當前處理到的輸入符號之外,還得再向右引用幾個符號之意;省略 (k)時即視為LR(1),而非LR(0)。
作為對比這里列出LL(1)文法的含義:
問:自底向上分析的關鍵問題是什麼?
答:如何正確地識別句柄,句柄是逐步形成的,用「狀態」表示句柄識別的進展程度。例如在 自底向上分析概述 中所提及到句柄識別錯誤的例子,通過狀態跟下一個輸入符號就可以判斷出應該做出哪一個動作,而狀態相當於一種記憶功能記錄當前句柄識別到什麼程度。
與移入分析器不同的是LR分析器多了一個與符號棧平行的狀態棧。
之後的分析過程與上圖類似,直至到如下狀態,分析成功。可見分析時進行什麼動作是由棧狀態棧棧頂的狀態和下一個輸入符號決定。
輸入:串w和LR語法分析表,該表描述了文法G的ACTION函數和GOTO函數。
輸出:如果w在L(G)中,則輸出w的自底向上語法分析過程中的歸約步驟;否則給出一個錯誤指示。
方法:初始時,語法分析器棧中的內容為初始狀態s0 ,輸入緩沖區中的內容為w$。然後,語法分析器執行下面的程序:
先了解LR(0)項目和增廣文法這兩個概念
右部某位置標有圓點的產生式稱為相應文法的一個LR(0)項目(簡稱為項目):A → α1·α2
文法開始符號S表示的是語言中的最大成分。如下圖當b出現時可以將它移入到分析棧中。b移進棧後我們期待歸約出B。當歸約出B時我們還期待再歸約一個B。
如果G是一個以S為開始符號的文法,則G的增廣文法G'就是在G中加上新開始符號S'和產生式S'→S而得到的文法
引入這個新的開始產生式的目的是使得文法開始符號僅出現在一個產生式的左邊,從而使得分析器只有一個接受狀態。
項目可以分為以下幾類:
上圖中S'對應的第一個項目稱為初始項目,而S'對應的最後一個項目稱之為接收項目在此狀態下文法的開始符號已經被歸約出來,因此可以接收了故稱為接收項目。紅色方框中的項目則被稱為歸約項目。
項目集閉包(Closure of Item Sets)
可以把等價的項目組成一個項目集(I),稱為項目集閉包,每個項目集閉包對應著自動機的一個狀態。
先了解CLOSURE和GOTO這兩個函數
項目集I的閉包的數學定義:
返回項目集I對應於文法符號X的後繼項目集閉包
規范LR(0)項集族(Canonical LR(0) Collection)
說明: 該自動機的初始狀態就是文法的初始項目的項目集閉包,其終止狀態集合只有一個狀態就是文法的接收項目的項目集閉包。
如果LR(0)分析表中沒有語法分析動作沖突,那麼給定的文法就稱為LR(0)。不是所有CFG都能用LR(0)方法進行分析,也就是說,CFG不總是LR(0)文法。
為了解決移進/歸約沖突和歸約/歸約沖突需要使用到 SLR分析法 和 LR(1)分析法 。
問: 為什麼沒有移進/移進沖突?
答: 首先只有在移進狀態和待約狀態下的項目才會有使用到移進操作。在0狀態時所有項目都是移進狀態根據LL文法顯然不會產生移進/移進操作,因為每個產生式左部的SELECT集是沒有交集的。而在其他具有待約狀態項目的狀態中,所有集合都是等價的。假若在某狀態下輸入終結符y時發生移進/移進沖突,即存在兩個這樣的項目A0→α0·yβ0,A1→α1·yβ1,但顯然這兩個項目是不等價的顯然與同一狀態下所有項目等價相矛盾,因此這種移進/移進沖突是不存在的。假若在某狀態下輸入非終結符X時發生移進/移進沖突,即存在兩個這樣的項目A0→α0·Xβ0,A1→α1·Xβ1,而A0與A1在同一狀態下是等價的則兩項目要麼是A0→α0·Xβ0與X→.Xβ1(原項目A1變為X,α1變為ε)要麼是A1→α1·Xβ1與X→.Xβ0(原項目A0變為X,α0變為ε)。顯然X→Xβ0|Xβ1(左遞歸)是不符合LL文法的因此這種情況也是不可能出現。
綜上移進/移進沖突在LR分析下是不存在的。
❸ 編譯原理 有文法G(S)這道題怎麼做
首先擴展文法為:
1)S1->S
2)S->aS
3)S->bS
4)S->a
則:
I0=Closure({S1->.S})={S1->.S,S->.aS,S->.bS,S->.a}
go(I0,S)=Closure({S1->S.})={S1->S.}=I1
go(I0,a)=Closure({S->a.S,S->a.})={S->a.S,S->.aS,S->.bS,S->.a,S->a.}=I2
go(I0,b)=Closure({S->b.S})={S->b.S,S->.aS,S->.bS,S->.a}=I3
go(I2,S)=closure({S->aS.})={S->aS.}=I4
go(I2,a)=Closure({S->a.S,S->a.})=I2
go(I2,b)=Closure({S->b.S})=I3
go(I3,S)=Closure({S->bS.})={S->bS.}=I5
go(I3,a)=Closure({S->a.S,S->a.})=I2
go(I3,b)=Closure({S->b.S})=I3
由圖所示,狀態I2,既有歸約項目(S->a.)又有移近項目(S->.aS,S->.bS,S->.a),產生沖突。當用SRL分析法時,需向前看一步,即求出:
Follow(S)=Follow(S1)={#}
則,Follow(S)∩{a,b}=∮
故而Action(I2,a)=s2
Action(I2,b)=s3
Action(I2,#)=r4
則構造出srl分析表如下所示:
ActionGoto
ab# S
I0 s2s3 1
I1 acc
I2s2s3 r4 4
I3s2s3 5
I4 r2r2r2
I5 r3r3 r3
❹ 編譯原理怎麼判斷是否為slr文法
LL(1)就是向前只搜索1個符號,即與FIRST()匹配,如果FIRST為空則還要考慮FELLOW.
LR需要構造一張LR分析表,此表用於當面臨輸入字元時,將它移進,規約(即自下而上分析思想),接受還是出錯.
LR(0)找出句柄前綴,構造分析表,然後根據輸入符號進行規約.
SLR(1)使用LR(0)時若有沖突,不知道規約,移進,活移進哪一個,所以需要向前搜索,則只把有問題的地方向前搜索一次.
LR(1)1.在每個項目中增加搜索符.2.舉個列子如有A->α.Bβ,則還需將B的規則也加入.
LALR(1)就是假如兩個產生式集相同則將它們合並為一個,幾合並同心集.
❺ 編譯原理
4、文法G為:
A->aABe/Ba
B->dB/ε
構造LL(1)分析表並判斷adae是否是該文法的句子。
5、文法G為:
A->i:=E;
E->E+E
E->E*E
E->i
構造SLR分析表,並判斷i:=i*i是否是該文法的句子。
6、文法G為:
S->E
E->aB/bB
A->cA/d
B->Cb/d
構造該文法的LR(0)和SLR(1)分析表,並模擬分析句子bcd時分析棧和輸入串的變化。
7、文法G為:
E->E+T/T
T->T*F/F
F->P^F/P
P->(E)/i
判斷該文法是否為算符優先文法,若是,構造優先表。
❻ 編譯原理LR分析法中的SLR(1)分析表和LR分析過程、語法樹怎麼求
第二題和第三題拿去,剛做的:
由B->cAa|c就可知該文法不是LR(0)文法了
❼ 編譯原理中語法分析的一道問題
LALR我做著做著覺得不對,但SLR還是沒問題的,這道題工程量非常龐大,想必以後也一定有人問,我就簡要的帶過吧,我歸納的解題步驟是:
構造LR(0)項目集規范族
求出FOLLOW集
根據規則圈出sj和rj對應的產生式
算出goto數
構造分析表