语法分析与中间代码生成-编译报告(共32页).doc

上传人:飞****2 文档编号:27102056 上传时间:2022-07-22 格式:DOC 页数:32 大小:248.50KB
返回 下载 相关 举报
语法分析与中间代码生成-编译报告(共32页).doc_第1页
第1页 / 共32页
语法分析与中间代码生成-编译报告(共32页).doc_第2页
第2页 / 共32页
点击查看更多>>
资源描述

《语法分析与中间代码生成-编译报告(共32页).doc》由会员分享,可在线阅读,更多相关《语法分析与中间代码生成-编译报告(共32页).doc(32页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、精选优质文档-倾情为你奉上编译原理综合训练专业计算机科学与技术学生姓名王海波班级B计算机094学号指导教师皋军完成日期2011年12月30日信息工程学院课程设计任务书课题名称编译原理课程设计完成时间2011.12.30指导教师皋军学生姓名王海波班级B计算机094总体设计要求题目:语法分析与中间代码产生器总体设计要求: 课程设计内容共给定4个题目,每个学生按照课程设计要求,在规定的一周时间内,选择一个独立完成涉及内容:语法分析生成中间代码课程设计成果1、课程设计报告书一份2、源程序清单一份3、成果使用说明书一份目录一、 课设要求用C语言对下述文法和单词表定义的语言设计编制一个编译器。(1)单词符

2、号及种别表单词符号种别编码单词值main1int 2float3double4char5if 6else 7do8while9l(l|d)*10内部字符串 ( +|-| ) d*(.dd* | )( e ( +|-| ) dd*|) 20二进制数值表示=21+22- 23* 24/ 25(26)272829,30;3132=3334=35=36!=37(2)语法结构定义 := main() := /程序用括号括起来:=;:=|:=ID= /赋值语句用”=”号:=if /条件怎么没有括号,囧(自己加1个):=do while := /没有布尔运算,还算简单 := +|- := *|/ :=ID|

3、num|()num:= ( +|-| ) 数字*(.数字数字* | )( e ( +|-| ) 数字数字*|)ID:=字母(字母|d数字)*字母:=a|b|c|z|A|B|C|Z数字:=0|1|2|9 := |=|=|!=二、 总体设计思想采用递归下降(自上而下)的语法制导翻译法。三、 详细算法设计在前两次试验的基础上改进。词法分析程序 语法分析程序 语义分析程序 编译器。不断完善,不断改进。渐变的过程。四、 流程框图图 I 主函数示意图图 II 递归下降分析程序示意图是否为main?调用scanner是否为(?调用scanner是否为)?调用scanner调用语句块分析函数staBlock出

4、错处理否否否图 III 语句块分析示意图是否为 ?调用scanner调用语句串分析函数staString调用scanner是否为 ?出错处理否否图 IV 语句串分析示意图调用语句分析函数sta回溯,调用backpatch是否为 ; ?调用scanner调用语句分析函数sta否出错处理图 V 语句分析示意图调用赋值语句分析函数fuzhi是否为 字符串?是否为 if ?调用条件语句分析函数tiaojian是否为 do ?调用循环语句分析函数xunhuan五、 函数相关说明1. 所有函数一览void scanner(); /扫描void lrparser(); void staBlock(int *

5、nChain); /语句块void staString(int *nChain); /语句串void sta(int *nChain); /语句void fuzhi(); /赋值语句void tiaojian(int *nChain); /条件语句void xunhuan(); /循环语句char* E(); /Expresiion表达式char* T(); /Term项char* F(); /Factor因子char *newTemp(); /自动生成临时变量void backpatch(int p,int t); /回填int merge(int p1,int p2); /合并p1和p2v

6、oid emit(char *res,char *num1,char *op,char *num2); /生成四元式2. void emit(char *res,char *num1,char *op,char *num2)该函数的功能是生成一个三地址语句送到四元式表中。void emit(char *res,char *num1,char *op,char *num2)strcpy(fourComq.result,res);strcpy(fourComq.arg1,num1);strcpy(fourComq.opera,op);strcpy(fourComq.arg2,num2);q+;四元

7、式表中的结构如下:structchar result10; /字符串(字符数组)char arg110; /操作数1char opera10; /运算符char arg210; /操作数2fourCom20; /结构体数组3. char *newTemp()该函数的功能是会动一个新的临时变量,临时变量名产生的顺序是T1,T2,T3,.char *newTemp()char *p;char varTemp10;p=(char *)malloc(10);kk+;itoa(kk,varTemp,10); /整数转换为字符串strcpy(p+1,varTemp);p0=T; /字符串前加T,便于识别r

8、eturn p;4. int merge(int p1,int p2)该函数的功能是将以P1,P2为链首的两条链合并成一条链,返回时的函数值作为合并后的链首。int merge(int p1,int p2) /合并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(fourCo

9、mcircle.result,%s,p1);/目的是用p1的值覆盖0return nResult; /p2是头,p1覆盖0,接在p2后边5. void backpatch(int p,int t)该函数的功能是把P所链接的每个四元式的第四区段(result段)都回填t。void backpatch(int p,int t) int w,circle=p;while(circle) /circle不为0的时候w=atoi(fourComcircle.result); /四元式circle第四分量内容/strcpy(fourComcircle.result,t); /把t填进四元式circle的第

10、四分量sprintf(fourComcircle.result,%d,t);circle=w; /w记录的是链条上下一个四元式,移动!return;6. void fuzhi()该函数的功能是对赋值语句进行分析。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);7. void tiaojian(int *nC

11、hain)该函数的功能是对条件语句进行分析。/-if()void tiaojian(int *nChain)char res10,num110,num210,op10;int nChainTemp;/-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,=);break;case 34:strcpy(op,);break;case 35:strcpy(op,=

12、);break;case 36:strcpy(op,=);break;case 37:strcpy(op,!=);break;default:printf(error);scanner();strcpy(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) /)scan

