编译原理课程设计报告_第1页
编译原理课程设计报告_第2页
编译原理课程设计报告_第3页
编译原理课程设计报告_第4页
编译原理课程设计报告_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、精选优质文档-倾情为你奉上编译原理课程设计报告 实验1:用Lex设计词法分析器1实验目的:学会用lex设计一个词法分析器。实验内容:使用lex为下述文法语言写一个词法分析器。实验要求:输入为用该语言所写的源程序文件;输出为记号序列,每个记号显示为二元组(记号名,记号属性值)的形式。输出可以在屏幕上,也可以输出到文件中。不要求建立符号表。在cygwin下用flex和gcc工具将实验调试通过,并能通过例子parser0中testcases目录下的test1.p测试例的测试。实验参考:exam1.l和exam2.l。语言文法:<程序>à PROGRAM <标识符>

2、; <分程序><分程序>à <变量说明> BEGIN <语句表> END.<变量说明> à VAR <变量说明表><变量说明表>à<变量表>: <类型> | <变量表>: <类型> <变量说明表><类型>à INTEGER | REAL<变量表>à <变量> | <变量>, <变量表><语句表>à <语句> |

3、 <语句> <语句表><语句>à <赋值语句> | <条件语句> | <WHILE语句> | <复合语句><赋值语句>à<变量> := <算术表达式><条件语句>à IF <关系表达式> THEN <语句> ELSE <语句><WHILE语句>à WHILE <关系表达式> DO <语句><复合语句> à BEGIN <语句表

4、> END<算术表达式> à <项> | <算术表达式> + <项> | <算术表达式> - <项><项> à <因式> | <项> * <因式> | <项> / <因式><因式>à <变量> | <常数> | (<算术表达式>)<关系表达式>à <算术表达式> <关系符> <算术表达式><变量>&#

5、224; <标识符><标识符>à <标识符><字母> | <标识符><数字> | <字母><常数>à <整数> | <浮点数><整数>à <数字> | <数字> <整数><浮点数>à .<整数> | <整数>.<整数><关系符>à < | <= | = | > | >=| <><

6、字母>à A | B | | X | Y | Z | a | b | | x | y | z<数字>à0|1|2|9程序代码:%#include <stdio.h> #define LT1#defineLE2#define GT3#defineGE4#defineEQ5#define NE6#define PROGRAM 7#define END13#define VAR9#define IF10#define THEN 11#define ELSE 12#define WHILE18#defineDO19#define ID 20#defin

7、e NUMBER 21#define RELOP 22#define NEWLINE 23#define ERRORCHAR 24%delim t nwsdelim+letter A-Za-zdigit 0-9id_|letter(letter|digit)*numberdigit+(.digit+)?(E+-?digit+)?int1 digit|digitint1*/%s COMMENT%<INITIAL>"/*"BEGIN COMMENT;ECHO;<COMMENT>"*/"BEGIN INITIAL;ECHO;<CO

8、MMENT>.|nECHO; /* ECHO是一个宏,相当于 fprintf(yyout, "%s", yytext)*/<INITIAL>ws ;<INITIAL>whilereturn (WHILE);<INITIAL>do return (DO);<INITIAL>PROGRAM return (PROGRAM);<INITIAL>end return (END);<INITIAL>VAR return (VAR);<INITIAL>if return (IF);<INIT

9、IAL>then return (THEN);<INITIAL>else return (ELSE);<INITIAL>id return (ID);<INITIAL>number return (NUMBER);<INITIAL>"<" return (RELOP);<INITIAL>"<=" return (RELOP);<INITIAL>"=" return (RELOP);<INITIAL>"<>&quo

10、t; return (RELOP);<INITIAL>">" return (RELOP);<INITIAL>">=" return (RELOP);<INITIAL>"+" return (RELOP);<INITIAL>"-" return (RELOP);<INITIAL>"*" return (RELOP);<INITIAL>"/" return (RELOP);<INITIAL

