编译原理课程设计简单编译器的设计与实现

上传人:1666****666 文档编号:37927837 上传时间:2021-11-05 格式:DOC 页数:17 大小:125.02KB
收藏 版权申诉 举报 下载
编译原理课程设计简单编译器的设计与实现_第1页
第1页 / 共17页
编译原理课程设计简单编译器的设计与实现_第2页
第2页 / 共17页
编译原理课程设计简单编译器的设计与实现_第3页
第3页 / 共17页
资源描述:

《编译原理课程设计简单编译器的设计与实现》由会员分享,可在线阅读,更多相关《编译原理课程设计简单编译器的设计与实现(17页珍藏版)》请在装配图网上搜索。

1、枣 庄 学 院计算机科学系课程设计任务书题 目: 简单编译器的设计与实现 姓 名: 学 号: 200912010128 年 级: 09级3+2班 专 业: 计算机科学与技术 指导教师: 职 称: 枣庄学院计算机科学系2010年12月2日课程设计的具体要求:在学习程序设计语言编译原理课程过程中,结合各章节构造编译程序的基本理论分别完成词法分析器、语法分析器和语义分析器实验,在基本实验完成的基础上,逐步完成课程设计。针对自己的理解和学习,实现一个小编译器包括符号表的构造,词法分析,语法分析,目标代码生成等重要子程序(其中词法分析、语法分析及语义分析功能必须完成),并对其进行分析解释和总结,同时将理

2、论与实际应用结合起来,接受软件设计等开发过程的全面训练,从而提高软件开发的能力。样本语言为C-语言,实现简单的编译器,其中基本的语句要求必须实现,其余部分可根据自己的实际情况选择实现。对主要代码给予解释和理解注释,各函数和过程应有简要描述,有功能说明,有入口和出口参数说明。 指导教师:_ 时间:_指导教师评语:成绩:_ 指导教师:_ 时间:_所需实验环境、设备: Windows XP操作系统、WIN-TC操作平台课程设计的具体安排: 2010年11月20日2010年11月22日,整理资料,准备材料 2010年11月23日2010年11月25日,编写代码,实现功能 2010年11月26日2010

3、年11月30日,调试,修改,完善 2010年11月31日,上交作业老师验收。 参考文献:1程序设计语言编译原理,陈火旺编著,国防工业出版社2编译原理,吕映芝、张素琴、蒋维杜编著,清华大学出版社3编译原理,Alfred V.Aho等,李建中译,机械工业出版社 简单编译器的设计与实现一、 课程设计的目的 在学习程序设计语言编译原理课程过程中,结合各章节构造编译程序的基本理论分别完成词法分析器、语法分析器和语义分析器实验,在基本实验完成的基础上,逐步完成课程设计。针对自己的理解和学习,实现一个小编译器括符号表的构造,词法分析,语法分析,目标代码生成等重要子程序,其中词法分析、语法分析及语义分析功能必

4、须完成),并对其进行分析解释和总结,同时将理论与实际应用结合起来,接受软件设计等开发过程的全面训练,从而提高软件开发的能力。二、 课程设计的任务(1)设计符号表确定符号表的组织方式,一般应包括名字栏和信息栏,其中名字栏作为关键字。要考虑能够存储有关名字的信息,并可以高效地完成如下操作:a.查找:根据给定的名字,在符号表中查找其信息。如果该名字在符号表中不存在,则将其加入到符号表中,否则返回指向该名字的指针;b.删除:从符号表中删除给定名字的表项。(2)设计词法分析器设计各单词的状态转换图,并为不同的单词设计种别码。将词法分析器设计成供语法分析器调用的子程序。功能包括:a. 具备预处理功能。将不

5、翻译的注释等符号先滤掉,只保留要翻译的符号串,即要求设计一个供词法分析调用的预处理子程序;b. 能够拼出语言中的各个单词;c. 将拼出的标识符填入符号表;d. 返回(种别码, 属性值)。(3)语法分析器要求用预测分析法、递归下降分析法、算符优先分析法、SLR分析法(几种方法任选),实现对表达式、各种说明语句、控制语句进行语法分析。(4)目标代码生成器能完成指定寄存器个数的情况下将一中间代码程序段翻译成汇编语言目标代码(汇编指令应包括加、减、乘、除),要求指令条数最少的情况下,尽量使用寄存器,尽量少访问内存,这样才能做到运行效率高。三、课程设计要求样本语言为C-语言,实现简单的编译器,其中基本的

