一,詞法分析器的作用
詞法分析是編譯的第一階段。詞法分析器主要任務是讀入源程序的輸入字符、將他們組成詞素,生成並輸出一個詞法單元序列,每個詞法單元對應於一個詞素。
分析部分:詞法分析、語法分析(簡化編譯器設計、提高編譯器效率、增強編譯器可移植性)
1)詞法單元:詞法單元名和可選的屬性值組成。關鍵字、操作符……
2)模式:詞法單元詞素可能具有的形式,當詞法單元是關鍵字時,模式就是這個關鍵字的字符序列
3)詞素:源程序中的一個字符序列,它和某個詞法單元模式匹配。
4)詞法錯誤:識別出某個錯誤詞素,繼續判斷下一個詞素
二,輸入緩沖
1)我們至少向前看一個字符,才能判斷當前詞素是否到頭。
2)對付大型源程序,需要處理大量字符。處理往往需要很多時間,我們采用兩個交替讀入的緩沖區。(詳見73)
三,詞法單元的規約
1)我們會不會用完緩沖區?通常對於比較長的字符串我們采用 ”+“的形式鏈接起來。
2)正則表達式:letter_(letter_ | digit) * 表示字母開頭 0個或多個 字母或數字
3)正則表達式例子
a | b {a, b}
(a | b) (a | b ) {aa, ab, ba, bb}
aa | ab | ba | bb {aa, ab, ba, bb}
a* 由字母a構成的所有串集
(a | b)* 由a和b構成的所有串集
復雜的例子
( 00 | 11 | ( (01 | 10) (00 | 11) * (01 | 10) ) ) * 01001101000010000010111001
3)正則表達式擴展
1>一個或多個實例 一元后綴算符“+”的意思是“一個或多個實例”,即正規式a+表示一個或多個a的所有串的集合。算符+和算符*有同樣的優先級和結合性。代數恆等式 r* = r+ | 和r+ = rr*表達了這兩個算符之間的關系。
2>零個或一個實例 一元后綴算符?的意思是“零個或一個實例”,r?是r | 的縮寫。如果r是正規式,那么(r)?是表示語言L(r)∪{ }的正規式。使用這兩種縮寫,可以用num digit+ (.digit+)? (E (+ | )? digit+)?來描述無符號數。
3>字符組 [abc](其中a、b和c是字母表的符號)表示正規式a | b | c。縮寫字符組[az]表示正規式a | b | … | z。使用字符組,可以用正規式[AZaz][AZaz09] *描述標識符。
四,詞法單元的識別
某些狀態為接受狀態或最終狀態,表明已經找到一個詞素。
1)關系符轉換圖
2)保留字和標識符轉換圖
3)無符號樹轉換圖
4)空白轉換圖
五,詞法分析器生成工具 Lex
1)Lex 是Unix環境下非常著名的工具,主要功能是生成一個詞法分析器(scanner)的C源碼,描述規則采用正則表達式(regular expression)。描述詞法分析器的文件*.l,經過lex編譯后,生成一個lex.yy.c 的文件,然后由C編譯器編譯生成一個詞法分析器。詞法分析器,簡單來說,其任務就是將輸入的各種符號,轉化成相應的標識符(token),轉化后的標識符 很容易被后續階段處理
2)用Lex穿件一個詞法分析器
3)Lex沖突解決
總是選擇最長的前綴,如果最長前綴跟多個模式匹配,總是選擇在Lex程序中先唄列出的模式
六,有窮自動機
1)有窮自動機可用作描述在輸入串中識別模式的過程,因此也能用作構造掃描程序。當然有窮自動機與正則表達式之間有着很密切的關系
2)有限自動機分成確定的和不確定的兩種情況。“不確定”(Nondeterministic Finite Automata ,NFA)的含義是,存在這樣的狀態,對於某個輸入符號,它存在不只一種轉換。 確定的和不確定的有限自動機都正好能識別正規集,也就是它們能識別的語言正好是正規式所能表達的語言。
3)NFA組成
4)轉換表
5)從正則表達式r=(a|b) * abb 到NFA