编译原理词法分析课程设计报告Word格式文档下载.doc

上传人:b****2 文档编号:14569299 上传时间:2022-10-23 格式:DOC 页数:17 大小:481.50KB
下载 相关 举报
编译原理词法分析课程设计报告Word格式文档下载.doc_第1页
第1页 / 共17页
编译原理词法分析课程设计报告Word格式文档下载.doc_第2页
第2页 / 共17页
编译原理词法分析课程设计报告Word格式文档下载.doc_第3页
第3页 / 共17页
编译原理词法分析课程设计报告Word格式文档下载.doc_第4页
第4页 / 共17页
编译原理词法分析课程设计报告Word格式文档下载.doc_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

编译原理词法分析课程设计报告Word格式文档下载.doc

《编译原理词法分析课程设计报告Word格式文档下载.doc》由会员分享,可在线阅读,更多相关《编译原理词法分析课程设计报告Word格式文档下载.doc(17页珍藏版)》请在冰豆网上搜索。

编译原理词法分析课程设计报告Word格式文档下载.doc

LB

“{”

LP

“(”

RB

“}”

RP

“)”

PLUS

“+”

三、设计思想和实现方法

(一)、Lex是一种生成扫描器的工具,(我是在Lunix 操作系统下安装flex,进行编程的)

Lex程序编程分为以下四步:

1.Lunix下用vi命令编写lex程序,我的文件是lex.l,编写好后,保存并退出。

2.使用命令flexlex.l,编译系统自动生成了lex.yy.c的C文件。

3.使用命令gcclex.yy.c-ll,生成可执行的扫描器a.out文件。

4.使用命令a.outfile1.c,其中file1.c为要进行此法扫描的C文件。

我要做的就是编写C语言词法的正则表达式,以及需要识别的各种词法记号和匹配后需要执行的动作即可,其他的操作都可以交给Lex来执行。

(二)、词法分析器的作用如下:

1.词法分析器的主要任务是读入源程序的输入字符

2.过滤掉源程序中的注释、空白(空格、换行符、制表符以及输入中用于分割词法单元的其他字符)

3.对源程序进行预处理,如对源程序的宏展开

4.将编译器生成的错误消息与与源程序的位置对应起来;

(三)、对于此题,我使用Lex编程来自动生成词法分析器。

使用Lex编程的重点与难点是正则式的定义,对于容易产生二义性的正则表达式,我们要借助与辅助函数来解决。

以下为一个二义性的解决;

plus({Int}|{Float}|{id}){blank}?

\+//加号的正则定义

{plus} {install(yytext,PLUS);

}//转换规则里的模式{动作}

需要说明的是:

当‘+’左边为一个标示符(id)或数字(num)时,我们才认为它是加号;

否则为正号。

但匹配到plus正则式时,我们调用intinstall()辅助函数,intinstall()函数再把“+”前面的标示符(id)或数字(num)与“+”分离开来,其余三个容易产生歧义的符号,也采用同种处理方法,install()辅助函数的定义,将在本报告的第四部分<

程序说明>

中给出。

四、程序说明

Lex是一种生成扫描器的工具,我们可以通过编写Lex文件来实现识别文本中的词汇模式的程序。

一个Lex程序可具有如下形式:

声明、定义部分

%%

转换规则

%%

辅助函数

1、声明部分包括变量和明示常量(被声明的表示一个常数标示符,如一个此法单元的名字)的声明,本程序声明部分包括:

C语言的头文件,及为每个关键字定义一个宏常量,为避免与ASCII冲突,数值从257开始。

定义部分同时给出了正则表达式。

第一段的部分如下,详细见附件二

声明部分

%{

#include<

stdio.h>

#include<

string.h>

ctype.h>

intyywrap();

#defineLB 257

#defineLP 258

….

….

#defineREAL_LITERAL 367

#defineSTRING 368

#defineCHARACTER 369

#defineNUM 370

%}

正则表达式

blank\0

delim[\t\n]

ws{delim}+

FloatE?

{digit}+(\.{digit}+)+(e{E}?

{digit}+)?

[Ff]

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