6、语句要求必须实现,其余部分可根据自己的实际情况选择实现。对主要代码给予解释和理解注释,各函数和过程应有简要描述,有功能说明,有入口和出口参数说明。四、 简单编译器的实现流程图源程序出错处理表格管理词法分析器 单词符号 语法分析器语法单位 语义分析与中间代码产生器中间代码 优化器中间代码 目标代码生成器目标代码 五、 实现环境Windows XP操作系统、win-TC运行环境六、课程设计的详细过程(1) 设计词法分析器设计思想:要求:1. 对单词的构词规则有明确的定义;2. 编写的分析程序能够正确识别源程序中的单词符号;3. 识别出的单词以的形式保存在符号表中;4. 词法分析中源程序的输入以.c

7、格式,分析后的符号表保存在.txt文件中。5. 对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析;6. 输入:由符合规定单词类别结构的各类单词组成的源程序。实现方法:根据加入语义过程的状态转换图直接编写词法分析程序。根据每一组状态转换关系(标识符)组织程序结构,并将所有公共处理过程分别实现即可。在扫描源程序字符串时,一旦识别出关键字、运算符、标识符、无符号常数中之一,即以二元式形式(类别编码,值)输出单词。每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词。实现过程及主要代码:定义主要函数: char prog80=0, token

