编译原理词法分析课程设计报告(共17页).doc

上传人:飞****2 文档编号:14398328 上传时间:2022-05-04 格式:DOC 页数:17 大小:477KB
返回 下载 相关 举报
编译原理词法分析课程设计报告(共17页).doc_第1页
第1页 / 共17页
编译原理词法分析课程设计报告(共17页).doc_第2页
第2页 / 共17页
点击查看更多>>
资源描述

《编译原理词法分析课程设计报告(共17页).doc》由会员分享,可在线阅读,更多相关《编译原理词法分析课程设计报告(共17页).doc(17页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、精选优质文档-倾情为你奉上编译原理课程设计报告题目名称实现C/C+语言的词法分析器班 级计算机二班学 号姓 名蒋阳斌指导教师宁航编写时间2011.12.262011.12.30一、课程设计题目名称实现C/C+语言词法分析器二、课程设计目的与任务(1)输入:C/C+源代码文件,即后缀为c/cpp的文件。(2)输出:后缀为tok的文本性文件。(3)实现功能:完成C/C+语言的词法分析器(C语言词法记号及其含义详见附件一)词法记号含义LB“”LP“(”RB“”RP“)”PLUS“+”三、设计思想和实现方法(一)、Lex是一种生成扫描器的工具,(我是在操作系统下安装f,进行编程的)Lex程序编程分为以

2、下四步:1. Lunix下用vi命令编写lex程序,我的文件是lex.l,编写好后 ,保存并退出。2. 使用命令flex lex.l,编译系统自动生成了lex.yy.c的C文件。3. 使用命令gcc lex.yy.c -ll,生成可执行的扫描器a.out文件。4. 使用命令a.out file1.c,其中file1.c为要进行此法扫描的C文件。我要做的就是 编写C语言词法的正则表达式,以及需要识别的各种词法记号和匹配后需要执行的动作 即可,其他的操作都可以交给Lex来执行。(二)、词法分析器的作用如下:1. 词法分析器的主要任务是读入源程序的输入字符2. 过滤掉源程序中的注释、空白(空格、换行

3、符、制表符以及输入中用于分割词法单元的其他字符)3. 对源程序进行预处理,如对源程序的宏展开4. 将编译器生成的错误消息与与源程序的位置对应起来;(三)、对于此题,我使用Lex编程来自动生成词法分析器。使用Lex编程的重点与难点是正则式的定义,对于容易产生二义性的正则表达式,我们要借助与辅助函数来解决。 以下为一个二义性的解决;plus (Int|Float|id)blank?+ /加号的正则定义plusinstall(yytext,PLUS);/转换规则里的 模式 动作需要说明的是:当+左边为一个标示符(id)或数字(num)时,我们才认为它是加号;否则为正号。但匹配到 plus正则式时,我

4、们调用int install() 辅助函数,int install()函数再把“+”前面的标示符(id)或数字(num)与“+”分离开来,其余三个容易产生歧义的符号,也采用同种处理方法,install()辅助函数的定义,将在本报告的第四部分 中给出。四、程序说明Lex是一种生成扫描器的工具,我们可以通过编写Lex文件来实现识别文本中的词汇模式的程序。一个Lex程序可具有如下形式:声明、定义部分%转换规则%辅助函数1、声明部分包括变量和明示常量(被声明的表示一个常数标示符,如一个此法单元的名字)的声明,本程序声明部分包括:C语言的头文件,及为每个关键字定义一个宏常量,为避免与冲突,数值从开始。定

5、义部分同时给出了正则表达式。第一段的部分如下,详细见附件二声明部分%# include#include#includeint yywrap();# define LB 257# define LP 258 . .# define REAL_LITERAL 367# define STRING 368# define CHARACTER 369# define NUM370%正则表达式blank 0delim tnws delim+Float E?digit+(.digit+)+(eE?digit+)?Ffid letter(letter|digit)*incom (/*+(/*+)*/)|(/

6、(.)*) mul (Int|Float|id)blank?* /乘号的正则定义Bit (Int|Float|id)blank?&/按位与的正则定义plus (Int|Float|id)blank?+ /加号的正则定义sub (Int|Float|id)blank?- /减号的正则定义.程序的每个转换规则具有如下形式:模式动作其中,每个模式是一个正则表达式,我的程序的正则表达式的定义全部在声明部分给出。动作部分是代码片段。以下为转换规则部分plusinstall(yytext,PLUS);subinstall(yytext,MINUS);mulinstall(yytext,MULT);+=pr

