1. 程式人生 > >Lex的簡單入門和正則表示式基礎

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分鐘入門教程:點選開啟連結

這是一部非常好非常好的正則表示式教程,值得深入學習!

其中電話號碼的例子可以幫助理解括號君~