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

posted @ 2011-03-29 23:51  Jesse_Luo  阅读(717)  评论(0)    收藏  举报