筆記blog
直接作題是有一些特定步驟,有技巧。但也必須先了解一些基本概念,本篇會經過例題形式解釋概念,會容易理解和記憶,以及解決相似問題。圖片
若是隻想作題能夠直接下拉至習題部分。編譯
對於產生式 A→aBcD,就能夠分解爲下面幾個不一樣的識別狀態:table
(1)A→.aBcD
(2)A→a.BcD
(3)A→aB.cD
(4)A→aBc.D
(5)A→aBcD.class
「.」 的左部符號表示已被識別出來的那部分句柄符號編譯原理
狀態(1)表示:處於句柄的頭
狀態(2)表示:已經識別出字符 a,等待 造成以 B 爲產生式左部的右部
狀態(3)表示:剛剛進行了一次規約,即把關於 B 的產生式右部規約成 B
狀態(4)表示:已經識別出字符 c,等待 造成以 D 爲產生式左部的右部
狀態(5)表示:已經到達句柄的尾巴,能夠把 aBcD 規約爲產生式左部的符號 A原理
字面意思理解:bfc
字符 | 含義 |
---|---|
L | 表示 從左到右 掃描輸入串 |
R | 表示利用 最右分析方法 來識別句子,即構造一個 最右推導的逆過程 |
k | 表示向右查看輸入串符號的個數 |
LR 分析過程是規範歸約的過程搜索
規範規約是最右推導的逆過程,最右推導是規範推導,因此 最左規約是規範規約。循環
LR 分析法根據當前分析棧中的符號串和向右順序查看輸入串的 k 個符號就能夠惟一肯定分析器的動做是移進仍是歸約、利用那個產生式進行歸約。
當沒有指明 k 是幾的時候,默認爲 1
文法的拓廣是對現有文法,添加一個 S',並對文法進行展開。
例如:
對於文法 G[E]:
E → E+T|T
T → T*F|F
F → i|(E)
能夠把它拓廣爲
文法 G[E']:
E' → E
E → E+T|T
T → T*F|F
F → i|(E)
此時可能會有疑問,不就是加了個開始符號,有什麼意義呢?爲何要再加個開始符號呢?
加開始符號是爲了狀態的表示,這樣原來的 S 會成爲右部,能夠表示 .S 和 S.
那同一非終結符的右部有多種狀況爲何不展開呢?
這裏是說拓廣文法,是添加開始符號,能夠展開能夠不展開,可是通常默認要展開,通常一道題不會只讓求拓廣文法,而是爲了後面。通常題目中是說 「求該文法的拓廣文法並編號」,此時請必定要展開。展開後應該是這樣:
1.E'→E
2.E → E+T
3.E → T
4.T → T*F
5.T → F
6.F → i
7.F → (E)
上面提到拓廣文法,展開,以及編號。
先看例題:
對於文法 G[S]:
S → vI:T
I → I,i
I → i
T → r
能夠把它拓廣並編號,以下:
文法 G[S']:
1.S' → S
2.S → vI:T
3.I → I,i
4.I → i
5.T → r
它的所有 LR(0) 項目,以下:
1.S' → .S
2.S' → S.
3.S → .vI:T
4.S → v.I:T
5.S → vI.:T
6.S → vI:.T
7.S → vI:T.
8.I → .I,i
9.I → I.,i
10.I → I,.i
11.I → I,i.
12.I → .i
13.I → i.
14.T → .r
15.T → r.
對上面 LR(0) 項目進行分類
類型 | 包含 | 特色 |
---|---|---|
規約項目 | 2, 7, 11, 13, 15 | . 在右部的末尾 |
接收項目 | 2 | . 在開始符號的末尾 |
移進項目 | 3, 5, 9, 10, 12, 14 | . 後面跟着終結符,表移進 |
待約項目 | 1, 4, 6, 8 | . 後面跟着非終結符,表等待後面非終結符的規約,簡稱待約 |
誰和誰是等價狀態?
例如:
待約項目 4 即 S→v.I:T 它的含義是等待棧頂規約出 I,但還沒有識別對應 I 的那些句柄的任何符號;
項目 8 即 I→.I,i 和項目 12 即 I→.i 的含義也是期待棧頂造成 I 的句柄,因此這三個項目的含義是同樣的,即 4, 8, 12 三個狀態是等價的。
同理:項目 6 即 S → vI:.T 和項目 14 即 T → .r 也是等價的
爲何它們是等價狀態?怎麼判斷等價狀態?
上面有說由於他們表示的含義是同樣的,而且會發現等價確定涉及至少一個待約項目,以及一個 . 在最左端的移進項目。
這是由於,待約項目是 . 後面跟非終結符,這個 . 是在非終結符的前面;當存在該非終結符的產生式時,且 . 在最左端的時候。由於 . 在最左端,其實也是至關於在該非終結符的前面。因此是一個等價的狀態。
LR 分析器的關鍵部分是 分析表的構造。分析表有如下幾種:
規範的 LR 分析表:
簡單的 LR 分析表:
向前看的 LR 分析表:
總結: LR(0) 功能最弱,功能弱是說當文法中產生式比較複雜,出現某些問題時,沒法解決。這些問題一部分能夠由 SLR 分析法解決。但還有一部分 SLR 解決不了,能夠用 LR(1) 來解決。
在規範歸約過程當中,一方面記住已移進和歸約出的整個符號串,即記住 「歷史」,另外一方面根據所用的產生式推測將來可能碰到的輸入符號,即對將來進行 「展望」。
當一串貌似句柄的符號串呈現於分析棧的頂端時,根據所記載的 「歷史」 和 「展望」 材料,來肯定棧頂的符號串是否構成句柄。
爲了記住分析的 「歷史」 和聚集 「展望」 的信息,LR 分析法這樣處理:
將歸約過程的 「歷史」 和 「展望」 材料綜合抽象成某些狀態,存放在一個狀態棧中,棧中每一個狀態都歸納了從分析開始直到某一歸約階段的所有「歷史」和「展望」材料。
LR(1) 分析法這樣處理:
首先,明白了在 LR(1) 分析法中展望是爲了解決其餘分析法解決不了的問題。簡單的說就是,狀態會出現衝突,咱們不能只經過後 1 個輸入串符號,直接肯定選用哪一個產生式,這是嚴重的錯誤。
因此 展望(向前搜索符) 是經過展望後面的內容,因此展望對應的終結符,應該 屬於該非終結符的 FOLLOW 集(確切的說,屬於 FOLLOW 集中的具體哪一個個終結符,應該根據產生式的推導過程肯定,經過語法樹來分析,是比較直觀的方法。也能夠直接經過求該非終結符後的 FIRST 集來肯定,但要注意是對誰求 FIRST 集,可表示爲 FIRST(βa),例題中會提到),來幫助惟一肯定選擇產生式。
拓展注:這裏提到的 FOLLOW 集和 FIRST 集不是衝突的,由於咱們要求的向前搜索符時 FOLLOW 集的子集,有時候不能肯定,因此用 FIRST(βa), β 表示由誰哪一個非終結符推導的,這個非終結符的後面的剩餘串,a 表示它上一個狀態中的向前搜索符。它倆拼接起來的串,對該串求 FIRST 集。
那麼可能會有疑問,利用上一個狀態?那第一個狀態呢?第一個狀態是固定的 S'→S,#
其實 # 就是 S 的 FOLLOW 集中的惟一的元素,它也是開始符號的向前搜索符
因此說 FOLLOW 集和 FIRST(βa) 是均可以求的,FIRST(βa) 是準確的向前搜索符,它是 FOLLOW 集的一部分
在 LR(1) 中,用
狀態, 終結符
例如:S' → # (#表示開始符號FOLLOW集會提到那個符號,有的地方用 $,是同樣的 )
這種形式是表式展望,終結符就是展望的後面的終結符,具體的下面例題中還會提到。
給定文法 G[S]:
S→L=R | R
L→*R | id
R→L
回答如下問題:
(1)文法的拓廣並編號
(2)LR(1) 項目集規範族所對應的識別活前綴的 DFA
(3)構造 LR(1) 分析表
解析:
拓廣文法 G[S']:
(0)S'→S
(1)S→L=R
(2)S→R
(3)L→*R
(4)L→id
(5)R→L
這裏就涉及到 「展望」 這個知識點了
向前搜索符的 FIRST 集求法:
求法 FIRST(βa)
對於 I0 :
首先 S' → .S, # 這個是固定的,就是第一個狀態的核心項目
下面對 S 求向前全部符都沒問題,都是 #
到了 L→.*R,這裏,求向前搜索符,使用 FIRST(βa)
應該是求 FIRST(=R#) 因此就是 = 了
爲何是 =R#?
由於 β 表示由誰哪一個非終結符推導的,這裏就是上面狀態【S→.L=R, #】這個非終結符 L 的後面的剩餘串是 =R,a 表示它上一個狀態中的向前搜索符,就是 #,拼接起來就是 =R#。
(圖片來源:中國大學慕課 -《編譯原理》哈爾濱工業大學 陳老師)
該 DFA 有窮自動機的解釋:
(1)這樣表示形式就是自動機,每一個方框表示一個狀態,從 I0 到 I13 因此共有 14 個狀態。
(2)每一個狀態中包含的多個項目,都是等價的。
(3)每一個項目中逗號後面的終結符或者 # 表示展望的終結符。
(4)關於畫出 DFA 的步驟:
(圖片來源:中國大學慕課 -《編譯原理》哈爾濱工業大學 陳老師)
能夠看出來 R 的展望應該有兩種狀況,一個是 =,一種是 #
但此時,咱們經過 S → R 找到的 R,因此應該是 #
不斷循環經過,將 . 後移,判斷下一個狀態,找出等價狀態,直到判斷完成。
根據自動機便可構造 LL(1) 分析表:
(圖片來源:中國大學慕課 -《編譯原理》哈爾濱工業大學 陳老師)
LL(1) 分析表解釋補充:
(1)內容 LL(1) 分析表 = 動做表 (ACTION) + 狀態轉移表(GOTO)
(2)動做表 中的每個元素 ACTION[S,a] 規定了當 棧頂狀態 爲 S,且面臨輸入符號 a 時應採起的動做。根據自動機中的終結符邊可判斷。
(3)狀態轉換表 中的每個元素 GOTO[S,x] 規定了當狀態 S 面對文法符號位 x 時的下一個狀態。根據自動機中的非終結符邊可判斷。
(4)動做表 的列對應全部終結符加上 #
(5)狀態轉換表 的列對應全部非終結符,不包括 S',由於 S 就是開始符號,S' 是爲了使 「接收狀態」 易於識別,所引入的。
(6)動做表 中例如:
(7)狀態轉換表 中例如:
(8)構造 LL(1) 分析表的步驟,重要 !!!:
!!!ACTION 表的構造:
(9)上面也更深刻的瞭解了展望的意義,首先,展望是存在一個狀態中的,終結符,對應的應該爲是當前等價的狀態,操做也就應該是移進。若是是自動機的邊,就是說不是當前狀態了,因此對應的是規約。
易錯點: