編譯原理隨記 NFA轉DFA子集構造演算法

2021-10-07 16:28:10 字數 3177 閱讀 5492

[編譯原理隨記]正規表示式記號和狀態圖:

lex程式的組成部分:

宣告部分 - 就是宣告變數命名、符號、常量、正則定義這些;

轉換規則 - 就是類似於狀態圖的狀態轉換一樣,每乙個輸入字元都會進行乙個**塊處理,這個處理就叫轉換規則。

比如:

p1  

p2 .....

每乙個 p 代表乙個正規表示式(可複雜可簡單), action 就代表執行程式**塊。

輔助過程 - 比如需要依賴什麼方法,外部包,第三方等等的東西,引進來就行。

有窮自動機:

可以理解為更加一般化的狀態轉換圖,分為確定有窮自動機(dfa),不確定有窮自動機(nfa)。作用就是把正規表示式引導並編譯成識別器,可以理解為一種抽象化框架來完成識別器的編碼,從而做出識別器功能。

一般化:

數學中指普遍性,從已有物件小集合到已有物件大集合過度思想,相似於泛化。最簡單理解是抽象化思想,比如有窮自動機就是一種狀態轉換圖的抽象。

不確定有窮自動機(nfa):

其實是輸入有窮序列時候,輸入導致轉換的狀態不確定。

比如說(a|b)*abb,(a|b)*就不確定輸入導致的狀態如何轉換,比如我輸入了 a ,我不知道下乙個狀態是 0 還是 1。

狀態轉換圖:

確定有窮自動機(dfa):

輸入有窮序列時候,能夠確定輸入導致的狀態。

dfa是比較容易建立程式的,所以將nfa轉為乙個dfa是很重要的。

我們要用到式子:ε-closure(s),ε-closure(move(t , a))

ε-closure(s)

表示由狀態s經由條件ε可以到達的所有狀態的集合。

= ε-closure(s) 表示:狀態(接收狀態,不一定是流程終點,是到達的點),就是從s狀態(叫做開始狀態,開始不一定是流程起點,是出發的點)轉換成的狀態集合,即ε-closure(s)移動任意個 ε 狀態是

ε-closure(move(t , a))

其中move(t, a)意思:假設當前狀態 t = ,然後輸入 a ;

ε-closure(move(t , a)) 就是 當前狀態 t = ,然後輸入 a 記為move(t, a),然後得出狀態假設為,即:

ε-closure(move(t , a))  = ε-closure(move( , a))  =

就是 當前狀態: 輸入了 a 之後的狀態,也意味著 所處的狀態是可以輸入a的(其中有任意個輸入為 ε 的操作)。

假設只有1,2才輸入a,那麼:ε-closure(move(t , a))  = ε-closure(move( , a))  = ,集合裡面5,6,7,8,9和1,2的狀態一致,只不過不能輸入a的意思。

比如說 (a|b)* abb 的另乙個nfa 狀態圖:

1、開始

-- 我要從開始輸入乙個a,首先 start 狀態是:

ε-closure(0) = ,因為這些狀態都是從start開始輸入任意個 ε 得到的狀態,開始狀態 0 也等同於輸入任意個 ε 後的狀態 。

-- 然後輸入a操作的狀態是:

ε-closure(move( , a))

因為圖中只有 2 , 7狀態才可以輸入 a,所以輸入 a 之後狀態是 3 , 8,得

ε-closure(move( , a)) = ε-closure()

同時因為  和 move(,ε)(輸入任意個  ε ,其實ε-closure 就表明了)狀態時一致的,因此得出:

ε-closure(move( , a)) = ε-closure() = (根據 3、8的狀態位置,然後沿著箭頭走空串狀態,結果裡面摻入了很多空串輸入的狀態)

2、把可能的狀態都列出來:

start =  = a

movea = = b   

movebcycle =  = c

moveb1 = = d // 這裡需要帶上迴圈中可能存在的狀態,因為存在迴圈可能

moveb2 = = e

3、編寫dtran**(有點像真值表)怎麼編寫,就是使用 ε-closure(move(t , a))  和  ε-closure(move(t , b))  得出狀態,

然後寫出 (a 狀態,輸入 a | b) 計算如下,其他可以照推:

ε-closure(move(a , a)) = b // 具體計算省略

ε-closure(move(a , b)) = c

然後將 a b c d e 狀態(這是從 2的狀態拿出來的..... 這些狀態集合統稱的新的狀態)和輸入 a | b 的結果,編寫成**為:

已經可以看到,我在a狀態,如果輸入 a 那麼下乙個狀態一定是 b (完全確定了),其他同理。

4、畫狀態圖

根據**連線就行了,弄成dfa的狀態圖,肯定寫的出程式了:

圖裡面,比如

[編譯原理隨記]正規表示式轉為dfa狀態圖(thompsion構造法):

[編譯原理隨記]正規表示式構建dfa(r(#)followpos(i)構造):

編譯原理 NFA構造DFA

本題摘自北郵的編譯原理與技術。首先,根據此圖構造狀態轉換表 表中第一列第一行表示從第乙個符號b通過任意個空轉換能到達的節點,ia表示由此行的狀態陣列 可以看作0狀態 經過乙個a可以到達的節點,同理,ib表示由狀態陣列經過乙個b可以到達的節點。當然,有些人可能覺得和看作兩個狀態不合理,他們之間不是有交...

編譯原理 NFA轉換到DFA

學習分享 超詳細解析nfa轉換到dfa 例nfa 1.第一步畫出類似下面的 iia ib2.填寫 i iaib 第一行中i表示從s開始經過任意個 到達的狀態的集合。每行中的ia,ib表示從該行i集合中各個狀態開始經過乙個a b 以及後面有任意個 必須出現在a b 後 到達的狀態的集合。其餘行中的i表...

NFA轉DFA程式設計

實驗二 利用子集構造法實現nfa到dfa的轉換 問題描述 利用子集構造法實現nfa到dfa的轉換。nfa的確定化 輸入形式 nfa 參見樣例。其中,第一列表示狀態名,終狀態用f表示 第二列和第三列分別表示輸入字元a和b所到達的狀態。輸出形式 dfa 參見樣例。其中,第一列表示輸入狀態名 第二列表示重...