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儲存剩餘元素的集合。由於...