參考《編譯原理及實踐》
有如下文法:a→(a)|a
先給出該文法的dfa:
根據規定,將a'→a作為開始。
得到文法:
a'→a
a→(a)|a
根據從左到右掃瞄,虛擬乙個游標。當前游標在-1處,即:
a'→a
↑(在a前面)
讓游標向右移動(第一次移動)。得到
a'→a
↑(在a後面)
但由於a是乙個可分解的文法(a→(a)|a)。所以,要向右移一位,則必須考慮分解式的情況,即得到:
1、由於a→(a),所以如果輸入時'('時,則有:
a→(a)
↑(在'('後面)
同時,由於a得到文法(a)和a
則在這裡需要加入另外兩個文法:
a→(a)
↑(在'('前)
a→a↑(在'a''前)
即:狀態0 到 狀態3的轉換
2、由於a→a,所以如果輸入時'a',則有:
a→a↑(在'a'後面)
即:狀態0到狀態2的轉換
3、若輸入為整個a則得到:
a→a↑(在a後面)
即:狀態0到狀態1的轉換
此時已得到4個狀態。且狀態1和2均已移動完成(到達規約狀態)
則現在只考慮狀態3。
狀態3能接受3個輸入。
1、輸入'(':則圖中狀態3的第二條文法得到第一條文法。第三條文法不響應'('
2、輸入'a':由第三條文法響應,得到狀態2(這是乙個規約狀態)
3、輸入a:則第一條文法響應輸入。得到狀態4
狀態4只接受一種輸入即')'到達狀態5(規約狀態)
移動-規約過程分析:
建立乙個堆疊,棧頂為$
設輸入為:((a)),在該輸入後新增$
從左到右掃瞄
1、'('。狀態轉到3,不是規約狀態,將3加入堆疊
當前堆疊:$ ( 3
2、'('。仍回到狀態3
當前堆疊 $ ( 3 ( 3
3、'a'。壓入棧頂,到達狀態2,其文法為a→a,從堆疊彈出a(棧頂元素),將a壓入棧頂
當前堆疊$ ( 3 ( a
4、壓入棧頂後到達狀態4,將')'壓入堆疊
當前堆疊:$ ( 3 ( a )
5、壓入堆疊後到達狀態5,是乙個規約狀態,則使用a→(a)規約,彈出狀態3,將a壓入棧頂到達狀態4
當前堆疊:$ ( a 4
6、')'。壓入棧頂到達狀態5,是乙個規約狀態,使用a→(a)規約
最終表示式被接受。
LR(0)文法的分析
include include include include include include include include include include include include include using namespace std typedef long long ll const...
編譯原理 LR分析(主要是LR(0)分析)
lr方法的基本思想就是,在規範歸約的過程中,一方面要記住已移進和歸約出的整個字串,也就是說要記住歷史 一方面能夠根據所用的產生式的推測未來可能碰到的輸入符號,也就是說能夠對未來進行展望。這樣,當一串貌似控制代碼的字串出現在分析棧的頂部時,我們希望能夠根據歷史和展望以及現實的輸入符號這三部分的材料,決...
編譯原理 LR分析(主要是LR(0)分析)
lr方法的基本思想就是,在規範歸約的過程中,一方面要記住已移進和歸約出的整個字串,也就是說要記住歷史 一方面能夠根據所用的產生式的推測未來可能碰到的輸入符號,也就是說能夠對未來進行展望。這樣,當一串貌似控制代碼的字串出現在分析棧的頂部時,我們希望能夠根據歷史和展望以及現實的輸入符號這三部分的材料,決...