incom(\/\*[^*]*\*+([^/*]*\*+)*\/)|(\/\/(.)*)

mul({Int}|{Float}|{id}){blank}?

\*//乘号的正则定义

Bit({Int}|{Float}|{id}){blank}?

\&

//按位与的正则定义

sub({Int}|{Float}|{id}){blank}?

\-//减号的正则定义

2.LEX程序的每个转换规则具有如下形式:

    模式{动作}

其中,每个模式是一个正则表达式,我的程序的正则表达式的定义全部在声明部分给出。

动作部分是代码片段。

以下为转换规则部分

}

{sub} {install(yytext,MINUS);

{mul} {install(yytext,MULT);

"

+="

{printf("

<

%s,%d>

\n"

yytext,PLUSA);

-="

yytext,MINUSA);

*="

yytext,MULA);

/="

yytext,DIVA);

Lex机器经过此法扫描。

通过模式匹配产生一个动作,其形式为<

词素,属性值>

,其中词素为当前匹配到的最长字符串,属性值为该词素对应的属性值,这里我们通过lex程序的声明部分的宏声明,给出每个词素对应的属性值,每个词素的属性值是唯一的。

3.Lex程序的第三个部分包括各个动作需要的所有辅助函数,其中int yywrap() 函数,这里作者定义了一个用于消除“+、—、*、&

”二义性的辅助函数

intinstall(constchar*y,intb)

{

intlen=strlen(y);

charid[len];

inti;

for(i=0;

i<

len-1;

++i)

id[i]=*(y+i);

id[len-1]='

\0'

;

if(!

sdigit(id))printf("

%s,%d>

id,IDENTIFIER);

elseprintf("

id,NUM);

printf("

%c,%d>

y[len-1],b);

return0;

};

五、程序运行结果

在lunix中用vi编辑器,编辑一个名叫lex.l的lex程序文件;

lex编译器产生lex.yy.c文件:

(如下图)

用gcclex.yy.c–ll命令产生a.out文件:

执行a.out文件,其中goods.c为要进行词法分析的C程序源文件,

使用:

./a.outgoods.c>

goods.tok通过命令行传递文件,并把分析器产生的词素通过重定向符‘>

’输入goods.tok文件中(操作如下图)

通过分屏操作符more打开goods.tok文件(如下图)

其中good.c文件的部分如下图:

六、测试报告

1、现在用写好的lex程序,用来扫描一个li.c文件,程序的重点在于二义性的处理,简单起见,我的li.c文件的内容不会太多,具体如下图:

(一)

2、我们用命令./a.outli.c>

li.tok对li.c文件进行词法分析,得到的结果输入到li.tok文件中,我们打开li.tok文件,其结果如下图:

(二)

在lex程序的声明部分我们定义了如下宏:

#definePLUS 261//“+”为加号

#defineMINUS 262//“-”为减号

#defineMULT 263//“*”为乘号

#defineBITAND276//“&

”为按位与操作

#defineUNARYMINUS297//“-”为正号

#defineUNARYPLUS298//“+”为负号

#defineDEREFERECE299//“*”为指针号

#defineADDRESS300//“&

”为引用符号

#defineIDENTIFIER303

我们由第一部可知a、b、c都为标示符(id),所以a、b、c其属性指都是303,第一个表达式a+b,扫描结果理论为<

+,261>

表示其为加号,由图二可知此法扫描实际结果与理论匹配;

第二表达式+a中的“+”理论上是正号,对应的是<

+,298>

图二中的实际结果也是<

,其他表达式,同理也可分析出。

七、存在问题及分析

词法分析的正则表达式编写有些不是很全面简洁,比如说char和income的正则式。

宏定义部分显得冗余,没有把握住词法分析的程序关键要处理的词素,

识别某些词法记号的正则表达式编写的不是很严谨,比如说在识别C语言预处理定义语句的正则表达式仅仅只能识别出预处理语句,而无法进行预处理包含的头文件的词法分析。

程序存在一个瑕疵,在处理”+、—、*、&

”时,扫描id+id、id*id、id-id、id&

id,时,把这四个符号当成加、减、乘、与符号,但当扫描遇到num+、num*、num&

、num-时,分不出mun是int还是float类型,只是笼统的把它归为数字。

这个问题是在设计辅助函数,及在正则式定义是出现的最大漏洞。

对Lex编程还不是很了解,对词法分析器的作用以及工作原理的理解还有待提高

八、总结及体会

在拿到本次课程设计题目后,对是用C/C++还是lex进行了分析,用C/C++语言直接编写词法分析程序从思路上来说会比较容易些,但在写代码的过程中,慢慢地就暴露出直接编写词法分析程序的一些问题,比如说代码里充斥着大量的if…switch…语句,也频繁些读写语句,极大地增加了代码的复杂度,从而促使我选择使用unix下的Lex编程来自动生成词法分析器的方案。

使用Lex编程就简化了代码的编写,但是Lex编程的重点是正则表达式的定义。

本次课程设计也暴露了我在编译原理学习中的一些不足,比如对正规式的含义和编写还有一些疑问,对辅助函数的编写显得不严谨,对词法分析器的作用和工作原理理解的不是很清等等,通过课程设计很好的复习了编译原理课程中的词法分析部分,对自己理解词法分析有很大的帮助

参考文献

AlfredV.AhoMonicaS.LamRaviSethiJeffreyD.Ullman《编译原理》,机械工程出版社

附录:

附录一

C语言词法记号及其含义表

MINUS

“-”

MULT

“*”

DIV

“/”

MOD

“%”

PLUSA

“+=”

MINUSA

“-=”

MULA

“*=”

DIVA

“/=”

MODA

“%=”

LS

“<

RS

“>

>

LSA

=”

RSA

NOT

“!

BITAND

&

BITOR

|"

XOR

^"

COMPL

~"

AND

“&

OR

“||”

LT

LE

GT

GE

EQ

“==”

NE

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

当前位置:首页 > 党团工作 > 入党转正申请

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

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