lex初学总结(二)
III. Lex代码格式
这里以一个能分析类似C语言的lex程序源码+注释来说明。
%{//C 和 Lex 的全局声明,相当于C中的声明部分
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
%}//在这里定义RE表达式
keyword ("if"|"while"|"do"|"break"|"true"|"false"|"int"|"char"|"bool"|"real"|"float"|"switch"|"case")digit [0-9]
letter [a-zA-Z]
symbol [\+\-\*\/><=!;,(){}\[\]]
id {letter}+({letter}|{digit})*
number {digit}+(\.{digit}+)?(E[+\-]?{digit}+)?
comment (\/\*(((\*)*[^\*\/]+(\/)*)*|(\*)*|(\/)*)\*\/)
delim [ \t\n]
ws {delim}+
illegal [^{digit}{letter}{symbol}{delim}]%%
//在这里定义模式和匹配操作(注意这里的匹配是安先后顺序进行的,顺序不当也会导致逻辑错误)
{comment} {printf("comment: %s\n",yytext);}
{ws} {/*do nth*/}
{keyword} {printf("keyword: %s\n",yytext);}
{number} {printf("number: %s\n",yytext);}
{symbol} {printf("symbol: %s\n",yytext);}
{id} {printf("identifier: %s\n",yytext);}
{illegal} {printf("illegal letter\n");}%%
//在这里完成C语言程序的其他部分(可以放到其他文件中),包括yywrap()等函数的具体实现和main()函数等
int yywrap()
{
return 1;
}
int main()
{
extern FILE *yyin;
if((yyin = fopen ("test.txt","rt")) == NULL){
printf("open file error\n");
return 1;
}
if (yylex()==1){
fprintf(stderr," Analaysis error\n");
return 1;
}
}
总结起来如下:
%{
C与lex的声明部分
%}
RE定义部分
%%
模式匹配与动作
%%
其它C语言代码
IV. Lex 编译过程
*.l文件 —lex编译器—> lex.yy.c文件 —C编译器(正常C编译过程)—> 可执行文件
由于这个设计,我们完全可以将其他的C代码写在单独的文件里,在C编译过程中再统一编译并链接起来,这样可以方便代码的管理和重用。
一次典型的编译过程如下(采用flex):
user@local:exp_1$ flex exp_1.l
user@local:exp_1$ gcc lex.yy.c -o exp_1
user@local:exp_1$ ./exp_1
不过,每次执行这个步骤还是很麻烦的,所以一般采用make进行编译和管理。
其实lex很少单独使用,一般是和yacc配合使用。所以笔记就都到此为止。
20110329
天行健,君子以自强不息
地势坤,君子以厚德载物

浙公网安备 33010602011771号