用Lex做词法分析

用Lex做词法分析


Lex编译器将输入的模式转换成一个状态转换图,并生成相应的实现代码,并存放到文件lex.yy.c中,这些代码模拟了状态转换图。


用Lex创建一个词法分析器
冲突解决规则:
1) 总是选择最长的前缀
2) 如果最长的可能前缀与多个模式匹配,总是选择Lex中先被列出的模式。

【实验步骤】


1、实验环境配置

安装Parser Generator,并编译lex和yacc函数库
使用向导配置时,用的VS2010,属性设置如下(有些库是用的VC++6.0)
Compiler Bin Directory C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO 10.0\VC\BIN
Compiler Bin Directory(2) C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO 10.0\COMMON7\IDE
Compiler Include Directory C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO 10.0\VC\INCLUDE
Compiler Include Directory(2) C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\INCLUDE
Compiler Library Directory C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO 10.0\VC\LIB
Compiler Library Directory(2) C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\LIB

2、编写Lex程序

(1)练习3.5.2:编写一个Lex程序。该程序拷贝一个文件,并将文件中的每个非空的空白符序列替换为单个空格。
编写Lex程序如下:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [\t]+  {printf(“”);}  
表示遇到连续多个空白符(或制表符),则替换为一个空格符
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. \n|.    {printf(“%s”,yytext);}  
表示其余的语句均照常打印出来

实验结果
读入文件:

替换掉空白符后结果:


(2)练习3.5.3:编写一个Lex程序。该程序拷贝一个C文件,并将程序中的关键字float的每个实例替换成double

编写Lex程序如下:


[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. \”.*\”  {printf(“%s”,yytext);}  
表示如果是在双引号(“)中(即为字符串),则照常打印
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. float/[ \t]+  {printf(“double”);}  
表示如果遇到float,且附加模式是后面跟有空白符,则将float替换为double
在这句话前面加上
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [^ \t\n]+ {printf(“%s”,yytext);}  
(连续的非空白符),是为了保证当float并非关键字时,如afloat,不会被替换为adouble.

实验结果
读入C文件:


替换掉关键字float后如下:


(3)练习3.5.4:编写一个Lex程序。该程序把一个文件改变成为“Pig latin”文。明确的讲,假设该文件是一个用空白符分隔开的单词(即字母串)序列。每当你遇到一个单词时:
1)如果第一个字母是辅音字母,则将它移到单词结尾,并加上ay
2)如果第一个字母是元音字母,则只在单词的结尾加上ay
所有非字母的字符不加处理直接拷贝到输出

编写Lex程序如下:


[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. {YuanYin}({Letter})*/[ \t\n]+ {printf(“%say”,yytext);}  
表示遇到元音字母开头的字母串,且附加模式跟有空白符(确保为单词),则在单词结尾加上ay
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. {FuYin}({Letter})*/[ \t\n]+ {printf(”%s%cay”,&yytext[1],yytext[0]);}  
表示遇到辅音字母开头的字母串,且附加模式跟有空白符(确保为单词),则从单词第二个字母开始输出,之后输出第一个字母,再在结尾加上ay

实验结果
输入aword bword “word”,转换成“Pig Latin”文结果:

【结果分析】

(1)通过实验熟悉了Lex做词法分析。在定义规则时,对Lex解决冲突的两个原则体会尤深——总是选择最长的前缀;如果最长的可能前缀与多个模式匹配,总是选择Lex中先被列出的模式。
(2)实验中几个题目并不复杂,但却很难考虑到所有的情况,如第二个练习替换float时,不能只遇到float即可,还要判断其是否为关键字。在后面发现实验中忘了考虑float单词出现在注释中的情况。不过考虑方法和进阶实验中的考虑相似。

转载请注明出处:http://blog.youkuaiyun.com/xiaowei_cqu/article/details/7760927

编译原理是研究如何将高级程序语言翻译成机器语言的学科。在编译过程中,词法分析是其中的重要一步,它将源代码分割成一系列单词(token),并标注上不同的词法单位。 lex是一种常用的用于生成词法分析器的工具。它通过读取用户定义的规则,自动生成对应的词法分析器代码。当我们需要构建一个词法分析运行环境时,可以使用lex使用lex生成的词法分析器代码一般包含以下几个部分: 1. 用户定义的词法规则:我们需要定义要识别的各种单词和对应的正则表达式。例如,定义关键字、标识符、数字、运算符等。 2. 词法规则匹配代码:lex会根据我们定义的规则,自动生成对应的匹配代码。以进行匹配操作,并且在匹配到相应单词时,执行相应的操作。这些操作可以是输出单词信息、进一步处理等。 3. 其他辅助代码:我们可以在lex生成的代码中,添加一些自定义的函数或全局变量,来辅助词法分析的进行。 使用lex进行词法分析的运行环境可以通过以下步骤来实现: 1. 定义词法规则:根据目标语言的词法规则,使用lex提供的语法,定义要识别的各种单词和对应的正则表达式。 2. 生成词法分析器代码:使用lex工具,将定义好的词法规则作为输入,生成对应的词法分析器代码。 3. 编译生成的词法分析器代码:将生成的词法分析器代码编译成可执行文件。 4. 运行词法分析器:将需要进行词法分析的源代码输入给词法分析器,它会根据我们定义的规则,将源代码分割成一系列单词,并进行相应的处理和输出。 通过使用lex,我们可以方便快捷地生成用于词法分析的运行环境,减少了手动编写词法分析器的工作量,并提高了开发效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值