编译原理简单编译器课程设计报告.pdf

上传人:叶*** 文档编号:36163332 上传时间:2022-08-25 格式:PDF 页数:29 大小:330.42KB
返回 下载 相关 举报
编译原理简单编译器课程设计报告.pdf_第1页
第1页 / 共29页
编译原理简单编译器课程设计报告.pdf_第2页
第2页 / 共29页
点击查看更多>>
资源描述

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

1、信息科学与工程学院课程设计任务书信息科学与工程学院课程设计任务书题目:一个简单编译器的设计与分析姓名:学号:专业班级:课程:编译原理指导教师:职称:讲师完成时间: 2011 年 12 月-2011 年 12 月枣庄学院信息科学与工程学院制2011 年 12 月 20 日1课程设计任务书及成绩评定课程设计任务书及成绩评定课程设计的任务和具体要求课程设计的任务和具体要求在理解编译原理相关理论的基础上,要求用 C 或 C+语言描述及上机调试,实现一个小编译器(包括符号表的构造,词法分析,语法分析,语义分析,目标代码生成等重要子程序, 其中词法分析、 语法分析及语义分析功能必须完成) ,使学生将理论与

2、实际应用结合起来,受到软件设计等开发过程的全面训练,从而提高学生软件开发的能力。指导教师签字:_日期:指导教师评语指导教师评语成绩:_指导教师签字:日期:2课程设计所需软件、硬件等课程设计所需软件、硬件等硬件环境:硬件环境:WindowsXP/Win7 操作系统软件环境:软件环境:Microsoft visual C+6.0课程设计进度计划课程设计进度计划起至日期起至日期工作内容工作内容备注备注2011-12-01052011-12-06102011-12-1116查找资料理清思路,编写程序完善程序,编辑文档参考文献、资料索引参考文献、资料索引序号文献、资料名称编著者出版单位【1】 程序设计语

3、言编译原理陈火旺 李春林国防工业出版社【2】 数据结构严蔚敏清华大学出版社【3】 C+程序设计吴乃林 况迎辉高等教育出版社【4】 C 语言程序设计谭浩强清华大学出版社【5】 程序设计语言编译原理陈火旺、刘春林等国防工业出版社3目录一、摘要错误错误!未定义书签。未定义书签。二、总体设计方案及主要设计原理错误错误!未定义书签。未定义书签。1、单词符号及种别表错误!未定义书签。2、语法结构定义错误!未定义书签。3、主要算法错误!未定义书签。(1)词法分析主要算法错误!未定义书签。(2)语法分析主要思想错误!未定义书签。(3)语义分析主要算法错误!未定义书签。三、源程序代码错误错误!未定义书签。未定义

4、书签。四、测试及分析错误错误!4未定义书签。未定义书签。五、 心得体会错误错误! 未未定义书签。定义书签。一、摘要编译程序的工作过程一般可以分为五个阶段:词法分析、语法分析、语义分析与中间代码产生、优化、目标代码生成。每一个阶段在功能上是相对独立的,它一方面从上一个阶段获取分析的结果来进行分析,另一方面由将结果传递给下一个阶段。由编译程序的五个阶段就对应了编译系统的结构。其中词法分析器利用超前搜索、状态转换等方法,将源程序转化成为一个一个的单词符号二元式。一般程序语言的单词符号包括关键字、运算符、常数、标识符和界符。语法分析器将这些单词符号作为输入,对它进行语法分析。语法分析分为两种方法:自上

5、而下分析法和自下而上分析法。针对不同程序语言的语法规则可以采取不同的分析方法,当然两种方法也可以同时使用。语法分析器把语法单元作为输入供语义分析器使用。一般的5语义分析器主要采用的是语法制导方法,即在语法分析的同时进行语法分析,并产生一定的语义动作,来生成中间代码。上面三个过程可以与硬件无关,而接下来的优化器和目标代码生成器是针对某一种处理器而言的。代码优化是将语义分析生成的中间代码进行优化,产生执行效率更高的代码。目标代码生成器最终生成可以在某种机器上运行的机器语言或者汇编语言。在整个编译过程中还包括对表格的操作和对错误的处理,这些也都是非常重要的环节。6下图给出了编译系统的结构框图二、总体

