基于LEX的C语言词法分析器Word文档格式.docx

上传人:b****1 文档编号:13166386 上传时间:2022-10-07 格式:DOCX 页数:13 大小:288.62KB
下载 相关 举报
基于LEX的C语言词法分析器Word文档格式.docx_第1页
第1页 / 共13页
基于LEX的C语言词法分析器Word文档格式.docx_第2页
第2页 / 共13页
基于LEX的C语言词法分析器Word文档格式.docx_第3页
第3页 / 共13页
基于LEX的C语言词法分析器Word文档格式.docx_第4页
第4页 / 共13页
基于LEX的C语言词法分析器Word文档格式.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

基于LEX的C语言词法分析器Word文档格式.docx

《基于LEX的C语言词法分析器Word文档格式.docx》由会员分享,可在线阅读,更多相关《基于LEX的C语言词法分析器Word文档格式.docx(13页珍藏版)》请在冰豆网上搜索。

基于LEX的C语言词法分析器Word文档格式.docx

%}

正则表达式声明的格式为“命名表达式”,比如:

digit[0-9]+

alphabet[A-Za-z]+

whitespace[\t]+

功能函数即为正常的C语言代码,遵守C语言代码格式即可。

(二)Lex特性简介

1.Lex依次尝试每一个规则,尽可能地匹配最长的输入流。

2.如果有一些内容根本不匹配任何规则,那么Lex将把它拷贝到标准输出。

二、正则表达式简介

在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。

正则表达式就是用于描述这些规则的工具。

换句话说,正则表达式就是记录文本规则的代码。

在这里,只用到了字符转义、重复、字符类、反义、贪婪与懒惰等较为基础的语法。

以下就简单对涉及到的语法进行介绍。

(一)字符转义

例如,.*在正则表达式中表示匹配所有,因此若要匹配.或*,则需要对其进行转义,即\.和\*。

(二)重复

在对数字和标识符等进行匹配时,字符位数不止一位,但遵守相同的规则,因此使用“重复”进行匹配。

例如,对数字进行匹配:

[0-9]+,“+”表示至少重复一次,即数字长度至少为1。

例如,对标识符进行匹配,由于C语言标识符必须以下划线或字母开头,所以规则为:

[_|A-Za-z]+(_|[A-Za-z]|[0-9])*。

“[_|A-Za-z]+”表示必须以下划线或字母开头,“(_|[A-Za-z]|[0-9])*”表示之后可以跟字母数字下划线,但是也可以不跟,这就是“+”和“*”所表示的“重复”的不同之处。

(三)字符类与反义

对没有预定义元字符的字符集合,需要在方括号里将其列出,例如,[aeiou]就是对任何一个英文元音字母的匹配,同理,[0-9]代表的含义与元字符\d完全一致,都是对一位数字进行的匹配。

有时需要查找不属于某个能简单定义的字符类的字符。

比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义:

对于元字符,其反义即为其大写:

\D,匹配非数字的字符。

更为普遍的表达方式如下:

[^aeiou],匹配除了aeiou这几个字母以外的所有字符。

(四)贪婪与懒惰

与Lex对规则的处理类似,正则表达式也会在匹配整个表达式的前提下,匹配尽可能多的字符,这就是“贪婪”。

有时,需要匹配尽可能少的字符,就是“懒惰”匹配,具体的例子如下:

a.*?

b,由于.*后加了?

,表示“懒惰”匹配,因此会匹配最短的,以a开始,以b结束的字符。

例如字符串aabab,“贪婪”匹配的结果是aabab,而“懒惰”匹配的结果则是aab。

三、词法分类识别

这里,将源程序中的字符分为七类。

由于字符串对于词法分析以及后续的语法分析的意义不大,因此,这里将其单独列为一类;

由于头文件的声明中会出现“<

”“>

”“””等分隔符,尤其是“<

”和“>

”,会与运算符中的大于小于号产生冲突,因此这里把头文件也单独列为一类。

(一)保留字

C语言共有32个保留字,如图:

(二)标识符

C语言标识符的要求是,必须以下划线或者字母开头,之后可以跟字母、数字、下划线。

(三)常数

由于常数的表达方式较多,这里只是代表性地选取了几种方式进行识别。

(四)操作符

C语言操作符包括一元操作符、二元操作符和三元操作符。

(五)字符串

这里的字符串是指包围在单引号或双引号内的字符串。

(六)分隔符

这里选取了以下经常见到的分隔符:

(七)头文件

头文件的格式有一下两种:

四、词法识别分类规则

(一)常数的识别

根据上述对常数识别的需求,构造出了如下正则表达式:

[0-9]+[\.0-9]*|

[0-9]+[\.0-9]*([e|E][+|-][0-9]+)|

0[x|X]([0-9abcdefABCDEF]+)

这里,为了美观,以“|”为分隔符,对表达式进行了换行处理,每一行对应一个常数类别。