11、>":=" return (RELOP);<INITIAL>"" return (RELOP);<INITIAL>"." return (RELOP);<INITIAL>"," return (RELOP);<INITIAL>.return ERRORCHAR;%int yywrap () return 1;void writeout(int c) switch(c) case ERRORCHAR: fprintf(yyout, "(ERRORCHAR

12、, "%s") ", yytext);break; case RELOP: fprintf(yyout, "(RELOP, "%s") ", yytext);break; case WHILE: fprintf(yyout, "(WHILE, "%s") ", yytext);break; case DO: fprintf(yyout, "(DO, "%s") ", yytext);break; case NUMBER: fprintf(yyou

13、t, "(NUM, "%s") ", yytext);break; case ID: fprintf(yyout, "(ID, "%s") ", yytext);break; case NEWLINE: fprintf(yyout, "n");break; case PROGRAM: fprintf(yyout, "(PROGRAM, "%s") ", yytext);break; case END: fprintf(yyout, "(END,

14、"%s") ", yytext);break; case VAR: fprintf(yyout, "(VAR, "%s") ", yytext);break; case IF: fprintf(yyout, "(IF, "%s") ", yytext);break; case THEN: fprintf(yyout, "(THEN, "%s") ", yytext);break; case ELSE: fprintf(yyout, "(

15、ELSE, "%s") ", yytext);break; default:break; return;int main (int argc, char * argv)int c,j=0;if (argc>=2) if (yyin = fopen(argv1, "r") = NULL) printf("Can't open file %sn", argv1); return 1; if (argc>=3) yyout=fopen(argv2, "w"); while (c = yyle

16、x()writeout(c);j+;if (j%5 = 0) writeout(NEWLINE);if(argc>=2) fclose(yyin); if (argc>=3) fclose(yyout);return 0;测试文件为Test1.p:PROGRAM test;VAR i, j, k: INTEGER; f0: REAL;BEGIN i := 1; j := 1; k := 0; f0 := 3.2; WHILE k<=100 DO BEGIN IF j <20 THEN BEGIN j := i; k := k+1; f0 := f0*0.2 END EL

17、SE BEGIN j := k; k := k-2; f0 := f0/.2 END ENDEND.运行结果:实验2:用Lex设计词法分析器2实验目的:学会用lex设计一个词法分析器,并考虑其与后续语法分析器的链接问题。实验内容:修改上次实验1的词法分析器,使其满足下列要求。实验要求:1. 要求每次调用词法分析函数yylex时,只返回一个记号(token);2. 为记号选择适当的属性值,并且每次词法分析函数返回记号前,都将记号的属性值存入全局变量yylval中。(yylval可以自己定义为全局变量);3. 记号属性值的选择:标识符的属性为标识符的名字字符串(例如,标识符name1的属性为字符串

18、”name1”),整数的属性为整数值,浮点数的属性为浮点数值。其他记号属性值可自己选择。关键字可以省略属性。4. 注意:由于属性值需要存入yylval中,并且记号属性值的类型比较多(可能为字符串、整数、浮点数等),因此yylval必须能同时存放各种类型的值(提示:将yylval设置为union类型)。5. 在cygwin下用flex和gcc工具将实验调试通过,并能通过例子parser0中testcases目录下的test1.p测试例的测试。实验3:熟悉Yacc的使用实验目的:熟悉语法分析器生成工具Yacc的使用,并学会在cygwin下使用bison工具编译Yacc文法说明文件。学习如何使用le

19、x和yacc合作进行语法分析。实验内容:根据给出的calculator例子(calculator0,calculator1,calculator2,calculator3)完成下面题目:用lex和yacc写一个计算布尔表达式真值的计算器。实验要求:输入为一个布尔表达式,以换行结束。输出为这个布尔表达式的真值(true或false)。必须用二义文法实现。布尔表达式二义文法为:S > S or S | S and S | not S | (S) | true | false,其中优先级or < and < not,or 和 and 左结合,not 右结合。用非二义文法实现作为选作

20、内容,非二义文法请参照表达式非二义文法自己写出来。在cygwin下用flex,bison和gcc工具将实验调试通过,并写出测试例测试正确性。实验参考:calculator0-3这四个例子。程序代码:Cal.y文件:%int yylex(); #define YYSTYPE double /* 将Yacc栈定义为double类型 printf("nThe value of the expression is %lf.n", $1);*/%token NUM LPAREN RPAREN ENTER %left OR%left AND%right NOT%left PLUS MI

