三. Flex进阶:需要了解的一些知识

2019-02-16  本文已影响9人  Dakini_Wind

参考:
词法分析器生成工具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”);}
%%
上一篇下一篇

猜你喜欢

热点阅读