不了解Flex的同學(xué),可以先溫習(xí)一下上一節(jié)的內(nèi)容Flex和Bison背景介紹
字?jǐn)?shù)統(tǒng)計(jì)實(shí)例介紹
我們先通過一個(gè)例子來給大家介紹Flex的語法規(guī)則,這個(gè)例子的主要作用是統(tǒng)計(jì)我們輸入內(nèi)容的行數(shù),單詞數(shù)和字符數(shù),代碼示例如下:
%option noyywrap
%{
int chars = 0;
int words = 0;
int lines = 0;
%}
/*
1. 變量yytext總是被設(shè)為指向本次匹配的輸入文本
2. . 在正則表達(dá)式中代表任意一個(gè)字符
**/
%%
[a-zA-Z]+ { words++; chars += strlen(yytext); }
\n { chars++; lines++;}
. { chars++;}
%%
int main(int argc, char **argv)
{
yylex();
printf("%8d%8d%8d\n", lines, words, chars);
}
整個(gè)程序結(jié)構(gòu)包含三個(gè)部分,各部分通過%%來分割。
第一部分主要包含聲明和選項(xiàng)設(shè)置。在聲明部分%{和%}之間的代碼會(huì)直接拷貝到C文件的開頭部分,示例代碼中主要是聲明了三個(gè)整形變量,用來分別統(tǒng)計(jì)字符數(shù),單詞數(shù)和行數(shù)。
第二部分主要包含匹配模式和相應(yīng)的動(dòng)作。在示例代碼中第一條正則表達(dá)式[a-zA-Z]+主要用來匹配一個(gè)單詞,當(dāng)成功匹配到單詞后,會(huì)將變量word加1,同時(shí)將字符數(shù)加上單詞的長(zhǎng)度(strlen是C語言中獲取字符串長(zhǎng)度的庫函數(shù)),第二條\n匹配換行符,當(dāng)成功匹配后,行數(shù)加1,字符數(shù)也加1,最后一條.匹配的是除換行符 \n之外的任何單字符,匹配成功以后字符數(shù)加1。
第三部分則是直接拷貝到詞法分析器中的C代碼。在示例代碼中會(huì)將主函數(shù)拷貝到生成的C文件中,當(dāng)運(yùn)行程序時(shí),會(huì)首先調(diào)用main函數(shù),在其內(nèi)部負(fù)責(zé)調(diào)用Flex的yylex函數(shù)開始詞法分析,并打印出分析之后的結(jié)果,包括行數(shù),單詞數(shù),字符數(shù)。
編譯和運(yùn)行示例代碼
在Mac平臺(tái)下編譯示例如下:
% flex fb1_1.l
% gcc lex.yy.c -o fb1 -lm
如果是Window或者Linux下編譯,鏈接選項(xiàng)更改為-lfl,當(dāng)?shù)谝恍忻顖?zhí)行完以后當(dāng)前文件夾下應(yīng)該會(huì)生成一個(gè)lex.yy.c文件,有興趣的同學(xué)可以對(duì)照著上面的示例代碼比對(duì)一下,看一看Flex是如何處理我們的示例代碼的。當(dāng)?shù)诙忻顖?zhí)行完以后,當(dāng)前文件夾下應(yīng)該會(huì)生成一個(gè)fb1可執(zhí)行文件,然后執(zhí)行當(dāng)前文件,輸入測(cè)試代碼,按Control+D后會(huì)顯示出統(tǒng)計(jì)的行數(shù),單詞數(shù)和字符數(shù)
% ./fb1
Hello World
1 2 12
通過上面的示例代碼,大家應(yīng)該可以深刻的體會(huì)到,要想編寫好Flex程序,首先要熟悉正則表達(dá)式。
本節(jié)的內(nèi)容就先到這里,謝謝大家~