參考:
詞法分析器生成工具flex
詞法分析器總結--flex&bison
詞法分析生成器flex的選項
1. Flex的一些常見選項:
%option 7bit
,%option 8bit
:指示flex生成一個7bit或8bit的掃描器與-7,-8 選項等價。
%option caseful
,%option case-sensitive
:區分大小寫,與-i相反。
%option case-insensitive
,%option caseless
:忽略大小寫,與-i選項等價。
%option debug
:讓生成的掃描器運行在debug模式,與-d選項等價。
%option yylineno
:flex 生成的掃描器用全局變量yylineno 維護着輸入文件的當前行編號。option lex-compat隱含有這個選項。
%option interactive
:指示flex生成一個交互式的掃描器。交互式掃描器就是向前查看下一個匹配的token是什麼。結果就是總向前多看了一個字符,即使是在掃描器已經看夠了文本已經排除了token 的歧義。但向前查看給了掃描器強大的交互能力。與-I等價。
%option yylineno
:記錄符號所在行號。如果使用了%option lex-compat
,則隱含地使用了該選項。
%option yywrap
:如果沒有設置(就如%option noyywrap
),當掃描器遇到end-of-file 時,不會調用yywrap(),但簡單的假定沒有更多的文件可以掃描(直到用戶把yyin 指向新的文件並再一次調用yylex())。
%option bison-bridge
:生成的掃描器API能夠被bision調用。API爲與bision兼容而作了些小改變。
%option reentrant
:生成可重用的掃描器API,這些API用於多線程環境。
%option c++
:如果沒有指定該選項,生成的掃描器.c文件是C語言格式的,指定後則生成C++文件。
%option array
:yytext的類型由char *變爲數組。
%option pointer
:與--array, %option array相反。
2. 一些常用全局變量和宏
(1) FILE
\*yyin
,\*yyout
:爲指向字符輸入和結果輸出文件的指針。如用戶未對其定義,則設爲標準輸入文件stdin
和stdout
。
(2)int yylex()
:爲詞法分析程序,它自動移動文件指針yyin和yyout
。在定義模式動作時,用戶可用return語句結束yylex()
,return 必須返回一整數。由於yylex()的運行環境都是以全局變量
的方式保存,因此,在下一次調用yylex()時,yylex()可從上次掃描的斷點處繼續 掃描,在語法分析時,可利用這一特性。若用戶未定義相應的return語句,則yylex()繼續分析被掃描的文件,直到碰到文件結束標誌EOF
。在讀到 EOF時,yylex()調用int yywrap()
函數(該函數用戶必須提供),若該函數返回非0值,則yylex()返回0而結束。否則,yylex()
繼續對yyin
指向的文件掃描。
(3) char *yytext
:存放當前被識別的詞形
。
(4) int yyleng
:存放字符串yytext的長度
。
(5)int yywrap()
:參見(2)
(6) yymore()
:將當前識別的詞形保留在yytext中,分析器下次掃描時的詞形將加追加在yytext中。例模式定義如下
……
hello {printf(“%s!”,yytext);yymore();}
world {printf(“%s!”,yytext);}
……
當輸入串爲”helloworld”時,將輸出”hello!helloworld!”
(7) yyless(int n)
:回退當前識別的詞形中n個字符到輸入中
(8) unput(char c)
:回退字符c到輸入,它將作爲下一次掃描的開始字符
(9) input()
:讓分析器從輸入緩衝區
中讀取當前字符,並將yyin
指向下一字符
(10) yyterminate()
:中斷對當前文件的分析,將yyin指向EOF。
(11) yyrestart(FILE * file)
:重新設置分析器的掃描文件爲file
(12) ECHO
:將當前識別的字符串拷貝到yyout
(13) BEGIN
:激活開始條件對應的模式
(14) REJECT
:放棄當前匹配的字符串和當前的模式,讓分析器重新掃描當前的字符串,並選擇另一個最佳的模式再次進行匹配。
3. 條件模式
LEX提供控制模式在一定狀態下使用的功能,稱爲條件模式。LEX首先在定義部份通過%start
來定義條件句。在規則部份可通過宏
BEGIN 條件名
來激活條件。BEGIN INITIAL
或BEGIN 0
將休眠所有的條件模式,使分析器回到開始狀態。
例:將輸入文件中的單詞”magic” 作如下處理:識別”magic”時,如”magic”所在行行首爲字符’a’,則輸出”first”;若爲’b’,則輸出”second”;否則,輸出”magic”。如不用條件模式,LEX源文件可這樣寫:
%{int flag;}%
%%
^a {flag=’a’;ECHO;}
^b {flag=’b’;ECHO;}
/n {flag=0;ECHO;}
magic {
switch(flag)
{
case ‘a’:printf(“first”);break;
case ‘b’:printf(“second”);break;
default :ECHO;break;
}
}
%%
如使用條件模式,則上述源文件可簡化爲
%start AA BB CC
%%
^a {ECHO;BEGIN AA;}
^b {ECHO;BEGIN BB;}
/n {ECHO;BEGIN 0;}
<AA>magic {printf(“first”);}
<BB>magic {printf(“second”);}
%%