第一行,表示对整数和浮点数进行匹配;

第二行,先对整数或浮点数进行匹配,之后匹配e或E,最后匹配一个整数,即123.456e+789的形式,即科学计数法;

第三行,先匹配数字0,之后匹配字母x或X,最后匹配0-9及a-f或A-F的字符,即0x123abc的形式,即16进制表示法。

(二)保留字的识别

C语言中有32个保留字,且区分大小写,因此,这里构造如下正则表达式进行匹配:

auto|break|case|char|const|continue|default|do|

double|else|enum|extern|float|for|goto|if|int|

long|register|return|short|signed|sizeof|static|

struct|switch|typedef|union|unsigned|void|

volatile|while

可见,只需简单的将各个保留字通过“|”符号进行连接,即可实现对所有保留字的识别。

(三)分隔符的识别

由于分隔符中存在与正则表达式中元字符相冲突的字符,如“.”,“[”等,因此需要对这些产生冲突的符号进行转义,构造如下正则表达式:

|;

|\(|\)|\{|\}|\[|\]|\'

|\"

|<

|>

(四)标识符的识别

根据上述的C语言标识符的要求,构造如下正则表达式:

[_|A-Za-z]+(_|[A-Za-z]|[0-9])*

此处涉及正则表达式语法较为简单,不再赘述。

(五)操作符的识别

由于操作符中,存在大量运算符号与正则表达式的元字符冲突,因此,根据C语言中的三种操作符,构造以下正则表达式:

>

=|<

<

=|\+\+|--|==|>

=|!

=|&

&

|\|\||<

|\+=|

-=|\*=|\/=|%=|&

=|\|=|^=|\+|-|\*|\/|%|>

|!

|&

~|

^|=

可以看到表达式中含有大量转义字符,使得原本容易识别的C语言操作符变得难以分辨,但根据“|”连接符的指示,单个单个的分析,还是很容易明白的。

(六)其他字符的识别

对于空白、换行、注释、头文件等的识别,规则较为简单,这里不再一一举出。

五、词法识别分类顺序

由于Lex对正则表达式的支持并不完全,因此存在不同表达式匹配同一字符串的现象。

这里,为了减少这种现象的发生,降低出错率,对规则的优先级进行了调整,以更好的满足设计需求。

这里从两方面进行说明,一是标识符和保留字的识别顺序,二是一、二、三元操作符的识别顺序。

(一)标识符和保留字的识别顺序

由于标识符的识别规则会同时把保留字当做标识符进行匹配,从而产生错误,因此,需要调换这两条规则的匹配优先级,调整的结果如图所示:

这样就能保证,Lex在进行词法分析时,优先将满足保留字匹配规则的字符串匹配出来,从而避免误判。

(二)一、二、三元操作符的识别顺序

由于C语言中存在多元操作符,因此在对操作符进行匹配的时候,就要考虑到将其完整匹配,而不是将一个多元操作符分为多个一元操作符进行匹配。

这里,就需要对正则表达式内匹配规则的顺序进行一个调整,即对位数多的操作符优先进行匹配,具体的做法就是,将其匹配规则提前,如下所示:

这样在对操作符进行匹配时,就能够正确进行匹配,不产生错误和冲突。

六、测试代码

为了检验该词法分析器是否能实现词法分析,根据功能需求,设计了如下测试代码ori.c:

对头文件、两种注释方式、四种类型的数字、一元和三元运算符、字符串、分隔符、标识符、保留字在词法上进行了相关的构造。

由于未涉及语义分析,因此,为了便于做词法分析,代码加入了各种类型的语句,但只是形式,不能正常运行。

七、结果分析

程序运行命令:

其中lex.l即为编写的Lex源代码;

lex.yy.x是上一步flex对lex.l源代码进行处理,生成的文件;

用gcc对lex.yy.c进行编译,生成可执行二进制文件flex;

运行flex,将对ori.c文件进行词法分析。

以下为程序分析结果:

可以看出,该词法分析器能够正常运行,对程序的词法进行了准确率较高的识别。

但是,仍然存在一些问题,比如,对于负数无法进行识别,程序会将负号识别为操作符,这一错误无法通过调整优先级进行改正,需要对正则表达式进行进一步改进。

由于减号和负号的适用场合较为复杂,之前尝试着使用正则表达式的“负向零宽断言”语法进行匹配,但发现Lex无法识别该语法,导致无法运行,目前暂时还未想到解决办法。

另外一点是,Lex只能进行语法分析,且没有错误处理机制,要做到错误处理,只有在语义层使用Yacc进行处理。

因此,若出现词法错误,Lex会直接把无法识别的字符打印出来,而不对其进行进一步的处理,也未提供相关功能。

八、参考文献

《程序设计语言编译原理》,陈火旺等著,国防工业出版社.

正则表达式30分钟入门教程,

Yacc与Lex快速入门,

LexManualPage,http:

//plan9.bell-

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > IT认证

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1