8、8; char ch;int syn,n,sum,m,p; char *rwtab6=begin,if,then,while,do,end;实现函数代码:扫描功能:void scaner() m=0;sum=0; for(n=0;n8;n+) tokenn=0;ch=progp+; while(ch= ) ch=progp+; if(isalpha(ch) while(isalpha(ch)|isdigit(ch) tokenm+=ch; ch=progp+; tokenm+=0; ch=progp-; syn=10; for(n=0;n6;n+) if(strcmp(token,rwtabn

9、)=0) syn=n+1;break; Else if(isdigit(ch) while(isdigit(ch) sum=sum*10+ch-0; ch=progp+; ch=progp-; syn=11; else switch(ch) case:m=0;tokenm+=ch;ch=progp+; if(ch=) syn=24; tokenm+=ch; else syn=23; ch=progp-; break; case:m=0;tokenm+=ch;ch=progp+; if(ch=) syn=18; tokenm+=ch; else syn=17; ch=progp-; break;

10、 case+:syn=13;token0=ch;break; case-:syn=14;token0=ch;break; case*:syn=15;token0=ch;break; case/:syn=16;token0=ch;break; case=:syn=25;token0=ch;break; case;:syn=26;token0=ch;break; case(:syn=27;token0=ch;break; case):syn=28;token0=ch;break; case#:syn=0;token0=ch;break; default:syn=-1;主函数:main() prin

11、tf(nnThe significance of the figures:n 1.figures 1 to 6 said Keywordn 2.figures 10 and 11 said Other indicatorsn 3.figures 13 to 28 said Operatorsn); p=0;printf(nplease input string:n); do ch=getchar(); progp+=ch; while(ch!=#);p=0;do scaner(); switch(syn)case 11: printf(%d,%d)n,syn,sum);break;case -

12、1: printf(n ERROR;n);break;default: printf(%d,%s)n,syn,token); while(syn!=0); getch();(2)设计语法、语义分析器设计思想:要求:1. 对语法规则有明确的定义;2. 编写的分析程序能够对实验一的结果进行正确的语法分析;3编写的分析程序能够对实验二的结果进行正确的语义分析;4对于遇到的语法、语义错误,能够做出简单的错误处理,给出简单的错误提示,保证语义分析过程;实现方法: 在词法分析识别出单词符号的基础上分析并规定程序的语法结构是否符合语法规则。其工作本质就是按文法的产生式,识别输入符号串是否为一个句子。首先定义

13、语法规则,然后按照规则实现语法分析。实现过程及主要代码: 插入符号表动作name-defn, t的程序如下:int name_def(char *name) int i,es=0; if (fhbp=maxfhbp) return(-1);for(i=fhbp-1;i=0;i-)/查符号表 if (strcmp(fhbi.name,name)=0) es=21;/21表示变量重复声明break; if (es=21) return(es);strcpy(fhbfhbp.name,name);fhbfhbp.address=datap;datap+;/分配一个单元,数据区指针加1fhbp+;re

14、turn(es); 查询符号表返回地址:int lookup(char *name,int *paddress) int i,es=0; for(i=0;ifhbp;i+) if (strcmp(fhbi.name,name)=0) *paddress=fhbi.address; return(es); es=23;/变量没有声明 return(es); 语法、语义分析及代码生成程序:int TESTparse() int es=0;if(fp=fopen(bbb.t,r)=NULL) printf(n打开%s错误!n,Scanout); es=10;return(es); /printf(请

15、输入目标文件名(包括路径):); /scanf(%s,Codeout);if(fout=fopen(ccc.t,w)=NULL) printf(n创建%s错误!n,Codeout); es=10; return(es); if (es=0) es=program();printf(=语法、语义分析及代码生成程序结果=n);switch(es) case 0: printf(语法、语义分析成功并抽象机汇编生成代码!n);break;case 10: printf(打开文件 %s失败!n,Scanout);break;case 1: printf(缺少!n);break;case 2: print

16、f(缺少!n);break;case 3: printf(缺少标识符!n);break;case 4: printf(少分号!n);break;case 5: printf(缺少(!n);break;case 6: printf(缺少)!n);break;case 7: printf(缺少操作数!n);break;case 21: printf(符号表溢出!n);break;case 22: printf(变量重复定义!n);break;case 23: printf(变量未声明!n);break; fclose(fp); fclose(fout);return(es); 定义语义规则并实现:

17、:=program:=int program() int es=0,i; fscanf(fp,%s %sn,token,token1); printf(%s %sn,token,token1); if(strcmp(token,) /判断是否 es=1; return(es); fscanf(fp,%s %sn,&token,&token1); printf(%s %sn,token,token1); es=declaration_list(); if (es0) return(es); printf( 符号表n); printf( 名字 地址n); for(i=0;i0) return(es

18、); if(strcmp(token,)/判断是否 es=2; return(es); fprintf(fout, STOPn);/产生停止指令 return(es);:=|/:=/|/改成:=int declaration_list() int es=0;while (strcmp(token,int)=0) es=declaration_stat();if (es0) return(es); return(es); :=int ;/fhbp,datap,codep -int IDnname-defn,t;int declaration_stat() int es=0; fscanf(fp,

19、%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,ID)return(es=3); /不是标识符es=name_def(token1);/插入符号表if (es0) return(es);fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,;) )return(es=4);fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1); return

20、(es);:=|/:=|/改成:=int statement_list() int es=0;while (strcmp(token,) es=statement();if (es0) return(es); return(es); :=|/ |/:= |/ | |int statement() int es=0;if (es=0 & strcmp(token,if)=0) es=if_stat();/if (es=0 & strcmp(token,while)=0) es=while_stat();/if (es=0 & strcmp(token,for)=0) es=for_stat();

21、/可在此处添加do语句调用if (es=0 & strcmp(token,read)=0) es=read_stat();/if (es=0 & strcmp(token,write)=0) es=write_stat();/if (es=0 & strcmp(token,)=0) es=compound_stat();/if (es=0 & (strcmp(token,ID)=0|strcmp(token,NUM)=0) es=expression_stat();/return(es); := if () else /:= if () else if ()BRFlabel1 BRlabel2

22、 SETlabellabel1 else SETlabellabel2if ()BRFlabel1 BRlabel2 SETlabellabel1 else SETlabellabel2其中动作符号的含义如下 BRFlabel1 :输出 BRF label1, BRlabel2:输出 BR label2, SETlabellabel1:设置标号label1 SETlabellabel2:设置标号label2int if_stat()int es=0,label1,label2; /iffscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,to

23、ken1);if (strcmp(token,() return(es=5); /少左括号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=expression();if (es0) return(es);if (strcmp(token,) return(es=6); /少右括号label1=labelp+;/用label1记住条件为假时要转向的标号fprintf(fout, BRF LABEL%dn,label1);/输出假转移指令fscanf(fp,%s %sn,&token,&token1);printf(%

24、s %sn,token,token1);es=statement(); if (es0) return(es);label2=labelp+;/用label2记住要转向的标号fprintf(fout, BR LABEL%dn,label2);/输出无条件转移指令fprintf(fout,LABEL%d:n,label1);/设置label1记住的标号if (strcmp(token,else)=0)/else部分处理 fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=statement(); if (es0) ret

25、urn(es); fprintf(fout,LABEL%d:n,label2);/设置label2记住的标号return(es); :=while() /:= while () /*:=while SETlabellabel1() BRFlabel2 BRlabel1 SETlabellabel2:=while SETlabellabel1() BRFlabel2 BRlabel1 SETlabellabel2动作解释如下:SETlabellabel1:设置标号label1BRFlabel2 :输出 BRF label2,BRlabel1:输出 BR label1,SETlabellabel2

26、:设置标号label2*/int while_stat()int es=0,label1,label2; label1=labelp+;fprintf(fout,LABEL%d:n,label1);/设置label1标号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,() return(es=5); /少左括号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=expression();if (es0) retu

27、rn(es);if (strcmp(token,) return(es=6); /少右括号label2=labelp+;fprintf(fout, BRF LABEL%dn,label2);/输出假转移指令fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=statement();if (es0) return(es);fprintf(fout, BR LABEL%dn,label1);/输出无条件转移指令fprintf(fout,LABEL%d:n,label2);/设置label2标号return(es); :=w

28、rite ;/:=write ;/:=write OUT;/:=write OUT;/动作解释:/ OUT:输出 OUTint write_stat() int es=0;fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=expression();if (es0)return(es);if (strcmp(token,;) return(es=4); /少分号fprintf(fout, OUTn);/输出指令fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,to

29、ken1);return(es); :=read ;/:=read ID;/:=read ;/:=read IDn LOOKnd INSTId;/动作解释:/LOOKnd:查符号表n,给出变量地址d; 没有,变量没定义/IN:输出IN/STId:输出指令代码STI dint read_stat() int es=0,address;fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,ID) return(es=3); /少标识符es=lookup(token1,&address);if (e

30、s0) return(es);fprintf(fout, IN %dn,address);/输入指令fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,;) return(es=4); /少分号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);return(es); 程序实现以下规则:1、:=|(|=|=|=|!=) /:= |(|=|=|=|!=)/*:=|GT|LES|=GE|=LE|=EQ|!=NOTEQ:=|GT

31、|LES|=GE|=LE|=EQ|!=NOTEQ*/int bool_expr() int es=0;es=additive_expr();if(es0) return(es);if ( strcmp(token,)=0 | strcmp(token,=)=0 |strcmp(token,)=0 | strcmp(token,0) return(es);if ( strcmp(token2,)=0 ) fprintf(fout, GTn);if ( strcmp(token2,=)=0 ) fprintf(fout, GEn);if ( strcmp(token2,)=0 ) fprintf(

32、fout, LESn);if ( strcmp(token2,=)=0 ) fprintf(fout, LEn);if ( strcmp(token2,=)=0 ) fprintf(fout, EQn);if ( strcmp(token2,!=)=0 ) fprintf(fout, NOTEQn); return(es);2、:=()|/:=()| ID|NUM/:=()|nLOOKndLOADd / |iLOADIi/:=()| IDnLOOKndLOADd |NUMiLOADIiint factor() int es=0; if (strcmp(token,()=0) fscanf(fp

33、,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=expression();if (es0) return(es);if (strcmp(token,) return(es=6); /少右括号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1); else if (strcmp(token,ID)=0) int address;es=lookup(token1,&address);/查符号表,获取变量地址if (es0) return(es);/变量没声明fprint

34、f(fout, LOAD %dn,address);fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);return(es); if (strcmp(token,NUM)=0) fprintf(fout, LOADI %sn,token1);fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);return(es);else es=7;/缺少操作数return(es); return(es); (3)运行结果分析:输入:T-t|e|(F)F-T+F|TS-#T#输出:词法分析结果: 语法分析结果: 四 、课程设计小结通过对编译器的设计实现,一方面再次熟悉了c语言的编程方法及思想,另一方面加深了而对所学编译知识的掌握和理解,也深刻的理解了编译器的思想和实现方法;从词法分析到语法分析,再到语义分析,整个独立而又紧密联系的环节,紧紧相扣,整体的实现理解的更加透彻。五、参考资料程序设计语言编译原理,陈火旺编著,国防工业出版社编译原理,吕映芝、张素琴、蒋维杜编著,清华大学出版社编译原理,Alfred V.Aho等,李建中译,机械工业出版社

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


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