lex的使用

来源:互联网 发布:大魔术师软件下载 编辑:程序博客网 时间:2024/05/16 14:10

首先了解一下lex:

一、lex的书写规则

 

<definitions>

 

 %%

 

 <rules>

 

 %%

 

 <user_code>

 

 

1Definition部分

 

1Definition部分用来引入一些头文件或一些词法分析过程中用到的函数。他们将直接的拷贝到输出文件中。这部分内容放到%{%}之间。

 

2Definition还可以用来定义一些词法分析器用到的宏。这部分内容要放到%{ 。。。。%}的下面。

 

 

 

2)规则部分

 

"if"     {return IF;}

 

"="      {returnASSIGN;}

 

";"      {returnEND_STMT;}

 

{IDENT} {Identifier();   returnID;}

 

{STR}   {StringConstant();    returnSTRING;}

 

"//"     {EatComment();}             /*comment:    skip */

 

\n      {lineno++;}                 /*newline:    countlines */

 

{WSPACE}{}                          /*whitespace: (donothing) */

 

 .       {returnERROR_TOKEN;}       /*other char: error,illegal token */

 

 

 

3)用户代码部分

这部分内容将原封不动的拷贝到LEx的输出文件当中。一般是词法分析过程中用到的一些函数1yytext 可能是一个数组或一个指针。指向被识别的记号。

 

2yylex() lex解析器的主函数,通过调用yylex()来实现对字符流的解析。通常作为一个词法扫描器的自动实现函数,他的返回值是一个整数,且通常是从258开始(防止和通常的acsii码冲突)。但有一个例外,那就是返回值00代表着到了文件结尾),通常我们匹配完一个模式后就要让yylex返回。例如:

 

[a-zA-Z]+ {return 258; }

 

这个模式就是匹配一个单词的动作,匹配完成立即返回。也就是说。外部的程序每次调用yylex()函数,只要匹配到这个WORD模式,就会立即返回。

 

但是我们也可以让它不返回(继续留在yelex()的调用里面),例如:

 

[a-zA-Z]+ {printf(WORD\n; }

 

[0-9}+ {printf(NUM\n);}

 

我们只是让它匹配完模式后在屏幕打印一些字符而已。注意:此时并未退出yylex()函数。而且yylex会继续从模式匹配的开头开始匹配,即会继续匹配下一个token

 

有关这一点的差别困扰了很多初学者。。

 

用《flex && bison》书上的原话就是:Ifaction code returns , scanning resumes on the next call toyylex(); if it doesnt return , scanning resumes immediately.

 

3yyleng,所匹配的yytext所指向的字符串的长度。

 

4yyin,是一个文件指针,指向待进行词法分析的字符流文件。

 

5yywrap(),yylex()到达输入文件的尾端时,它调用yywrap(),该函数返回数值01.如果值为1,那么程序完成而且没有输入。换句话说,如果值为0,那么词法分析程序假设yywrap()已经打开了他要读取的另外一个文件,而且继续读取yyin。默认yywrap()总是返回1.用户可以自己编写yywrap();

 

6)input()获取下一个而字符,但是如果目标语言是c++,则用yyinput(),避免与c++本身的input()函数冲突。