C 语言的 lex工具

源于编译的实验作业……

参考链接:blog.csdn.net/dl88250/article/details/1714626

Lex工具是一种词法分析程序生成器,它可以根据词法规则说明书的要求来生成单词识别程序,由该程序识别出输入文本中的各个单词。

一、结构:定义部分、规则部分、用户子程序部分

1、定义部分

定义部分起始于"%{"符号,终止于"%}"符号,其间可以是包括include语句、声明语句在内的C语句。

%{

#include "stdio.h"

#include "y.tab.h"

extern int lineno;

%}

第二部分是一组正规定义和状态定义。正规定义是为了简化后面的词法规则而给部分正规式定义了名字。每条正规定义也都要顶着行首写。例如下面这组正规定义分别定义了letter,digit和id所表示的正规式:

letter      [A-Za-z]

digit        [0-9]

id          {letter}({letter}|{digit})*

注意:上面正规定义中出现的小括号表示分组,而不是被匹配的字符。而大括号括起的部分表示正规定义名。

2、规则部分

规则部分起始于"%%"符号,终止于"%%"符号,其间则是词法规则。

词法规则由模式和动作两部分组成。模式部分可以由任意的正则表达式组成,动作部分是 由C语言语句组成,这些语句用来对所匹配的模式进行相应处理。需要注意的是,lex将识别出来的单词存放在yytext[]字符数据中,因此该数组的内容 就代表了所识别出来的单词的内容。

%%

[/t] {;}

[0-9]+/.?|[0-9]*/.[0-9]+

{ sscanf(yytext,"%1f", &yylval.val);

return NUMBER; }

/n { lineno++;return '/n'; }

.  { return yytex+[0]; }

%%

3、用户子程序部分

用户子程序部分可以包含用C语言编写的子程序,而这些子程序可以用在前面的动作中,这样就可以达到简化编程的目的。下面是带有用户子程序的lex程序片段。

"/*"   skipcmnts();

.   /* rest of rules  */

%%

skipcmnts()

{

for (  ;  ;   )

{

while (input()!='*');

if(input()!='/')

unput(yytext[yylen-1]);

else return;

}

二、Lex常规表达式

参考链接:blog.csdn.net/hguisu/article/details/7490027

C 语言的 lex工具_第1张图片

举例:

C 语言的 lex工具_第2张图片

标记声明举例:

C 语言的 lex工具_第3张图片

三、 Lex源程序中常用到的变量及函数:

yyin和yyout:这是Lex中本身已定义的输入和输出文件指针。这两个变量指明了lex生成的词法分析器从哪里获得输入和输出到哪里。默认:键盘输入,屏幕输出。

yytext和yyleng:这也是lex中已定义的变量,直接用就可以了。

yytext:指向当前识别的词法单元(词文)的指针

yyleng:当前词法单元的长度。

ECHO:Lex中预定义的宏,可以出现在动作中,相当于fprintf(yyout, “%s”,yytext),即输出当前匹配的词法单元。

yylex():词法分析器驱动程序,用Lex翻译器生成的lex.yy.c内必然含有这个函数。

yywrap():词法分析器遇到文件结尾时会调用yywrap()来决定下一步怎么做:

若yywrap()返回0,则继续扫描

若返回1,则返回报告文件结尾的0标记。

由于词法分析器总会调用yywrap,因此辅助函数中最好提供yywrap,如果不提供,则在用C编译器编译lex.yy.c时,需要链接相应的库,库中会给出标准的yywrap函数(标准函数返回1)。

你可能感兴趣的:(C 语言的 lex工具)