經過前面兩篇文章。已經講清楚了LR語法分析中最重要的分析表的構造過程。先補充一個小問題,就是LR(0)項目的分類
根據圓點所在的位置和圓點后是終結符還是非終結符或為空把項目分為以下幾種:
移進項目: 形如 A→α .a β ,a是終結符, a ,b∈V* 以下同
待約項目:A→α .B β , 其中B是非終結符
歸約項目:A→α . 表明產生式已分析完成。
接受項目:形如 S’→S .
特別的。A→ε的LR(0)項目只有A→ • 是歸約項目
因為LR分析表的構造前面兩篇文章已經講的很清楚了,所以這個題目重要是解釋一下如何使用分析表來構造,分析表的構造也許你得自己參考前面兩篇文章來構造了。題目來自網絡。
好,下面看題目,已知文法G[S]:
(1) S → aAcBe
(2) A → b
(3) A → Ab
(4) B → d
寫出對輸入串 abbcde#的LR分析 過程。
在分析的時候,因為我們的手工分析,所以還需要一個表來記錄我們的步驟。否則記不住啊。該表共需7列。行數不定。做到哪是哪。
步驟 | 符號棧 | 輸入符號棧 | 動作 | 狀態棧 | ACTION | GOTO |
其中,步驟就是從1向下遞增。符號棧用來保存運算中的結果,初始為#,輸入符號棧保存輸入串,初始值為給定的。動作里面就是用來注釋是進行移進,還是規約。狀態棧就是保持LR分析表的那個狀態了。Action 和Goto同理
通過前兩篇文章的步驟,此題可以構造出如下的一張LR分析表
分析表中有Si和rj大家都知道的。s是shift的縮寫,也就是移進,r是reduce的縮寫,也就是規約。規約是推導的逆操作,大家都懂。
先來看看在進行分析的時候s和j操作的規則
Si:移進,把i移入到狀態棧,把a移入到文法符號棧。其中i,j表示狀態號。
ri:歸約,用第i個產生式歸約,同時狀態棧與符號棧退出相應個符號,並把GOTO表相應狀態和第i個產生式的左部非終結符入棧。
文法中有A→β的產生式,若β的長度為r(即|β|=r),則從狀態棧和文法符號棧中自棧頂向下去掉r個符號,即棧指針P減去r。並把A移入文法符號棧內,Sj=GOTO[Si,A]移進狀態棧,其中Si為修改指針后的棧頂狀態。
當歸約到文法符號棧中只剩文法的開始符號S時,並且輸入符號串已結束即當前輸入符是’#',則為分析成功。
然后使用我們將要使用的輔助表來分析吧,為了簡單。我還是直接給出答案。然后分析一下典型的情況。
第一步,符號棧中是#,輸入符號串就是給定的要分析的串,狀態棧因為從0開始,所以狀態棧直接填0,大家都知道,LR分析是從左到右掃描的。所以心里想着一根指針p,p首先指向輸入串的a,然后我們查分析表的(0,a),0就是狀態0,a就是指針的當前字符。分析表中的(0,a)是s2,填入第一步的action,並且動作列填入移進,根據規則,將2入狀態棧,a入符號棧,
進入第二步,指針p肯定要前進一步了,所以輸入符號串就進入b了。此步同上一步,不多解釋。
關鍵是進入第三步后,此時,符號棧中為#ab,輸入符號串是bcde#,狀態棧是024,此時去查表,差的是(4,b),4是狀態棧頂,b是p指針的當前位置。發現是r2,根據規則,用第二條產生式(2) A → b來規約。把動作欄先填了,同時狀態棧與符號棧退出相應個符號,也即是說,把狀態欄的棧頂4,退出來,同時符號棧的b也退出,心里想着,不填表,並把GOTO表相應狀態和第i個產生式的左部非終結符入棧。Goto表需要查的是(2,A)=3,2是r2的2,A是第二個產生式的左部嘛。所以,就把3入狀態棧,A入符號棧。
后面的都是一樣的。不解釋了。要想學懂編譯原理。多動手是必需的。你也手工試試吧。
參考:
http://leaver.me/archives/574.html
http://leaver.me/archives/548.html