7、intf(n,yytext,PLUSA);-=printf(n,yytext,MINUSA);*=printf(n,yytext,MULA);/=printf(n,yytext,DIVA);Lex机器经过此法扫描。通过模式匹配产生一个动作,其形式为,其中词素为当前匹配到的最长字符串,属性值为该词素对应的属性值,这里我们通过lex程序的声明部分的宏声明,给出每个词素对应的属性值,每个词素的属性值是唯一的。.程序的第三个部分包括各个动作需要的所有辅助函数,其中()函数,这里作者定义了一个用于消除“+、*、&”二义性的辅助函数int install(const char*y,int b) int l

8、en=strlen(y);char idlen;int i;for(i=0;ilen-1;+i)idi=*( y+i);idlen-1=0;if(!sdigit(id)printf(n,id,IDENTIFIER);else printf(n,id,NUM);printf(n, ylen-1,b);return 0;五、程序运行结果在lunix中用vi编辑器,编辑一个名叫lex.l的lex程序文件;lex编译器产生lex.yy.c文件:(如下图)用gcc lex.yy.c ll命令产生a.out文件:(如下图)执行a.out文件,其中goods.c为要进行词法分析的C程序源文件,使用:./a.

9、out goods.c goods.tok 通过命令行传递文件,并把分析器产生的词素通过重定向符输入 goods.tok文件中(操作如下图)通过分屏操作符more 打开goods.tok文件(如下图)其中good.c文件的部分如下图:六、测试报告1、现在用写好的lex程序,用来扫描一个li.c文件,程序的重点在于二义性的处理,简单起见,我的li.c文件的内容不会太多,具体如下图:图(一)2、我们用命令 ./a.out li.c li.tok 对li.c文件进行词法分析,得到的结果输入到li.tok文件中,我们打开li.tok文件,其结果如下图: 图(二)在lex程序的声明部分我们定义了如下宏:

10、# define PLUS 261 /“+”为加号# define MINUS262/“-”为减号# define MULT 263/“*”为乘号# define BITAND 276/“&”为按位与操作# define UNARYMINUS 297/“-”为正号# define UNARYPLUS 298 /“+”为负号# define DEREFERECE 299/“*”为指针号# define ADDRESS 300/“&”为引用符号# define IDENTIFIER 303我们由第一部可知 a、b、c都为标示符(id),所以a、b、c其属性指都是303,第一个表达式a+b,扫描结果

11、理论为表示其为加号,由图二可知此法扫描实际结果与理论匹配;第二表达式+a中的“+”理论上是正号,对应的是,图二中的实际结果也是,其他表达式,同理也可分析出。七、存在问题及分析词法分析的正则表达式编写有些不是很全面简洁,比如说char 和income的正则式。宏定义部分显得冗余,没有把握住词法分析的程序关键要处理的词素,识别某些词法记号的正则表达式编写的不是很严谨,比如说在识别C语言预处理定义语句的正则表达式仅仅只能识别出预处理语句,而无法进行预处理包含的头文件的词法分析。程序存在一个瑕疵,在处理”+、*、&”时,扫描 id+id、id *id、id-id、id&id,时,把这四个符号当成加、减

12、、乘、与符号,但当扫描遇到num+、num*、num&、num-时,分不出mun是int 还是float类型,只是笼统的把它归为数字。这个问题是在设计辅助函数,及在正则式定义是出现的最大漏洞。对Lex编程还不是很了解,对词法分析器的作用以及工作原理的理解还有待提高八、总结及体会在拿到本次课程设计题目后,对是用C/C+还是lex进行了分析,用C/C+语言直接编写词法分析程序从思路上来说会比较容易些,但在写代码的过程中,慢慢地就暴露出直接编写词法分析程序的一些问题,比如说代码里充斥着大量的ifswitch语句,也频繁些读写语句,极大地增加了代码的复杂度,从而促使我选择使用unix下的Lex编程来自

13、动生成词法分析器的方案。使用Lex编程就简化了代码的编写,但是Lex编程的重点是正则表达式的定义。本次课程设计也暴露了我在编译原理学习中的一些不足,比如对正规式的含义和编写还有一些疑问,对辅助函数的编写显得不严谨,对词法分析器的作用和工作原理理解的不是很清等等,通过课程设计很好的复习了编译原理课程中的词法分析部分,对自己理解词法分析有很大的帮助参考文献 Alfred V.Aho Monica S.Lam Ravi Sethi Jeffrey D.Ullman 编译原理,机械工程出版社附录:附录一C语言词法记号及其含义表词法记号含义LB“”LP“(”RB“”RP“)”PLUS“+”MINUS“-

14、”MULT“*”DIV“/”MOD“%”PLUSA“+=”MINUSA“-=”MULA“*=”DIVA“/=”MODA“%=”LS“”LSA“=”NOT“!”BITAND&BITOR|XORCOMPLAND“&”OR“|”LT“”LE“”GE“=”EQ“=”NE“!=”ASSIGN“=”DOT“.”MS-LARAPOSINC+POSDEC-PREINC+PREDEC-UNARYMINUS-附件二 程序源代码:%/*Filename:lex.lProduct Lex file in unixAuthor:蒋阳斌 学号:*/# include#include#includeint yywrap()

15、;# define LB 257# define LP 258# define RB 259# define RP260# define PLUS 261# define MINUS262# define MULT 263# define DIV264# define MOD265# define PLUSA 266# define MINUSA 267# define MULA 268# define DIVA 269# define MODA 270# define LS 271# define RS 272# define LSA 273# define RSA 274# define

16、NOT 275# define BITAND 276# define BITOR 277# define XOR 278# define COMPL 279# define AND 280# define OR 281# define LT 282# define LE 283# define GT 284# define GE 285# define EQ 286# define NE 287# define ASSIGN 288# define DOT 289# define MS 290# define LA 291# define RA 292# define POSINC 293#

17、define POSDEC 294# define PREINC 295# define PREDEC 296# define UNARYMINUS 297# define UNARYPLUS 298# define DEREFERECE 299# define ADDRESS 300# define COMMA 301# define SC 302# define IDENTIFIER 303# define ASM 304# define AUTO 305# define BOOL 306# define BREAK307# define CASE 308# define CATCH 30

18、9# define CHAR 310# define CLASS 311# define CONST 312# define CONST_CAST 313# define CONTINUE 314# define DEFAULT 315# define DELETE 316# define DO 317# define DOUBLE 318# define DYNAMIC_CAST 319# define ELSE 320# define ENUM 321# define EXPLICIT 322# define EXTERN 323# define FALSE 324# define FLO

19、AT 325# define FOR 326# define FRIEND 327# define GOTO 328# define IF 329# define INLINE 330# define INT 331# define LOG 332# define LONG 333# define MUTABLE 334# define NAMESPACE 335# define NEW 336# define OPERATOR 337# define PRIVATE 338# define PROTECTED 339# define PUBLIC 340# define REGISTER 3

20、41# define REINTERPRET_CAST 342# define RETURN 343# define SHORT 344# define SIGNED 345# define SIZEOF 346# define STATIC 347# define STATIC_CAST 348# define STRUCT 349# define TEMPLATE 350# define THIS 351# define THROW 352# define TRUE 353# define TRY 354# define TYPEDEF 355# define TYPRID 356# de

21、fine TYPENAME 357# define UNION 358# define UNSIGNED 359# define USING 360# define VIRTUAL 361# define VOID 362# define VOLATITLE 363# define WCHAR_T 364# define WHILE 365# define INTEGER_LITERAL 366# define REAL_LITERAL 367# define STRING 368# define CHARACTER 369# define NUM370%/*正则式的定义*/blank 0de

22、lim tnws delim+letter A-Za-zdigit 0-9E +-Int E?digit+Float E?digit+(.digit+)Ffid letter(letter|digit)*incom (/*+(/*+)*/)|(/(.)*) Oct 0(E?)0-7+ UNSIGN 0-9+uU HEX 0xX(E?)a-fA-F0-9+ string * char (ntbrf)|(0-71,3)|(xXA-Fa-f0-91,2)|headfile #include mul (Int|Float|id)blank?*Bit (id|Int|Float)blank?&plus

23、(id|Int|Float)blank?+sub (id|Int|Float)blank?-% /*转换规则*/ws/*no action*/printf(n,yytext,LB);(printf(n,yytext,LP);printf(n,yytext,RB);)printf(n,yytext,RP);plusinstall(PLUS);/匹配加号subinstall(MINUS);/匹配减号mulinstall(MULT);/匹配乘号Bitinstall(BITAND);/匹配按位与操作符/printf(n,yytext,DIV);%printf(n,yytext,MOD);+=print

24、f(n,yytext,PLUSA);-=printf(n,yytext,MINUSA);*=printf(n,yytext,MULA);/=printf(n,yytext,DIVA);%=printf(n,yytext,MODA);printf(n,yytext,LS);printf(n,yytext,RS);=printf(n,yytext,LSA);=printf(n,yytext,RSA);!printf(n,yytext,NOT);printf(n,yytext,COMPL);&printf(n,yytext,AND);|printf(n,yytext,OR); printf(n,yy

25、text,LT);=printf(n,yytext,LE);printf(n,yytext,GT);=printf(n,yytext,GE);=printf(n,yytext,EQ);!=printf(n,yytext,NE);=printf(n,yytext,ASSIGN);.printf(n,yytext,DOT);-printf(n,yytext,MS);printf(n,yytext,LA);printf(n,yytext,RA);+printf(n,yytext,POSINC);-printf(n,yytext,POSDEC);-printf(n,yytext,UNARYMINUS)

26、;/匹配符号+printf(n,yytext,UNARYPLUS);/匹配正号*printf(n,yytext,LA);/匹配指针符号&printf(n,yytext,ADDRESS);/匹配引用符号,printf(n,yytext,COMMA);printf(n,yytext,SC);asmprintf(n,yytext,ASM);autoprintf(n,yytext,AUTO);boolprintf(n,yytext,BOOL);breakprintf(n,yytext,BREAK);caseprintf(n,yytext,CASE);catchprintf(n,yytext,CATCH

27、);charprintf(n,yytext,CHAR);classprintf(n,yytext,CLASS);constprintf(n,yytext,CONST);const_castprintf(n,yytext,CONST_CAST);continueprintf(n,yytext,CONTINUE);defaultprintf(n,yytext,DEFAULT);deleteprintf(n,yytext,DELETE);doprintf(n,yytext,DO);doubleprintf(n,yytext,DOUBLE);dynamic_cast printf(n,yytext,D

28、YNAMIC_CAST);enumprintf(n,yytext,ENUM);explicitprintf(n,yytext,EXPLICIT);externprintf(n,yytext,EXTERN);falseprintf(n,yytext,FALSE);floatprintf(n,yytext,FLOAT);forprintf(n,yytext,FOR);friendprintf(n,yytext,FRIEND);gotoprintf(n,yytext,GOTO);ifprintf(n,yytext,IF);inlineprintf(n,yytext,INLINE);intprintf

29、(n,yytext,INT);logprintf(n,yytext,LOG); long printf(n,yytext,LONG);mutableprintf(n,yytext,MUTABLE);namespaceprintf(n,yytext,NAMESPACE);newprintf(n,yytext,NEW);operatorprintf(n,yytext,OPERATOR);privateprintf(n,yytext,PRIVATE); protectedprintf(n,yytext,PROTECTED);publicprintf(n,yytext,PUBLIC);register

30、printf(n,yytext,REGISTER); reinterpret_cast printf(n,yytext,REINTERPRET_CAST);returnprintf(n,yytext,RETURN);shortprintf(n,yytext,SHORT); signedprintf(n,yytext,SIGNED);sizeofprintf(n,yytext,SIZEOF);staticprintf(n,yytext,STATIC); static_castprintf(n,yytext,STATIC_CAST);structprintf(n,yytext,STRUCT);te

31、mplateprintf(n,yytext,TEMPLATE); this printf(n,yytext,THIS);throwprintf(n,yytext,THROW);trueprintf(n,yytext,TRUE); tryprintf(n,yytext,TRY);typedefprintf(n,yytext,TYPEDEF);typeidprintf(n,yytext,TYPRID); typenameprintf(n,yytext,TYPENAME);unionprintf(n,yytext,UNION);unsignedprintf(n,yytext,UNSIGNED); u

32、singprintf(n,yytext,USING);virtualprintf(n,yytext,VIRTUAL);voidprintf(n,yytext,VOID); volatitleprintf(n,yytext,VOLATITLE);wchar_tprintf(n,yytext,WCHAR_T);whileprintf(n,yytext,WHILE); id printf(n,yytext,IDENTIFIER); Int printf(n,yytext,INT); incom printf(注释%sn,yytext); Float printf(n,yytext,FLOAT);Oc

33、t printf(n,yytext,INTEGER_LITERAL); /八进制数UNSIGNprintf(n,yytext,UNSIGNED); /无符号数HEX printf(n,yytext,INTEGER_LITERAL); /十六进制数string printf(n,yytext,STRING); /字符串char printf(n,yytext,CHARACTER); /字符headfile printf(头文件及预处理%sn,yytext); /匹配头文件及预处理 %int yywrap()return 1;int Isdigit(const char*s1) /*该函数是用来区

34、分“+、-、*、&”前是数字(num)还是标示符(id)*/ int len=strlen(s1); int i; int t=0; for(i=0;i1)return 0; return 1;int install(const char *y,int b) int len=strlen(y);char idlen;int i;for(i=0;ilen-1;+i)/*该部分用来把“+、-、*、&”和前面标示符(id)或数字(num)分离开来*/idi=*( y+i);idlen-1=0;if(!Isdigit(id)printf(n,id,IDENTIFIER);else printf(n,i

35、d,NUM);printf(n, ylen-1,b);return 0;int main(int argc,char*argv)if(argc!=2)printf(没有提供要词法分析的文件!请按正确的格式输入:n);printf(如 a.out XXX.cpp);return 1; printf(作者:蒋阳斌 学号:n); printf(#使用LEX实现的C/C+词法分析#n);yyin=fopen(argv1,r); if(yyin=NULL) printf(C/C+文件没有打开 n); return 2; printf(=n); printf(文件产生的词法分析的结果如下:n,argv1);yylex()

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