試析從LR 0 生成DFA及移動 規約過程分析

2021-08-30 05:29:25 字數 1260 閱讀 4464

參考《編譯原理及實踐》

有如下文法: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方法的基本思想就是,在規範歸約的過程中,一方面要記住已移進和歸約出的整個字串,也就是說要記住歷史 一方面能夠根據所用的產生式的推測未來可能碰到的輸入符號,也就是說能夠對未來進行展望。這樣,當一串貌似控制代碼的字串出現在分析棧的頂部時,我們希望能夠根據歷史和展望以及現實的輸入符號這三部分的材料,決...