flex
是用來生成程序的工具(最初用來生成編譯器),它所生成的程序能夠處理結構化輸入
。
基礎:瞭解正則表達式
和編譯原理
相關知識(詞法分析器、語法分析器、自動機等)。
一個簡單的Flex程序:
這個程序實現字數統計
功能,這個程序可以讀入一個文件,然後報告這個文件的行數
、單詞數
和字符數
。
$ vim WordCount.l
用vim創建文件拓展名爲l
或lt
的文件,輸入以下內容:
%{
int chars = 0;
int words = 0;
int lines = 0;
%}
%%
[a-zA-Z]+ { words++; chars += strlen(yytext); }
\n { chars++; lines++; }
. { chars++; }
%%
main(int argc, char **argv)
{
yylex();
printf("%8d%8d%8d\n", lines, words, chars);
}
flex程序包含三個部分,各部分之間通過僅有%%的行來分割,三個部分介紹如下:
(1)聲明部分
%{
和%}
之間的代碼會被原樣照抄到生成的C文件的開頭部分。
在這個例子中,它只是用來設定行數、單詞數和字符數的變量。
(2)規則部分
模式處在一行的開頭
處,接着是模式匹配
時所需要執行的C代碼
(這兒的C代碼是用{}
括住的一或多行語句。)
模式必須在行首
出現。(flex認爲空白開始的行都是代碼)
(3)C代碼部分
末尾的C代碼是我們的主程序,它負責調用flex提供的詞法分析例程yylex(),並輸出結果。
接下來將它編譯:
$ flex -o WordCount.yy.c WordCount.lt
$ cc -o WordCount WordCount.yy.c -lfl
-o
用於確定輸出文件,如果不加,flex默認生成lex.yy.c
,gcc默認生成a.out
-lfl
用於鏈接flex庫( flex library)
cc
命令其實就是gcc
,以後將全部寫爲gcc,可以證實如下:
$ ls -l /usr/bin/cc
lrwxrwxrwx 1 root root 3 11月 29 19:48 /usr/bin/cc -> gcc
執行的方式有許多(第一種直接輸入,後兩種將文件作爲標準輸入):
$ ./WordCount
Hello World~
Yeah
2 3 18
# 或者
$ ./WordCount < file
1 1 10
# 或者
$ cat file | ./WordCount
1 1 10
真正的wc(字符統計)程序與上述定義有所不同:沒有空白字符的字符串。
所以需略作修改:
[^\t\n\r\f\v ]+ { words++; chars += strlen(yytext); }