(三)Flex進階:需要了解的一些知識

參考:
詞法分析器生成工具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:爲指向字符輸入和結果輸出文件的指針。如用戶未對其定義,則設爲標準輸入文件stdinstdout
(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 INITIALBEGIN 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”);}
%%
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章