了解flex程序(flex自动构造词法分析)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pfl_327/article/details/83148604

找寻flex程序的方向

  1. flex
    什么是flex?
    flex是指 fast lexical analyzer generator,快速词法分析器生成器,也就是说,flex用于产生词法分析器;
    flex的输入是文件或输入设备,这些输入中的信息以正则表达式和C代码的形式组成,这些形式被称为规则(rule);
    flex的默认输出是C语言的源码文件:lex.yy.c,也可以重命名;该文件通过编译生成可执行的文件;
    当可执行文件被执行时,其分析输入中可能存在的符合规则的内容,当找到任何一个正则表达式相匹配内容时,相应的C代码将被执行;
    当然中间匹配的过程很复杂,比如匹配正则表达式,并输出;使用LEX就不需要考虑这些,我们只需要定义以下几点:
    (1)正则表达式,怎么样才算匹配,比如我们定义的语言中INTEGER才是整数,则输入 为INTEGER时匹配正则表达式;
    (2)返回的词法单元,当匹配时要返回什么需要自己定义;

  2. flex的输入文件由3段组成,用一行中只有%%来分隔;

定义:definition
%%
规则:rules
%%
用户代码:code

①.定义部分
其中定义有变量声明,正则表达式声明;
变量声明有两种:
例1:

%{
int a;
int b;
%}

例2:

int a;
    int b;

需要有tab键缩进;

正则表达式声明方式:
表达式名称 表达式
在使用时需要将表达式名称用{}括起来;
②.规则部分
一个规则一行,每行有两部分构成:
正则表达式 {动作函数}
动作函数可以调用在用户代码中定义的函数;

  1. 举个例子可能更明显吧!
    例:
%option main
%{
    int line=1;
%}
DIGIT [0-9]
OINTEGER [1-9]{DIGIT}*
INTEGER ("+"|"-")?{OINTEGER}
DECIMAL {INTEGER}(.{OINTEGER})?
LETTER [a-zA-Z]
ID ({LETTER}|_)({LETTER}|_|{DIGIT})*
OPT ("+="|"-="|"*="|"/="|"+"|"-"|"*"|"/"|"<="|">="|"=="|"=")
%%
\n {++line;}
(int|float|double|short) {printf("line%d:(type,%s)\n",line,yytext);}
for {printf("line%d:(for,)\n",line);}
{INTEGER} {printf("line%d:(integer,%s)\n",line,yytext);}
{DECIMAL} {printf("line%d:(decimal,%s)\n",line,yytext);}
{ID} {printf("line%d:(identify,%s)\n",line,yytext);}
("("|")"|"{"|"}"|"["|"]") {printf("line%d:(bracket,\"%s\")\n",line,yytext);}
"\"" {printf("line%d:(QUOTE,)\n",line);}
{OPT} {printf("line%d:(OPT,%s)\n",line,yytext);}

. {}
%%
/*辅助过程部分*/

代码说明:
%{ int line=1; %}
:全局变量的说明,需要用“%{”和“%}”括起来;
DIGIT [0-9]
:类似于C语言中的宏定义,翻译规则中的{DIGIT}将被“[0-9]”所替换;”[0-9]”是一个正则表达式,表示字符’0’、’1’、…、’8’、’9’中的任意一个;
INTEGER ("+"|"-")?{OINTEGER}
:+号需要用引号括起来,因为正则表达式也有+号;同理,-号也需要括起来;
"\"" {printf("line%d:(QUOTE,)\n",line);}
:引号需要有反斜杠进行转义;

  1. 注意点:
    正规定义中[xy]等价于(x|y)
    定义部分一些在翻译规则中使用的变量的声明,需要由%{和%}包围起来,这部分声明将被直接抄写在lex.yy.c中,不作为正规定义和翻译规则的一部分;
    如果变量的声明不在%{和%}之间,那么需要在声明部分进行缩进(使用tab缩进);
    辅助过程是一些函数,能够被抄入到生成的c文件中,在规则后面的动作中可以调用;
    规则后面的动作可以通过return返回词法单元的记号;在动作、辅助过程中可以使用变量yylval、yytext、yyleng,这些变量为全局变量,通过yylval传送记号属性给语法分析器,yytext为解析出的词法单元字符串的指针,yyleng为词法单元字符串长度;
    若两个表达式同时匹配一个词法单元,如表达式if和[a-z]+同时匹配if\s,(注意\s表示空格),那么按照两个表达式在翻译规则中的顺序选择动作;而表达式<和<=匹配<=\s时,<可以匹配1个单词,<=可以匹配两个单词,那么选择匹配元素多的<=;

猜你喜欢

转载自blog.csdn.net/pfl_327/article/details/83148604