LR(1)項目集族的構造:如何確定前向搜索符(新版)

舊版鏈接 https://blog.csdn.net/hhhhhhhhhhkkkkkkkkkk/article/details/19990287
按照這個標題搜進來的各位是不是以爲這也是和課本一樣的內容呢,其實這是我看了兩天課本才理解出來的內容啊,絕對和課本不一樣。 課本上LR(1)項目集族的構造內容如下
以S′→·S,#屬於初始項目集中,把’#‘號作爲向前搜索符,表示活前綴爲γ(若γ是有關S產生式的某一右部)要歸約成S時,必須面臨輸入符爲’#'號才行。我們對初始項目S′→·S,# 求閉包後再用轉換函數逐步求出整個文法的LR(1)項目集族。具體構造步驟如下:
(1) 構造LR(1)項目集的閉包函數。
a)假定I是一個項目集, I 的任何項目都屬於CLOSURE(I)。
b) 若有項目 A→α·Bβ,a 屬於CLOSURE(I),B→γ是文法中的產生式,β∈V*,b∈FIRST(βa), 則 B→·γ,b 也屬於CLOSURE(I)中。
c) 重複b)直到CLOSURE(I)不再增大爲止。
大家是不是看的一頭霧水呢。課本上還給出了一個例子:
文法:

0 S'->S

1 S->aAd

2 S->bAc

3 S->aec

4 S->bed

5 A->e

項目集簇:

S
a
b
A
e
A
e
d
c
c
d
I0:

S'->.S,#

S->.aAd,#

S->.bAc,#

S->.aec,#

S->.bed,#
I1:

S'->S.,#
I2:

S->a.Ad,#

S->a.ec,#

A->.e,d
I3:

S->b.Ac,#

S->b.ed,#

A->.e,c
I4:

S->aA.d,#
I5:

S->ae.c,#

A->e.,d
I6:

S->bA.c,#
I7:

S->be.d,#

A->e.,c
I8:

S->aAd.,#
I9:

S->aec.,#
I10:

S->bAc.,#
I11:

S->bed.,#

大家是不是在想I2中

A->e.,d

後的d,
I7中

A->e.,c

後的c是怎麼來的呢?

課本的答案是對的,但是寫法很是讓我們一頭霧水,下面讓我們來看看答案是怎麼出來的:

  • 1.一開始,S’是整個句子,所以後面理所當然跟句子結束符#。
    然後S後面是‘ε’(就是什麼都沒有)所以β=ε,
    接着逗號後面是‘#’即a=#,
    這樣FIRST(βa)=FIRST(ε#)={#}。這就是I0中S後面#號的來歷。

  • 2.在I2:S->a. Ad,#中
    A的後面是d,所以FIRST(d#)={d}(就是“d#”的第一個終結符d),所以接下來A的後面跟的是d如圖中綠色所示。

  • 3.在確定了A的逗號後面的搜索符後,基本上就可以直接照搬下去了,如圖中的紫色所示。(其實#號一直都在照搬來着,大家注意到沒?)

下面再講一點FIRST(β)的計算。

  • 1.如果β的第一個字符是終結符,如:
β=aAbbC
β=eBbbD

那麼

β
aAbbC
eBbbD
a
e
a,e

即:

FIRST(β)
=FIRST(aAbbC)+FIRST(eBbbD)
={a}+{e}={a,e};   (‘+’代表‘並’,那個符號不好打,用‘+’來代替了。​)
  • 2.如果β的第一個字符是非終結符,如:
β=AEbC
A=DBac
D=ε
B=ea
B=bd
E=ε

那麼:

β
AEbC
(DBac)EbC
((ε)Bac)EbC
(εBac)EbC
(Bac)EbC
εEbC
(Bac)EbC
(E)bC
(Bac)EbC
(ε)bC
(Bac)EbC
bC
((ea)ac)EbC
((bd)ac)EbC
b
(eac)EbC
(bac)EbC
b
eEbC
bEbC
b
e
b
e,b

即:

FIRST(β)
=FIRST(AEbC)
=FIRST(FIRST(A)EbC)
=FIRST(FIRST(DBac)EbC)
=FIRST(FIRST(FIRST(D)Bac)EbC)
=FIRST(FIRST(εBac)EbC)        (ε表示空,如果不是空,就結束了,但是空還要計算ε後面的Bac)
=FIRST(FIRST(εBac)EbC)+FIRST(FIRST(Bac)EbC)
=FIRST(εEbC)+FIRST(FIRST(Bac)EbC)
=FIRST(FIRST(E)bC)+FIRST(FIRST(Bac)EbC)
={εbC}+FIRST(FIRST(Bac)EbC)
={bC}+FIRST(FIRST(FIRST(ea)ac)EbC)+FIRST(FIRST(FIRST(bd)ac)EbC)        (由於B有兩個推導式,所以分開來寫並求並集,‘+’代表‘並’)
={b}+FIRST(FIRST(eac)EbC)+FIRST(FIRST(bac)EbC)
={b}+FIRST(eEbC)+FIRST(bEbC)
={b}+{e}+{b}
={e,b}

爲了普遍性,我把β搞的複雜了點,多看幾遍,你就會了。如果不會,在下面留言。我可是看了兩天才看懂的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章