21、NUS%left TIMES DIVIDE%right UMINUS% /* 这样写prog可以让分析器每次读入一行进行分析,下一行重新分析expr */prog : prog exprp | exprp ;exprp : expr ENTER printf("1 表示 true;0 表示 false %lf.n", $1);shuchu($1); ;expr : expr PLUS expr$ = $1 + $3;| expr MINUS expr $ = $1 - $3;| expr TIMES expr $ = $1 * $3;| expr DIVIDE expr $

22、 = $1 / $3;| LPAREN expr RPAREN $ = $2;| MINUS expr $ = -$2;| NUM $ = $1; | expr OR expr $=panduan($1*$1+$3*$3); | expr AND expr $=panduan($1*$3); | NOT expr $=panduan2($2);%int main()yyparse();return 0;Cal.l文件:%#include "cal.tab.h"#include <stdio.h> int yywrap(void) return 1;#define

23、 LT1#defineLE2#define GT3#defineGE4#defineEQ5#define NE6#define PROGRAM7#define END13#define VAR9#define IF10#define THEN 11#define ELSE 12#define WHILE18#defineDO19#define ID 20#define RELOP 22#define NEWLINE 23#define ERRORCHAR 24%ws t+digit 0-9inumdigit+fnum digit*.digit+letterA-Za-zid_|letter(le

24、tter|digit)*%inum sscanf(yytext, "%lf", &yylval); return NUM;fnumsscanf(yytext, "%lf", &yylval); return NUM;"+"return PLUS;"*"return TIMES;"-"return MINUS;"/"return DIVIDE;"("return LPAREN;")"return RPAREN;"

25、or" return OR;"and" return AND;"not" return NOT;"<"return LT;"<="return LE;">"return GT;">="return GE;"=" return EQ;"!=" return NQ;":=" return FZ;ws;"n"return ENTER;. printf("nLE

26、X:ERROR! c=%sn", yytext);<INITIAL>"/*"BEGIN COMMENT;ECHO;<COMMENT>"*/"BEGIN INITIAL;ECHO;<INITIAL>whilereturn (WHILE);<INITIAL>do return (DO);<INITIAL>PROGRAM return (PROGRAM);<INITIAL>end return (END);<INITIAL>VAR return (VAR);<I

27、NITIAL>if return (IF);<INITIAL>then return (THEN);<INITIAL>else return (ELSE);<INITIAL>id return (ID);%int panduan(double a)if(a!=0) a=1;return a;int panduan2(double a)if(a=0) a=1;else if(a!=0) a=0;return a;int shuchu(double a)if(a=0)printf("false");else if (a!=0)print

28、f("true");return 1;运行程序:实验4:用Yacc设计语法分析器1实验目的:学习如何使用Yacc设计一个语法分析器,并与用lex写的词法分析器链接起来。实验内容:使用yacc为课程设计实验1所给的语言写一个语法分析器(你可以重新设计该语言的文法,但不能改变语言)。其中,词法分析使用课程设计实验2中已完成的词法分析器(即,你需要将本实验的语法分析器和实验2的词法分析器链接起来)。实验要求:输入为实验1所给语言写的源程序文件;输出为屏幕显示语法分析是否成功。在语法分析中不能出现任何的冲突(移进-归约或归约-归约冲突),或者虽然有冲突,但是你能够说清楚冲突是如何解

29、决的。在cygwin下用flex,bison和gcc工具将实验调试通过,并且你写的语法分析器至少应该能通过例子parser0中testcases目录下的test0.p和test1.p两个测试例的测试。实验参考:可以在例子parser0的基础上进行修改;如果你尚不能将实验2的词法分析器和本实验的语法分析器链接起来,可以暂时使用parser0给出的词法分析器(前提是你的语法分析器中终结符名的定义与parser0的相同)。程序代码:Cal.y%int yylex(); #define YYSTYPE double /* 将Yacc栈定义为double类型 printf("nThe valu