6、设计方案及主要设计原理表格管理出错处理单词符号语法单元中间代码中间代码目标代码语法分析器语义分析与中间代码生成器优化器目标代码生成器词法分析器72.1、单词符号及种别表示单词符号种别编码单词值main1int2float3double4char5if6else7do8while9l(l|d)*10内部字符串( +|-| ) d*(.dd* | )( e ( +|-| ) dd*|)20二进制数值表示=21+22-23*24/25(26)272829,30;3132=3334=35=36!=372.2、语法结构定义8 := main() := /程序用括号括起来:=;:=|:=ID=/赋值语句用

7、”=”号:=if/条件怎么没有括号,囧(自己加 1 个):=do while := := +|- := *|/ :=ID|num|()num:= ( +|-| ) 数字*(.数字数字*| )( e ( +|-| ) 数字数字*|)ID:=字母(字母|d 数字)*字母:=a|b|c|z|A|B|C|Z数字:=0|1|2|9 := |=|=|!=2.3、主要算法2.3.1、词法分析主要算法这部分对源文件进行分析,允许/*/注释。从源文件依次读取字符, 对字符进行分析, 组成字符串、 数字、 关系符等固定含义的 token符,并把它们添加到 token 链中,如果遇到非法字符报错并退出程序。2.3.

8、2、语法分析主要思想这部分对 Token 链进行分析,利用自底向上的分析方法,构建 SLR(1)分析表的过程是手工完成的。语法分析的同时构建语法树,移进时创建叶子,规约时创建节点。2.3.3、语义分析主要分析这部分对语法树从左到右进行遍历,节点记录了规约式的编号,遍历到节点时就进行相应处理。语义分析主要检查变量、函数是否被定义或重定义,同时产生四元式。三、源程序代码9#include#include#include#includechar prog80; /存放所有输入字符char token8; /存放词组char ch; /单个字符int syn,p,m,n,i;/syn:种别编码doub

9、le sum;int count;int isSignal; /是否带正负号(0 不带,1 负号,2 正号)int isError;int isDecimal; /是否是小数double decimal;/小数int isExp;/是否是指数int index;/指数幂int isNegative; /是否带负号double temp;int temp2;int repeat; /是否连续出现+,-int nextq;int kk; /临时变量的标号int ntc,nfc,nnc,nnb,nna;char*rwtab9=main,int,float,double,char,if,else,do

10、,while;structchar result10; /字符串(字符数组)char arg110;char opera10;char arg210;fourCom20; /结构体数组void scanner(); /扫描void lrparser();void staBlock(int *nChain); /语句块void staString(int *nChain); /语句串void sta(int *nChain); /语句void fuzhi(); /赋值语句void tiaojian(int *nChain); /条件语句void xunhuan(); /循环语句char* E()

11、; /Expresiion 表达式char* T(); /Term 项10char* F(); /Factor 因子char *newTemp(); /自动生成临时变量void backpatch(int p,int t); /回填int merge(int p1,int p2); /合并 p1 和 p2void emit(char *res,char *num1,char *op,char *num2); /生成四元式void main()p=0;count=0;isDecimal=0;index=0;repeat=0;kk=0;printf(nPlease input your sourc

12、e string:n);doch=getchar();progp+=ch;while(ch!=#);p=0;isError=0;scanner();lrparser();for(i=1;inextq;i+) /循环输出四元式printf(n%dt,i);printf(%5s%5s%5st%5s)n,fourComi.arg1,fourComi.opera,fourComi.arg2,fourComi.result);void lrparser()int nChain;nfc=ntc=1;nextq=1;if(syn=1) /mainscanner();if(syn=26) /(11scanne

13、r();if(syn=27) /)scanner();staBlock(&nChain);elseprintf(缺少右括号n);elseprintf(缺少左括号n);elseprintf(缺少 mainn);/ := void staBlock(int *nChain) /语句块if(syn=28) /scanner();staString(nChain);/backpatch(*nChain,nextq);if(syn=29) /scanner();/读下一个elseprintf(缺少号n);elseprintf(缺少号n);/:=;void staString(int *nChain) /

14、语句串sta(nChain);backpatch(*nChain,nextq);while(syn=31) /;scanner();sta(nChain);12/backpatch(*nChain,nextq-1);void sta(int *nChain) /语句if(syn=10)fuzhi();/*nChain=0;else if(syn=6) /iftiaojian(nChain);else if(syn=8) /doxunhuan();/-if()void tiaojian(int *nChain)char res10,num110,num210,op10;int nChainTem

15、p;/-if(syn=6) /ifscanner();/strcpy(num1,E();if(syn=26) /(scanner();strcpy(num1,E();if(syn=32)switch(syn)case 32:strcpy(op,);break;case 33:strcpy(op,=);13break;case 34:strcpy(op,);break;case 35:strcpy(op,=);break;case 36:strcpy(op,=);break;case 37:strcpy(op,!=);break;default:printf(error);scanner();s

16、trcpy(num2,E();strcat(num1,op);strcat(num1,num2);/nfc=nextq+1;ntc=nextq; /记住 if 语句位置emit(0,if,num1,goto);nfc=nextq; /if 中表达式为假emit(0,goto);/第一个 0 已回填backpatch(ntc,nextq); /ntc 链接的所有四元式都回填 nextqif(syn=27)/)scanner();staBlock(&nChainTemp); /语句块*nChain=merge(nChainTemp,nfc);/:=do while void xunhuan()ch

17、ar res10,num110,num210,op10;14int nChainTemp;if(syn=8) /donnc=nextq; /记住 if 语句位置,emit 之后 nextq 就变了/emit(0,if,num1,goto);scanner();staBlock(&nChainTemp); /语句块if(syn=9) /whilescanner();if(syn=26) /(scanner();strcpy(num1,E();if(syn=32)switch(syn)case 32:strcpy(op,);break;case 33:strcpy(op,=);break;case

18、 34:strcpy(op,);break;case 35:strcpy(op,=);break;case 36:strcpy(op,=);break;case 37:strcpy(op,!=);break;default:printf(error);15scanner();strcpy(num2,E();strcat(num1,op);strcat(num1,num2);nnb=nextq;emit(0,if,num1,goto);backpatch(nnb,nnc);nna=nextq;emit(0,goto);backpatch(nna,nextq);if(syn=27)/)scanne

19、r();void fuzhi() /赋值语句只有 1 个操作数char res10,num10; /num 操作数if(syn=10) /字符串strcpy(res,token); /结果scanner();if(syn=21) /=scanner();strcpy(num,E();emit(res,num,=,);elseprintf(缺少=号n);char* E() /Expression 表达式16char *res,*num1,*op,*num2;res=(char *)malloc(10);num1=(char *)malloc(10);op=(char *)malloc(10);n

20、um2=(char *)malloc(10);strcpy(num1,T();while(syn=22)|(syn=23) /+ -if(syn=22) /+strcpy(op,+);elsestrcpy(op,-);scanner();strcpy(num2,T();strcpy(res,newTemp();emit(res,num1,op,num2);strcpy(num1,res);return num1;char* T() /Term 项char *res,*num1,*op,*num2;res=(char *)malloc(10);num1=(char *)malloc(10);op

21、=(char *)malloc(10);num2=(char *)malloc(10);strcpy(num1,F();while(syn=24)|(syn=25) /* /if(syn=24)strcpy(op,*);elsestrcpy(op,/);scanner();strcpy(num2,F();strcpy(res,newTemp();emit(res,num1,op,num2);strcpy(num1,res);return num1;17char* F() /Factor 因子char *res;res=(char *)malloc(10);if(syn=10) /字符串strc

22、py(res,token);scanner();else if(syn=20) /二进制数itoa(int)sum,res,10); /整数转换为字符串scanner();else if(syn=26) /(scanner();res=E();if(syn=27) /)scanner();else isError=1;elseisError=1;return res;char *newTemp()char *p;char varTemp10;p=(char *)malloc(10);kk+;itoa(kk,varTemp,10);strcpy(p+1,varTemp);p0=T;return

23、p;/将 p 所链接的每个四元式的第四个分量都回填 tvoid backpatch(int p,int t)18int w,circle=p;while(circle) /circle 不为 0 的时候w=atoi(fourComcircle.result); /四元式 circle 第四分量内容/strcpy(fourComcircle.result,t); /把 t 填进四元式 circle 的第四分量sprintf(fourComcircle.result,%d,t);circle=w; /w 记录的是链条上下一个四元式,移动!return;int merge(int p1,int p2

24、) /合并 p1 和 p2char circle,nResult;if(p2=0)nResult=p1;elsenResult=circle=p2;while(atoi(fourComcircle.result) /四元式第四个分量不为 0circle=atoi(fourComcircle.result);/strcpy(fourComcircle.result,p1);sprintf(fourComcircle.result,%s,p1);/目的是用 p1 的值覆盖 0return nResult; /p2 是头,p1 覆盖 0,接在 p2 后边void emit(char *res,cha

25、r *num1,char *op,char *num2)strcpy(fourComnextq.result,res);strcpy(fourComnextq.arg1,num1);strcpy(fourComnextq.opera,op);strcpy(fourComnextq.arg2,num2);nextq+;void scanner()sum=0;decimal=0;19m=0;for(n=0;n=a)&(ch=A)&(ch=a)&(ch=A)&(ch=0)&(chtokench=progp+; /读下一个字符tokenm+=0;p-; /回退一格syn=10; /标识符/如果是beg

26、in,if,then,while,do,end标识符中的一个for(n=0;n=0)&(ch=0)&(ch=0)&(ch=0)&(ch=9)/指数index=index*10+ch-0;ch=progp+;/10 的幂/123e3 代表 123*10(3)/sum=sum*pow(10,index);是错误的if(isNegative)sum=sum*pow(0.1,index);elsesum=sum*pow(10,index);if(isSignal=1)sum=-sum;21isSignal=0;p-;syn=20;else switch(ch)case :m=0;tokenm+=ch;

27、ch=progp+;if(ch=)syn=33;tokenm+=ch;elsesyn=32;p-;break;case =:m=0;tokenm+=ch;ch=progp+;22if(ch=)syn=36;tokenm+=ch;elsesyn=21;p-;break;case +:temp2=progp;tokenm+=ch;if(temp2=0)&(temp2=0)&(temp2=9)&(repeat=1)isSignal=1;ch=progp+; /读“-”下一个字符23repeat=0;goto IsNum;/转到数字的识别if(temp2=+)|(temp2=-)&(repeat=0)

28、/如果重复出现符号,才将后边的+,-视为正负号repeat=1;/预言会重复/ch=progp+;/读下一个字符syn=23;break;case *:temp2=progp;tokenm+=ch;if(temp2=+)isSignal=2;repeat=1;else if(temp2=-)isSignal=1;repeat=1;syn=24;break;case /:syn=25;tokenm+=ch;break;case (:temp2=progp;tokenm+=ch;if(temp2=+)isSignal=2;repeat=1;else if(temp2=-)24isSignal=1;

29、repeat=1;syn=26;break;case ):syn=27;tokenm+=ch;break;case :syn=28;tokenm+=ch;break;case :syn=29;tokenm+=ch;break;case ,:syn=30;tokenm+=ch;break;case ;:syn=31;tokenm+=ch;break;case#:syn=0;tokenm+=ch;break;default:syn=-1;四、测试及分析25运行程序,结果如下:先输入正确的程序26再输入错误的程序五、心得体会27本次编译原理词法分析器的系统开发使我对词法分析有了进一步的认识,也对编译原理这门课程的了解更加深入,要想学好它重在实践。通过此次手动构造词法分析,我认识到做程序设计并不是只掌握词法分析的思想和方法就够的,一定得自己动手,这样才能充分认识到自己的不足,以提高自己的设计能力。通过实践,我发现自身还有许多不足之处,我深刻认识到要学好计算机必须重视实践,所以在以后的学习过程中,我会更加注视上机操作,使自己更好地学好专业知识。回顾此次编译原理课程设计,可以说得是苦多于甜,但是我在巩固了以前所学过知识的同时,也学到了很多在已开设课程中未学到的知识。只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正提高自己的实际动手能力和独立思考的能力。

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

当前位置:首页 > 应用文书 > 公文通知

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

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