編譯原理——詞法分析(3)有窮自動機中DFA與NFA的理解

 

1.1詞法分析器生成工具Lex

雖然在學習上,我們學習的是Lex,但是最近經常使用的是詞法分析器生成工具是Flex,它可以爲C語言生成代碼,Vern Paxson於1987年以C語言寫作了Flex,他引用了Jef Poskanzer爲Ratfor寫作的詞法分析器。如果我們想爲Java生成代碼,可以使用JFlex。

在Flex中,它支持使用正則表達式來描述各個詞法單元的模式,由此給出一個詞法分析器的規約。Lex工具的輸入表示方法稱爲Lex語言,而工具本身則稱爲Lex編譯器。在它的核心部分,Lex編譯器將輸入的模式轉換成一個狀態轉換圖,並生成相應的實現代碼,並存放到文件lex.yy.c中。

1.2 Lex的使用流程

       (1)用Lex語言寫出一個輸入文件,描述將要生成的詞法分析器,下圖的lex.l爲輸入文件。

       (2)Lex編譯器將lex.l轉換成C語言程序,存放該程序文件的文件名總是lex.yy.c。

       (3)文件lex.yy.c總是被C編譯器編譯爲一個名爲a.out的文件

       其他:C編譯器的輸出就是一個讀取輸入字符流並聲成詞法單元流的可運行的詞法分析器。

編譯後的C程序,在下圖中被稱爲a.out,通常是一個被語法分析器調用的子例程,這個子例程返回一個整數值,即可能出現的某個詞法單元名的編碼。而詞法單元的屬性值,不管它是一個數字編碼,還是一個只想符號表的指針,或者什麼都沒有,都保存在全局變量yylval中。這個變量有詞法分析器和語法分析器共享。這麼做可以同時返回一個詞法單元名和一個屬性值。

詞法分析器的輸入是源程序的字符流

2.1有窮自動機

有窮自動機是識別器,它們只能對每個可能的輸入串簡單地回答”是”或”否”。分爲兩類:第一類是不確定的有窮自動機(NFA),它對其邊上的標號沒有任何限制,一個符號標記離開同一狀態的多條邊,並且空串也可以作爲標號。第二類是確定的有窮自動機,對於每個狀態及自動輸入字母表中的每個符號,它都有且只有一條離開該狀態、以該符號爲標號的邊。

2.1.1 不確定的有窮自動機(有多條路徑)

       由五個部分組成:(1)一個有窮的狀態集合S (2)一個輸入符號集合Σ,即輸入字母表。空串不是Σ中的元素。(3)一個轉換函數,爲每個狀態和Σ∪{∈}中的每個符號都給出了相應的後繼狀態的集合。(4)初始狀態。(5)S的一個子集F被指定爲接受狀態的集合。

2.1.2 確定的有窮自動機(僅有一條路徑)

       是不確定有窮自動機的一個特例,其中不同在:(1)沒有輸入∈之上的轉換動作。(2)對每個狀態s和每個輸入符號a,有且僅有一條標號爲a的邊離開s。

NFA抽象地表示了用來識別某個語言中的串地算法,而相應地DFA則是一個簡單具體地識別串地算法。

3. 通過查了一些資料,以下是自己對DFA和NFA區別的一些理解(如有錯誤或補充望指出,一起學習呀~):

(1)左邊一個可以認爲用DFA來表示空串,右邊一個也能表示空串,是NFA,但是不是DFA。

(2)對於DFA,一個特定的符號輸入,有且只能得到一個狀態,而NFA就有可能得到一個狀態集。(這個用轉換表來看會特別明顯!)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章