13、ner();staBlock(&nChainTemp); /语句块*nChain=merge(nChainTemp,nfc);8. void xunhuan()该函数的功能是对循环语句进行分析。/:=do while void xunhuan()char res10,num110,num210,op10;int nChainTemp;if(syn=8) /donnc=nextq; /记住if语句位置,emit之后nextq就变了/emit(0,if,num1,goto); scanner();staBlock(&nChainTemp); /语句块if(syn=9) /whilescanner(

14、);if(syn=26) /(scanner();strcpy(num1,E();if(syn=32) switch(syn)case 32:strcpy(op,);break;case 33:strcpy(op,=);break;case 34:strcpy(op,);break;case 35:strcpy(op,=);break;case 36:strcpy(op,=);break;case 37:strcpy(op,!=);break;default:printf(error);scanner();strcpy(num2,E();strcat(num1,op);strcat(num1,

15、num2);nnb=nextq;emit(0,if,num1,goto); backpatch(nnb,nnc);nna=nextq;emit(0,goto);backpatch(nna,nextq);if(syn=27) /)scanner();六、 编译器使用说明程序提示用户输入字符串“Please input your source string:”,用户输入字符串并以“#”号结束。回车后,程序显示运行结果。七、 心得与体会刚拿到课设题目的时候,感觉很难,没有头绪。虽然之前实验时候,词法分析程序和语法分析程序的代码都是自己一个一个敲的。但是记得那时的语法分析程序用的是递归下降分析法,而且

16、只判断输入串是否是文法的句子(输出只有简单的success或者error)。课设的要求呢?要加上语义分析,而且要输出四元式。好像语义分析的部分,我一点印象也没有了,老师那一部分上得有点快。“语义分析与中间代码生成”,我又一点一点的看。3天时间,终于可以写出语义程序了。但是后来发现,更难的东西在后边。程序语句有3种:赋值语句,条件语句,循环语句。而赋值语句的翻译,恰恰是最简单的。对于赋值语句的翻译,课本上有详细的讲解,有代码的简单举例。而对于条件语句(ifelse)和循环语句(dowhile),课本讲解不那么详细,没有代码举例,上课时候我也没太理解老师所讲解的。特别是其中链nChain的概念,一

17、直看不懂。因为这个困难,课设被我搁置了3天。而且好像没有预期中困难,可能是有条件语句的铺垫吧。他们的处理方法其实很类似,也是emit+backpatch+merge。而且由于老师给的语法中没有布尔表达式,所以很多merge的工作也可以省略了,嘿嘿。最后一步就是整合,系统测试,书写文档了。个人认为这次课设的机会非常宝贵,加深了我对编译器处理语言的过程的理解。我想,作为学软件的学生,不应该只会用Java,或者C+,或者C#。一门高级语言其实学起来是很容易的,而在校期间,这些计算机基础课程一定要学好!才能为将来打好基础。八、 源程序清单/*编译器*/*Erin*/*软件工程0801班*/*HUST*

18、/*#include#include#include#includechar prog80; /存放所有输入字符 char token8; /存放词组 char ch; /单个字符 int syn,p,m,n,i; /syn:种别编码 double sum; int count; int isSignal; /是否带正负号(0不带,1负号,2正号)int isError;int isDecimal; /是否是小数 double decimal; /小数 int isExp; /是否是指数 int index; /指数幂 int isNegative; /是否带负号 double temp; i

19、nt temp2;int repeat; /是否连续出现+,-int nextq;int kk; /临时变量的标号int ntc,nfc,nnc,nnb,nna;char *rwtab9=main,int,float,double,char,if,else,do,while; structchar result10; /字符串(字符数组)char arg110;char opera10;char arg210;fourCom20; /结构体数组void scanner(); /扫描void lrparser(); void staBlock(int *nChain); /语句块void sta

20、String(int *nChain); /语句串void sta(int *nChain); /语句void fuzhi(); /赋值语句void tiaojian(int *nChain); /条件语句void xunhuan(); /循环语句char* E(); /Expresiion表达式char* T(); /Term项char* F(); /Factor因子char *newTemp(); /自动生成临时变量void backpatch(int p,int t); /回填int merge(int p1,int p2); /合并p1和p2void emit(char *res,ch

21、ar *num1,char *op,char *num2); /生成四元式void main()p=0;count=0;isDecimal=0;index=0;repeat=0;kk=0;printf(nPlease input your source 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 %5s t%5s )n,fourComi.arg1,fourCom

22、i.opera,fourComi.arg2,fourComi.result);void lrparser()int nChain;nfc=ntc=1;nextq=1;if(syn=1) /mainscanner();if(syn=26) /(scanner();if(syn=27) /)scanner();staBlock(&nChain);elseprintf(缺少右括号n);else printf(缺少左括号n);elseprintf(缺少mainn);/ := void staBlock(int *nChain) /语句块if(syn=28) /scanner();staString(n

23、Chain);/backpatch(*nChain,nextq);if(syn=29) /scanner(); /读下一个elseprintf(缺少号n);elseprintf(缺少号n);/:=;void staString(int *nChain) /语句串sta(nChain);backpatch(*nChain,nextq);while(syn=31) /;scanner();sta(nChain);/backpatch(*nChain,nextq-1);void sta(int *nChain) /语句if(syn=10)fuzhi();/*nChain=0;else if(syn=

24、6) /iftiaojian(nChain);else if(syn=8) /doxunhuan();/-if()void tiaojian(int *nChain)char res10,num110,num210,op10;int nChainTemp;/-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,=);break;case 34:strcpy(o

25、p,);break;case 35:strcpy(op,=);break;case 36:strcpy(op,=);break;case 37:strcpy(op,!=);break;default:printf(error);scanner();strcpy(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链接的所

26、有四元式都回填nextqif(syn=27) /)scanner();staBlock(&nChainTemp); /语句块*nChain=merge(nChainTemp,nfc);/:=do while void xunhuan()char res10,num110,num210,op10;int nChainTemp;if(syn=8) /donnc=nextq; /记住if语句位置,emit之后nextq就变了/emit(0,if,num1,goto); scanner();staBlock(&nChainTemp); /语句块if(syn=9) /whilescanner();if(

27、syn=26) /(scanner();strcpy(num1,E();if(syn=32) switch(syn)case 32:strcpy(op,);break;case 33:strcpy(op,=);break;case 34:strcpy(op,);break;case 35:strcpy(op,=);break;case 36:strcpy(op,=);break;case 37:strcpy(op,!=);break;default:printf(error);scanner();strcpy(num2,E();strcat(num1,op);strcat(num1,num2)

28、;nnb=nextq;emit(0,if,num1,goto); backpatch(nnb,nnc);nna=nextq;emit(0,goto);backpatch(nna,nextq);if(syn=27) /)scanner();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() /

29、Expression表达式char *res,*num1,*op,*num2;res=(char *)malloc(10);num1=(char *)malloc(10);op=(char *)malloc(10);num2=(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,

30、res);return num1;char* T() /Term项char *res,*num1,*op,*num2;res=(char *)malloc(10);num1=(char *)malloc(10);op=(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,

31、num2);strcpy(num1,res);return num1;char* F() /Factor因子char *res;res=(char *)malloc(10);if(syn=10) /字符串strcpy(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 *new

32、Temp()char *p;char varTemp10;p=(char *)malloc(10);kk+;itoa(kk,varTemp,10);strcpy(p+1,varTemp);p0=T;return p;/将p所链接的每个四元式的第四个分量都回填tvoid backpatch(int p,int t) int w,circle=p;while(circle) /circle不为0的时候w=atoi(fourComcircle.result); /四元式circle第四分量内容/strcpy(fourComcircle.result,t); /把t填进四元式circle的第四分量sp

33、rintf(fourComcircle.result,%d,t);circle=w; /w记录的是链条上下一个四元式,移动!return;int merge(int p1,int p2) /合并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,char *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; m=0; for(n=0;n=a)&(ch=

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

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

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

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