编译原理——词法分析(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就有可能得到一個狀態集。(這個用轉換表來看會特別明顯!)
總結
以上是生活随笔為你收集整理的编译原理——词法分析(3)有穷自动机中DFA与NFA的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RISC-V应用于高性能处理器的可能性
- 下一篇: Unity打包Android项目报错