Lex的簡單入門和正則表示式基礎
編譯原理上機課任務如下:
=================================================這是分割線=========================================================
flex 是- fast lexical analyzer generator 的簡稱,一個詞法分析器生成工具。
下述檔案已經儲存到我的百度雲
(一) 目錄介紹
在本實驗目錄中,包括兩個子目錄。
1、子目錄 flex
它包含了 flex.exe, flex.hlp, libfl.lib 三個檔案,另外還有一個例子檔案 example.l 及該例子生成的 lex.yy.c。
2、子目錄 lex_yy
這個目錄是為 lex.yy.c 建立的一個專案(使用 VC6)。它包含有 lex.yy.c, libfl.lib (拷貝自目錄 flex),以及相關的專案檔案。在debug 子目錄中是已經生成的 詞法分析器 lex.yy.exe, 利用它可以進行詞法分析。
(二)實驗示範
1、編寫 lex 程式,如 example.l 檔案所示
2、呼叫 flex 以生成 lex.yy.c, DOS命令格式: flex < example.l
3、新建一個目錄(如 lex_yy), 把lex.yy.c 及 libfl.lib 拷貝到該目錄下。
4、用VC6開啟lex.yy.c,並生成一個新專案。
5、編譯並連結libfl.lib, 得到詞法分析器 debug/ley.yy.exe。
6、驗證詞法分析器的功能:
1)編寫一輸入檔案(如lex_yy/debug/12.txt)
2) 呼叫 lex.yy.exe(DOS 命令格式 lex.yy.exe < 12.txt )
3) 觀察輸出結果是否與預想的相符。
(三)實驗要求
1、編寫一個詞法分析器,它針對輸入檔案,實現以下功能:
1)每遇到你的學號,就輸出你的名字,對於其他的串原樣輸出。
2)統計輸入檔案中單詞的數目、字元的數目。
例如:(以肖永躍的上機題為例):
輸入檔案如下所示:
200213001 hello world
wo ai tian an men
hello world i love
200213001
輸出應該如下所示:
肖永欽 hello world
wo ai tian an men
hello world i love
肖永欽
# of ids = 11, # of chars = 66
=================================================這是分割線=========================================================
下面講一下實驗中學習到的小技巧:
CMD視窗是可以直接拖檔案進去的,還有cd等命令都可以使用
XP下不能shift+右鍵,就出現在此開啟命令列視窗,所以想找到目錄可以試試cd命令,用法和linux下是一樣的。
當然,這樣還是有點麻煩,如果你需要打 flex < example.l 這樣的命令的話。因為你要先進到目錄下再打一行命令。
我們可以這樣操作來完成 flex < example.l 命令的輸入:
1、點住檔案“flex.exe”拖進cmd窗口裡鬆手
2、打一個“<”
3、點住檔案“example.l”拖進cmd窗口裡鬆手
這時顯示如下:
看~~一樣的吧,而且還是絕對路徑,前面都不用cd命令進子目錄了
=================================================這是分割線=========================================================
接下來講一下實驗中用到的程式碼:
首先介紹一下flex:點選開啟連結(這篇文章稍後將轉載到我的部落格)
那麼來分析一下這次上機實驗的程式碼:
//定義部分
int num_words = 0, num_chars = 0;
space [\t\n]
blank {space}+
letter [(A-Z)(a-z)]
digit [0-9]
word ({letter}|{digit})+
//規則部分
%%
//模式必須頂頭寫 模式的格式為正則式或者{}括起來的已經定義好的巨集
//空白後接C語言語句,表示識別後的相應動作
201392326 {printf("我");num_chars+=9;}
{blank} {printf("%s",yytext);}
{word} {num_words++;num_chars+=yyleng;printf(" #%d# ",num_words);}
//使用者附加C語言部分
%%
int main()
{
yylex();
printf("\n#number of words = %d, #number of chars = %d\n ", num_words, num_chars);
return 0;
}
下面著重介紹一下實驗中帶來困惑的地方:
※正則表示式裡括號的使用方法和區別!
():小括號起到分組功能,也就是和數學裡意義相同,用於把一部分括在一起。
【】:中括號表示括號中的某一個,例如程式碼中的【0-9】表示0~9中的任一數字,【ABC】表示A或B或C
{ }:花括號表示重複若干次,例如“A{3}”即“AAA”,“AAB{2}”即“AABB”,表示最近處的單元重複若干次,在FLEX分析時也表示引用巨集(貌似不加也可以,但保險起見建議新增)。
回頭看一個複雜的例子: AC【DF】(AB){2}
等價於:AC D|F ABAB
關於括號實驗時有不少問題,好心的學長十分有耐心,還推薦了一個好東西
正則表示式30分鐘入門教程:點選開啟連結
這是一部非常好非常好的正則表示式教程,值得深入學習!
其中電話號碼的例子可以幫助理解括號君~