Flex學習筆記 1 生成簡易的詞法分析程式

2021-10-01 04:16:29 字數 3126 閱讀 5147

flex是重寫lex誕生的快速詞法分析生成器,在編譯前端(詞法分析->語法分析->語義分析)中處在最靠前的位置,它可以用來生成特定的詞法分析程式。

安裝flex:

apt-get install flex
沒有專用於flex的ide,可以在vscode安裝lex flex yacc bison外掛程式,可以讓flex語法高亮。

flex程式通常寫成.l檔案,其中由兩個%%分成上中下三部分,第一部分是宣告和選項設定(編譯後被原樣寫入生成的詞法分析程式最頂端),第二部分是正規表示式模式和相應action,第三部分主程式中是一些與action相關的例程(也會被照抄)。

第一部分如果不需要就不用寫。第三部分如果不寫,flex會提供乙個最小的呼叫詞法分析器的主程式。

核心就在第二部分,因為乙個正規表示式可以對應乙個有限自動機,flex就是將正規表示式翻譯成dfa,然後在dfa轉移時執行相應的action完成處理。

如課本上的統計行數、單詞數、字元數的flex程式:

%%%

//分割第一部分和第二部分

[^ \t\n\r\f\v]

+//匹配到單詞(沒有空白符的連續串)時,單詞數+1,字元數+=單詞長度

\n

//匹配到換行符時,字元數+1,行數+1

.//匹配到其它任何字元,只增加字元數%%

//分割第二部分和第三部分

//主函式

intmain

(int argc,

char

**ar**)

使用flex命令對其翻譯:

flex wordcount.l
在同一目錄下生成了近1800的c語言程式lex.yy.c,這就是flex生成的程式,只不過這個例子不是詞法分析目的。將這個程式用gcc(或者unix的cc)編譯:

gcc lex.yy.c -lfl
其中-lfl引數用於鏈結flex的庫函式。編譯後在目錄下生成了a.out,直接執行就可以使用這個程式了,輸入可換行的文字並最終ctrl+d(這是unix/linux下的換行符)結束輸入:

lzh@desktop-hcsig2e:/mnt/e/compiler/flex$ ./a.out

i am sb lzh.

i like cute cat, and i wanna eat foods.

that's all, bye!

3 16 70

這表示,輸入的文字有3行,16個單詞("that』s"整個視為乙個單詞),70個字元。

這裡按照課本上的案例,做乙個整數的四則運算器。

flex在這裡生成詞法分析程式,詞法分析程式會識別輸入的單詞,然後將分析結果輸出。

%

%"+"

"-""*"

"/""|"[0

-9]+

//數字

\n

[ \t]

//忽略空白符

.//其它字元是不合法的,提示錯誤

%%

翻譯,編譯,執行:

lzh@desktop-hcsig2e:/mnt/e/compiler/flex$ ./a.out

2019+11-30/2

number 2019

plus

number 11

minus

number 30

divide

number 2

newline

77 + 8 8 | abc

number 77

plus

number 8

number 8

absmystery charactor a

mystery charactor b

mystery charactor c

newline

一般為模式匹配的action中設定返回值(而不是像前面那樣直接print),這樣yylex()每次識別到相應的模式,如果有返回值,就立即返回,然後繼續呼叫yylex()識別下乙個模式;如果是沒有返回值的模式,就會繼續向後識別。

另外,還可以設定記號編號記號值。記號編號用於記錄詞的類別,而記號的值則用於記錄此類別的某個具體值。例如記號編號可以是number,然後記號值取10,就表示了整型常量10。

bison建立的語法分析器自動從258開始指派記號編號,這是為了防止和文字字元衝突。flex裡為了和bison統一,也不妨從258開始編號。

記號的值為了能給不同的型別使用,通常使用union型別。不過這個例子裡因為只有數字需要有記號值,所以直接就用int型別。

%

;//儲存記號值

int yylval;%}

%%"+""-"

"*""/"

"|"[0-

9]+//匹配到數字時,將其轉為int寫入記號值的變數中

\n

[ \t]

//忽略空白符

.//其它字元是不合法的,提示錯誤%%

intmain

(int argc,

char

**ar**)

return0;

}

翻譯,編譯,執行:

lzh@desktop-hcsig2e:/mnt/e/compiler/flex$ ./a.out

2019+11-30/2

258 = 2019

259258 = 11

260258 = 30

262258 = 2

264

NLP學習筆記15 生成句子

本文屬於nlp學習筆記系列。當乙個模型訓練好後,我們可以利用這個模型來生成一些資料,就是生成模型。例如 生成句子,影象,程式等。當然還有判別模型。語言模型屬於生成模型,所以可以生成句子。下面的例子,假如有個詞庫,然後每乙個詞對應的概率已經訓練好了,然後用unigram來生成乙個句子 由於unigra...

Docker學習筆記3 生成映象

通過編寫dockerfile檔案,我們可以利用docker來製作自己的映象檔案。命令格式如下 docker build t 映象名 dockerfile檔案所在資料夾路徑 t表明後面引數是映象的映象名。執行完該命令就根據dockerfile中的配置生成了我們需要的映象檔案。dockerfile詳解 ...

7 2 1 生成1 n的排列

問題描述 嘗試用遞迴的方法 先輸出所有以1開頭的排列,然後輸出以2開頭的排列,一直到輸出完以9開頭的排列。偽 void print permutation 序列 a,集合 s 由於集合s可以用序列a表示出來 遍歷1 n的所有數,只要a中沒有出現的元素即可使用,因此可以不使用s儲存剩餘元素的集合。由於...