1. 程式人生 > 其它 >詞法分析筆記-2

詞法分析筆記-2

六、有窮自動機

現在, 我們將揭示Lex是如何將它的輸入程式變成一個詞法分析器的。 轉換的核心是被稱為有窮自動機(finite automata) 的表示方法。 這些自動機在本質上是與狀態轉換圖類似的圖, 但有如下幾點不同:

1) 有窮自動機是識別器(recognizer) , 它們只能對每個可能的輸入串簡單地回答“是”或“否”。

2) 有窮自動機分為兩類:

① 不確定的有窮自動機( NFA)對其邊上的標號沒有任何限制。 一個符號標記離開同一狀態的多條邊,並且空串∈ 也可以作為標號。

② 對於每個狀態及自動機輸入字母表中的每個符號, 確定的有窮自動機(DFA) 有且只有一條離開該狀 態、 以該符號為標號的邊。 確定的和不確定的有窮自動機能識別的語言的集合是相同的。 事實上, 這些語言的集合正好是能夠用正則表示式描述的語言的集合。 這個集合中的語言稱為正則語言(regular language) [4]。

6.1 不確定的有窮自動機

一個不確定的有窮自動機(NFA) 由以下幾個部分組成: 1) 一個有窮的狀態集合S。

2) 一個輸入符號集合Σ, 即輸入字母表(input alphabet) 。 我們假設代表空串的∈ 不是Σ中的元素。

3) 一個轉換函式(transition function) , 它為每個狀態和Σ∪ {∈ }中的每個符號都給出了相應的後繼狀態(next state) 的集合

4) S中的一個狀態s0被指定為開始狀態, 或者說初始狀態。

5) S的一個子集F被指定為接受狀態( 或者說終止狀態的) 集合。

不管是NFA還是DFA, 我們都可以將它表示為一張轉換圖( transition graph) 。 圖中的結點是狀態, 帶有標號的邊表示自動機的轉換函式。

從狀態s到狀態t存在一條標號為a的邊當且僅當狀態t是狀態s在輸入a上的後繼狀態之一。 這個圖與狀態轉換圖十分相似, 但是:

① 同一個符號可以標記從同一狀態出發到達多個目標狀態的多條邊。

② 一條邊的標號不僅可以是輸入字母表中的符號, 也可以是空符號串∈

6.2 轉換表

我們也可以將一個NFA表示為一張轉換表(transition table) , 表的各行對應於狀態, 各列對應於輸入符號和∈ 。 對應於一個給定狀態和給定輸入的條目是將NFA的轉換函式應用於這些引數後得到的值。 如果轉換函式沒有給出對應於某個狀態-輸入對的資訊, 我們就把Ø放入相應的表項中

轉換表的優點是我們能夠很容易地確定和一個給定狀態和一個輸入符號相對應的轉換。 它的缺點是: 如果輸入字母表很大, 且大多數狀態在大多數輸入字元上沒有轉換的時候, 轉換表需要佔用大量空間

6.3 自動機中輸入字串的接受

一個NFA接受(accept) 輸入字串x, 當且僅當對應的轉換圖中存在一條從開始狀態到某個接受狀態的路徑, 使得該路徑中各條邊上的標號組成符號串x。 注意, 路徑中的∈ 標號將被忽略, 因為空串不會影響到根據路徑構建得到的符號串

6.4 確定的有窮自動機

確定的有窮自動機(簡稱DFA) 是不確定有窮自動機的一個特例,其中: 1) 沒有輸入∈ 之上的轉換動作。

2) 對每個狀態s和每個輸入符號a, 有且只有一條標號為a的邊離開s。

如果我們使用轉換表來表示一個DFA, 那麼表中的每個表項就是一個狀態。 因此, 我們可以不使用花括號, 直接寫出這個狀態, 因為花括號只是用來說明表項的內容是一個集合。 NFA抽象地表示了用來識別某個語言中的串的演算法, 而相應的DFA則是一個簡單具體的識別串的演算法。 在構造詞法分析器的時候, 我們真正實現或模擬的是DFA。

幸運的是, 每個正則表示式和每個DFA都可以被轉變成為一個接受相同語言的DFA。 下邊的演算法說明了如何將DFA用於串的識別。