30、e of the expression is %lf.n", $1);*/%token NUM LPAREN RPAREN ENTER %left OR%left AND%right NOT%left PLUS MINUS%left TIMES DIVIDE END%right UMINUS BEGIN VAR %nonassoc PROGRAM%union int inum; double fnum; char * id;% /* 这样写prog可以让分析器每次读入一行进行分析,下一行重新分析expr prog : prog exprp | exprp ;exprp : expr

31、ENTER printf("1 表示 true;0 表示 false %lf.n", $1);shuchu($1); ;expr : expr PLUS expr$ = $1 + $3;| expr MINUS expr $ = $1 - $3;| expr TIMES expr $ = $1 * $3;| expr DIVIDE expr $ = $1 / $3;| LPAREN expr RPAREN $ = $2;| MINUS expr $ = -$2;| NUM $ = $1; | expr OR expr $=panduan($1*$1+$3*$3); | ex

32、pr AND expr $=panduan($1*$3); | NOT expr $=panduan2($2);*/prog : PROGRAM biaoshifu fenpro |fenpro |biaoshifu ;biaoshifu:ID ;fenpro :blsm BEGIN yjb END |blsm printf("BEGIN n "); |yjb printf("END n"); ;blsm: VAR blsmb printf("VAR"); |blsmb ;blsmb:blb MH leixing |blb MH le

33、ixing blsmb |blb |leixing ;leixing:INTEGER printf("INTEGER"); |REAL printf("REAL"); ;blb:bl$ = $1; |bl DH blb ;bl:NUM $ = $1; ;yjb:yj |yj yjb ;yj:fzyj |tjyj |whileyj |fhyj ;fzyj:bl FZ bds $ = $3; |bl |bds ;bds:guanxi $ = $1; |suanshu $ = $1; ;tjyj:IF guanxi THEN yj ELSE yj |guanx

34、i |yj ;whileyj:WHILE guanxi DO yj printf("WHILE"); |guanxiprintf("DO"); |yj ;fhyj:BEGIN yjb ENDprintf("BEGIN"); |yjb printf("END"); ;suanshu:xiang |suanshu PLUS suanshu $ = $1 + $3; |suanshu MINUS xiang$ = $1 - $3; ;xiang:yinshi |xiang*yinshi$ = $1 * $3; |xina

35、g/yinshi$ = $1 / $3; ;yinshi:bl$ = $1; |NUM$ = $1; |LPAREN suanshu RPAREN $ = $2; ;guanxi:suanshu LT suanshu $=bijiao1($1,$3); |suanshu GT suanshu $=bijiao2($1,$3); |suanshu LQ suanshu $=bijiao3($1,$3); |suanshu GQ suanshu $=bijiao4($1,$3); |suanshu EQ suanshu $=bijiao5($1,$3); |suanshu NQ suanshu $

36、=bijiao6($1,$3); ;%int main()yyparse();return 0;Cal.l%#include "cal.tab.h"#include <stdio.h> int yywrap(void) return 1;#define LT1#defineLE2#define GT3#defineGE4#defineEQ5#define NE6#define IF10#define THEN 11#define ELSE 12#define WHILE18#defineDO19#define ID 20#define RELOP 22#defi

37、ne NEWLINE 23#define ERRORCHAR 24%ws t+digit 0-9inumdigit+fnum digit*.digit+letterA-Za-zid_|letter(letter|digit)*%s COMMENT%inum sscanf(yytext, "%lf", &yylval); return INUM;fnumsscanf(yytext, "%lf", &yylval); return FNUM;"+"return PLUS;"*"return TIMES;

38、"-"return MINUS;"/"return DIVIDE;"("return LPAREN;")"return RPAREN;"or" return OR;"and" return AND;"not" return NOT;"<"return LT;"<="return LE;">"return GT;">="return GE;"=&

39、quot; return EQ;"!=" return NQ;":=" return FZ;":" return MH;"," return DH;"" teturn FH;ws;"n"return ENTER;. printf("nLEX:ERROR! c=%sn", yytext);<INITIAL>"/*"BEGIN COMMENT;ECHO;<COMMENT>"*/"BEGIN INI

40、TIAL;ECHO;<INITIAL>whilereturn (WHILE);<INITIAL>do return (DO);<INITIAL>PROGRAM return (PROGRAM);<INITIAL>end return (END);<INITIAL>VAR return (VAR);<INITIAL>if return (IF);<INITIAL>then return (THEN);<INITIAL>else return (ELSE);<INITIAL>id retur

