詞法分析工具flex的安裝及使用(Ubuntu)

一、Ubuntu安裝flex

在ubutu上安裝 yacc的命令:

sudo apt-get install flex bison

  • yacc(Yet Another Compiler Compiler)
    yacc是一個(gè)經(jīng)典的生成語法分析器的工具。yacc生成的編譯器主要是用C語言寫成的語法解析器(Parser),需要與詞法解析器Lex一起使用,再把兩部份產(chǎn)生出來的C程序一并編譯。

  • flex:詞法分析器
    flex是一個(gè)詞法分析器。用來將一個(gè).l文件生成一個(gè).c程序文件。即生成一個(gè)詞法分析器。然后讀取輸入,和正則表達(dá)式匹配,再執(zhí)行相應(yīng)的動(dòng)作,實(shí)現(xiàn)了程序的功能。我們可以發(fā)現(xiàn)flex實(shí)現(xiàn)在程序外部就可以接受輸入的功能。

    Flex是一個(gè)生成掃描器的工具,能夠識(shí)別文本中的詞法模式。Flex 讀入給定的輸入文件,如果沒有給定文件名的話,則從標(biāo)準(zhǔn)輸入讀取,從而獲得一個(gè)關(guān)于需要生成的掃描器的描述。此描述叫做規(guī)則,由正則表達(dá)式和 C代碼對(duì)組成。Flex 的輸出是一個(gè) C 代碼文件——lex.yy.c——其中定義了yylex() 函數(shù)。編譯輸出文件可以生成一個(gè)可執(zhí)行文件。當(dāng)運(yùn)行可執(zhí)行文件的時(shí)候,它分析輸入文件,為每一個(gè)正則表達(dá)式尋找匹配。當(dāng)發(fā)現(xiàn)一個(gè)匹配時(shí),它執(zhí)行與此正則表達(dá)式相關(guān)的C代碼。Flex 不是GNU工程,但是GNU為Flex 寫了手冊(cè)。

二、flex使用示例:實(shí)現(xiàn)Ubuntu中wc的功能

    1. article.txt文件的內(nèi)容如下,wc的功能就是統(tǒng)計(jì)該文件中的行數(shù)、單詞及字符個(gè)數(shù)。

      wc統(tǒng)計(jì)結(jié)果
    1. 編寫countNum.l程序如下
%{
#define T_WORD 1
int numChars = 0, numWords = 0, numLines = 0;    //初始化字符、單詞、行數(shù)
%}


WORD            ([^ \t\n\r\a]+)   //匹配單詞

%%
\n              { numLines++; numChars++; }    //匹配換行
{WORD}          { numWords++; numChars += yyleng; return  
 T_WORD; }
<<EOF>>         { return 0; }   // 文件結(jié)束
.               { numChars++; }   //其他字符
%%

int main() {
        int token_type;
        while (token_type = yylex()) {
                printf("WORD:\t%s\n", yytext);
        }
        printf("\nChars\tWords\tLines\n");
        printf("%d\t%d\t%d\n", numChars, numWords, numLines);
        return 0;
}

int yywrap() {
        return 1;
}
  • 3 執(zhí)行flex countNum命令,生成一個(gè)lex.yy.c文件
  • 4 執(zhí)行g++ lex.yy.c countNum對(duì)lex.yy.c文件進(jìn)行編譯,生成countNum可執(zhí)行程序
  • 5 運(yùn)行./countNum < article.txt,把a(bǔ)rticle.txt輸入到countNum中,打印統(tǒng)計(jì)結(jié)果
    統(tǒng)計(jì)結(jié)果

三、flex解析

yylex()是由flex創(chuàng)建的掃描程序的入口點(diǎn),調(diào)用yylex()啟動(dòng)或者重新開始掃描。Lex編寫的yylex()從名為yyin的FILE *文件指針中讀取字符。 如果未設(shè)置yyin,則默認(rèn)為標(biāo)準(zhǔn)輸入。 它輸出到y(tǒng)yout,如果未設(shè)置默認(rèn)為stdout。 還可以在yywrap()函數(shù)中修改yyin,該函數(shù)在文件末尾調(diào)用。 它允許打開另一個(gè)文件,并繼續(xù)解析。如果是這種情況,將其返回0。如果要結(jié)束此文件的解析,將其返回1。一般來說,每次調(diào)用yylex()都會(huì)返回一個(gè)表示標(biāo)記類型的整數(shù)值。

flex的結(jié)構(gòu)如下:

%{ /*declaration*/ %}
/* Definition */
%%
/* Rules */
%%
/* C Code */

一個(gè)*.l的文件里的結(jié)構(gòu)大概如上,用%%分隔開來。分為三個(gè)區(qū):

  • 定義區(qū):包含一些簡(jiǎn)單的名字定義(name definitions)來簡(jiǎn)化詞法掃描器(scanner)的規(guī)則,并且還有起始條件(start condition)的定義。(上個(gè)例子比較簡(jiǎn)單,并未涉及定義區(qū))
  • 規(guī)則區(qū):包含了一系列具有pattern-action形式的規(guī)則,并且模式 pattern 位于行首不能縮進(jìn),action 也應(yīng)該起始于同一行。(上例使用正則表達(dá)式給出)
  • 用戶代碼區(qū):代碼將被原封不動(dòng)地拷貝到輸出文件中,并且這些代碼通常會(huì)被掃描器調(diào)用,當(dāng)然,該區(qū)是可選的,如果 Flex 源文件中不存在該區(qū),那么可以省略第二個(gè) " %%" 。

使用諸如Flex的詞法生成器的好處是使得程序員可以集中考慮詞法的特點(diǎn);而不是具體如何實(shí)現(xiàn)詞法分析。

參考:https://zhuanlan.zhihu.com/p/65490271

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容