lr方法的基本思想就是,在規範歸約的過程中,一方面要記住已移進和歸約出的整個字串,也就是說要記住歷史;一方面能夠根據所用的產生式的推測未來可能碰到的輸入符號,也就是說能夠對未來進行展望。這樣,當一串貌似控制代碼的字串出現在分析棧的頂部時,我們希望能夠根據歷史和展望以及現實的輸入符號這三部分的材料,決定出現在棧頂的這一串符號是否就是我們要找的控制代碼。
採用下推自動機這種資料模型。包括以下幾個部分:
1.輸入帶
2.分析棧:包括狀態棧和文法符號棧兩部分。(s0,#)為分析開始前預先放在棧裡的初始狀態和句子括號。
3.lr 分析表:包括動作表和狀態轉移表兩張表。
一張lr分析表包括兩部分:動作表(action)和狀態轉換表(goto)。它們都是二維陣列。action[s,a]
規定了當狀態
s面臨輸入符號
a時應採取什麼動作
(移進、歸約、接受和報錯),而
goto[s,x]
規定了當狀態
s面對文法符號
x(終結符或非終結符
)時的下一狀態是什麼。
顯然, goto[s,x]定義了乙個以文法符號為字母表的dfa。
不同的 lr 分析法構造lr分析表的方法都不同,由此產生了不同的lr分析法。
置ip指向輸入串w的第乙個符號
令si為棧頂狀態
a是ip指向的符號(當前輸入符號)
begin(重複開始)
ifaction[si,a]=sjthen
begin
push j,a (進棧)
ip前進(指向下一輸入符號)
endelse
ifaction[si,a]=rj(若第j條產生式為a→β)
then
begin
pop|β| 項
若當前棧頂狀態為sk
pushgoto[sk,a] 和a(進棧)
endelse
ifaction[si,a]=acc then
return (成功)
else error
end. (重複結束)
1、可歸字首與規範句型的活字首
文法g[s]:
(1) s → aacbe[1]
(2) a → b[2]
(3) a →ab[3]
(4) b → d[4]
sþaacbe[1]
þaacd[4]e[1]
þaab[3]cd[4]e[1]
þab[2]b[3]cd[4]e[1]
每次歸約句型的前部分依次為:
ab[2]
aab[3]
aacd[4]
aacbe[1]
規範句型的這種前部分符號串稱為可歸字首
我們把形成可歸字首之前包括可歸字首在內的所有規範句型的字首都稱為活字首
(活字首就是可歸字首的字首)如下:
e,a,ab
e,a,aa,aab
e,a,aa,aac,aacd
e,a,aa,aac,aacb,aacbe
(一)lr分析構造識別活字首的有窮自動機
專案(item
):在每個產生式的右部適當位置新增乙個圓點構成專案。
根據圓點所在的位置和圓點後是終結符還是非終結符把專案分為以下幾種:
移進專案,形如 a→a•ab
待約專案,形如 a→a•bb
歸約專案,形如 a→a•
接受專案,形如s』 →s•
根據圓點所在的位置和圓點後是終結符還是非終結符把專案分為以下幾種:
移進專案,形如 a →a . ab
待約專案,形如 a→a . bb
歸約專案,形如 a→a .
接受專案,形如 s』→s.
把文法的所有產生式的專案都引出,每個專案都為
nfa的乙個狀態。其中
文法的第乙個產生式的第乙個專案為文法的初態
文法的接受專案為文法的句子識別態
文法的每乙個產生式的歸約專案為文法的控制代碼識別態
專案圓點的左部表示分析過程的某個時刻用該產生式歸約時控制代碼已識別的部分,圓點右部表示待識別的部分。
1、把文法的所有產生式的專案都引出,每個專案都為nfa的乙個狀態
2、確定初態、控制代碼識別態、句子識別態
3、確定狀態之間的轉換關係
*若專案i為
x →x1x
2...x
i-1•xi
...xn專案
j為x →x1x
2...x
i-1xi •
xi+1
...x
n則從狀態
i到狀態
j連一條標記為xi
的箭弧*若i為x→g•ad,k為a→•b,則從狀態i畫標 記為
e的箭弧到狀態k
方法一:(採用子集構造法)
方法二:通過構造文法g的lr(0)的專案集規範族來直接構造識別活字首的dfa
lr(0)專案集規範族的構造
構成識別乙個文法活字首的dfa專案集(狀態)的全體稱為這個文法的lr(0)
專案集規範族(1
)通過閉包函式(closure)來求
dfa乙個狀態的專案集,找出所有的等價的專案。如果i
是文法g
』的乙個專案集,定義和構造
i的閉包closure(i)如下:
a)i的專案都在
closure(i)中b)
若a→a•
bb屬於
closure(i)
,則每一形如b→•
g的專案也屬於
closure(i)
c)重複
b)直到
closure(i)
不再擴大
(2)定義轉換函式如下:
goto(i
,x)=closure(j)
其中:i為包含某一專案集的狀態,x為一文法符號
j=圓點不在產生式右部最左邊的專案稱為核,唯一的例外是s』 →
• s。因此用goto(i
,x)轉換函式得到的j為轉向後狀態所含專案集的核
使用閉包函式(closure)和轉向函式(goto(i,x))構造文法g』的lr(0)的專案集規範族,步驟如下:
a)置專案s』→ •s為初態集的核,然後對核求閉包closure()得到初態的專案集
b)對初態集或其它所構造的專案集應用轉換函式goto(i,x)=closure(j)求出新狀態j的專案集
c)重複b)直到不出現新的專案集為止
編譯原理 LR分析(主要是LR(0)分析)
lr方法的基本思想就是,在規範歸約的過程中,一方面要記住已移進和歸約出的整個字串,也就是說要記住歷史 一方面能夠根據所用的產生式的推測未來可能碰到的輸入符號,也就是說能夠對未來進行展望。這樣,當一串貌似控制代碼的字串出現在分析棧的頂部時,我們希望能夠根據歷史和展望以及現實的輸入符號這三部分的材料,決...
編譯原理 LR 0 分析舉例
方便複習用 文法 e l a e rightarrow l a e l a l el el rightarrow el e l el e 分別求 dfa parsing table 和串 a a 的分析過程。先拆分和擴張文法 1.e e1.e rightarrow e 1.e e 2.e l 2.e...
LR(0)文法的分析
include include include include include include include include include include include include include using namespace std typedef long long ll const...