41、n (ID);%int panduan(double a)if(a!=0) a=1;return a;int panduan2(double a)if(a=0) a=1;else if(a!=0) a=0;return a;int shuchu(double a)if(a=0)printf("false");else if (a!=0)printf("true");return 1;int bijiao1(double a,double b)if(a<b)return 1;else return -1;int bijiao2(double a,do

42、uble b)if(a>b)return 1;else return -1;int bijiao3(double a,double b)if(a<=b)return 1;else return -1;int bijiao4(double a,double b)if(a>=b)return 1;else return -1;int bijiao5(double a,double b)if(a=b)return 1;else return -1;int bijiao6(double a,double b)if(a!=b)return 1;else return -1;实验5:用Y

43、acc设计语法分析器2实验目的:学习如何使用Lex和Yacc设计一个语法分析器,并学习如何在语法分析的同时生成分析树。实验内容:修改实验4,给产生式加上动作,动作为生成一棵语法分析树。这棵分析树的结构可以使用或参照例子parser1中ast.h文件中定义的分析树结构。实验要求:输入为实验1所给语言写的源程序文件;输出为一棵语法分析树,这棵语法分析树的表示方法可以是这样两种:1.将分析树的数据结构打印出来;2.按分析树的结构输出一个C语言源程序文件(即输入是所给语言的源程序文件,输出为语义相同的C语言源程序文件)。在cygwin下用flex,bison和gcc工具将实验调试通过,并且你写的语法分

44、析器至少应该能通过例子parser1中testcases目录下的test0.p和test1.p两个测试例。实验参考:可以参考例子parser1或在它的基础上进行修改;如果你尚不能将实验2的词法分析器和本实验的语法分析器链接起来,可以暂时使用parser1给出的词法分析器(前提是你的语法分析器中终结符名的定义与parser1的相同)。你也可以在自己的语法分析器中直接使用parser1已经提供的输出方式(打印分析树的数据结构),但前提是你必须使用parser1提供的分析树结构(ast.h)。程序代码:%#include <stdio.h>#include "ast.h&quo

45、t; /该文件定义了抽象语法树(分析树)的数据结构#include "errormsg.h"#define YYDEBUG 1 /* 允许跟踪错误,与%debug功能相同 */int yylex(void); /* function prototype */* 该函数显示错误信息s,显示时包含了错误发生的位置。*/void yyerror(char *s) EM_error(EM_tokPos, "%s", s);/* 存放抽象语法树中 "程序" 数据结构的变量 */a_prog program = NULL;% /* 定义属性值栈的

46、类型,实验8需要修改此处 */%union int ival;double fval;string sval; a_exp exp; a_bexp bexp; a_stm_list stms; a_prog prog; a_dec_list decl; /* 定义各个终结符,以及他们的属性值的类型,实验8需要修改此处 */%token <sval> ID /* id */%token <ival> INT /*整型数*/%token <fval> FLOAT /*浮点数*/%token INTEGER REAL /*两种类型名:整型、实型*/%token C

47、OMMA COLON SEMICOLON LPAREN RPAREN PERIOD /* 符号 , : ; ( ) . */ PROGRAM BEGINN END VAR IF WHILE DO /* 关键字:PROGRAM BEGIN END VAR IF WHILE Do */ THEN ELSE /* 关键字:THEN ELSE */ ASSIGN EQ NEQ LT LE GT GE /* 符号 := = <> < <= > >= */ PLUS MINUS TIMES DIVIDE /* 符号 + = * / */%start program /*

48、 定义各个非终结符的属性值类型,实验8需要修改此处 */%type <prog> program%type <decl> bianliangbiao declist vardec%type <stms> fuhe xunhuan tiaojian fuzhi yuju stmts%type <exp> exp yinshi xiang suanshu %type <bexp> guanxi%program:PROGRAM ID SEMICOLON vardec BEGINN stmts END PERIODprogram = A_Prog(EM_tokPos, $2, $4, $6);vardec : VAR declist $ = $2;declist : bianliangbiao COLON INTEGER SEMICOLON $ = A_DecLi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论