编译器和汇编器在工作过程中,往往完成如下的任务:
(1) 读取源代码并且获得程序的结构描述;
(2) 分析程序结构,并且生成相应的目标代码。
Flex和Bison就是为可以帮助完成以上任务。Flex将源代码文件分解为各种词汇(token),Bison找到这些词汇的组成方式。下面通过例子讲述它们的使用方法,在Cygwin环境下调试。
1. Flex
Flex是一个生成扫描器(scanner)的工具,生成的扫描器能够识别文本中的词法模式(lexical pattern)。Flex接受文本格式的Flex文件(扩展名可以为.l,.flx、.lex或者.flex)作为输入,生成一个c源文件:lex.yy.c,其中定义了一个函数yylex(),该函数就是扫描器。它根据Flex文件中定义的模式(pattern)对输入的文本串进行分析,然后执行对应的动作(Action),该模式和对应的动作叫做规则。例如,可以定义一个模式识别自定义标识符,并在对应的动作中规定,如果遇到自定义标识符,将该标识符写入某个数组。另外,lex.yy.c可以编译后执行,也可以被其他源文件中的函数调用。
下面看一个简单的例子(example1.lex):
int num_lines = 0, num_chars = 0;
%option noyywrap
%%
\n ++num_lines; ++num_chars;
. ++num_chars;
%%
int main()
{
yylex();
printf( "# of lines = %d, # of chars = %d\n",num_lines, num_chars );
return 0;
}
在cygwin下,键入如下命令:
$flex example1.lex //该命令生成lex.yy.c文件
$gcc -g -Wall -o scan.exe lex.yy.c //该命令生成可执行文件scan.exe
$./scan 回车
键入几行字符,以Ctrl+D结束。扫描程序scan.exe扫描键入的字符串,识别的根据模式执行动作,不识别的直接输出。本例中遇到换行符'\n'变量num_lines和num_chars加1,遇到字符num_chars加1,最后输出结果: