版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、汕头大学 08计算机科学与技术 编译原理实验报告 编译原理实验报告 一实验目的:熟练掌握PLO语言编译程序的结构和功能;二实验要求: 扩充PLO语言的功能,增加for语句和case语句;已知for语句和case语句的语法如下: <for语句>:=for(赋值语句;关系表达式) do <语句> <关系表达式>:=<表达式><关系运算符><表达式> <case语句>:=<case><标识符>:<常量>:<语句>endcase .3. 实验环境与工具:(1)计算机及操作
2、系统:WindowsXP(2)程序设计语言:C(3)编译程序:PL/0 (4)实现工具(平台):VC+6.04 设计方案:1. 概述: 源语言:pl0 目标语言:类pcode代码 实现工具(平台):VC+6.02. 结构设计说明: PlO所有子程序如下:过程或函数名简要功能说明main初始化编译环境,建立关键字表,调用分程序Block对源文件进行编译,当编译正确时,自动调用解释执行程序,对目标代码进行解释执行。error出错处理,打印出错位置和错误性质编号。并在信息栏输出错误信息。getch过滤空格,读取一个字符getsym词法分析,读取一个单词gen生成目标代码(类pcode代码),并送入目
3、标程序区。test测试当前单词是否是合法block分程序分析处理过程。enter登录过程说明对象包括变量、常量和过程名的属性信息到符号表。position查找标识符在符号表中的位置。constdeclaration常量定义处理,收集常量信息并登录到符号表。vardeclaration变量定义处理,收集变量信息并登录到符号表。listcode列出目标代码清单。statement语法分析,语句部分处理。expression表达式分析处理。term项分析处理过程。factor因子分析处理。condition条件处理。interpret对目标代码进行解析执行。Base通过静态链求数据区首地址。3. 增
4、加for语句:(1) 设计思想:For语句的语法分析:<for语句>:=for(赋值语句;关系表达式) do <语句>do;:=条件表达式identfor语句设计思路:主要分为两部分模块:一,for和;之间的赋值语句处理;二,条件语句处理和最后的语句处理。首先获取赋值号左边的标识符,从符号表中找到它的信息,并确认这个标识符确为变量名。然后通过调用表达式处理过程算得赋值号右部的表达式的值并生成相应的指令保证这个值放在运行期的数据栈顶。最后通过前面查到的左部变量的位置信息,生成相应的STO指令,把栈顶值存入指定的变量的空间,实现了赋值操作。返回函数值也是用赋值语句进行返回值
5、的储存。首先调用condition函数处理条件语句,并且把当前condition处理生成的判断条件操作代码的的地址cx保存到cx1。每个循环体中,在循环体结束前,设置跳回判断操作判断当前条件是否跳出循环。都把本循环体结束的下一个位置保存到cx2生成跳转,并在循环结束时用cx2更新为目前循环结束跳转地址。难点分析:本模块,主要难点是处理循环体的跳转,解决方法参照上点。不过可以参照if语句和while语句。(2) 扩充代码: 1)在头文件pl0.h中的符号symbol中增加所要求增加的符号,用加粗倾斜红色字体标出: 2)源代码:if(sym=forsym) /* 准备按照for语句处理 */get
6、symdo;if(sym=ident) /* 按照赋值语句处理 */i=postion(id,*ptx);if(i=0)error(11); /* 变量未找到 */elseif(tablei.kind!=variable)error(12); /* for语句格式错误或者赋值语句格式错误 */i=0;getsymdo;if(sym=becomes)getsymdo;else error(13); /* 检测赋值符号 */memcpy(nxtlev,fsys,sizeof(bool)*symnum);expressiondo(nxtlev,ptx,lev); /* 处理赋值符号右侧表达式 */i
7、f(i!=0)gendo(sto,lev-tablei.level,tablei.adr); /* expression将执行一系列指令,但最终结果将会保存在栈顶,执行sto命令完成赋值 */ else error(17);cx1=cx; /* 保存判断条件操作的位置 */getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlevdosym=true; /* 后跟符号为do */conditiondo(nxtlev,ptx,lev); /* 调用条件处理 */cx2=cx; /* 保存循环体的结束的下一个位置 */gendo(jpc,0,0)
8、; /* 生成条件跳转,但跳出循环的地址未知 */if(sym=dosym)getsymdo;else error(18); /* 缺少do */statementdo(fsys,ptx,lev); /* 循环体 */gendo(jmp,0,cx1); /* 回头重新判断条件 */codecx2.a=cx; /* 反填跳出循环的地址,与if类似 */4. 增加case语句:(1) 设计思想:Case语句的语法分析:<case语句>:=<case><标识符>:<常量>:<语句>endcase identcaseendcase语句:ide
9、nt:设计思路: 按照上述语法分析图,先写出格式判断,建立语句处理的框架。再细致写出伪代码的生成核心部分。(以下分析中提及的“循环体”是指上面语法分析图的循环结构) 依照语法要求写出语法分析的框架,大致如上分析图。 首先,将变量的位置存到blpst,供后面生成变量与常量比较指令用。用casenum记下case含有的情况个数。每个循环体开始,取得常量之后,生成三条指令lod(将变量压到栈顶)、lit(将常量押到栈顶)、opr 0 8(两者作比较)。在生成后面语句的代码之前,生成jpc利用变量和常量比较所得结果进行跳转,若为假,则跳到本循环体结束的地方。接着,对循环体内语句进行处理。生成无条件跳转
10、指令跳转到case语句结束,由于地址未知,要等先把各个循环体中的无条件跳转指令的地址放到cxjmpadr数组中,待case结束后再回填跳转地址。最后,回填本循环体头的条件跳转地址。 难点分析:1.处理常量与变量的比较。一开始以为应该跟if语句类似,处理常量与变量的比较的时候发现这一点跟if语句压根不同,而且要难得多。不过,后来认识到变量的本质,从生成的汇编代码的角度出发,利用生成三条指令lod(将变量压到栈顶)、lit(将常量押到栈顶)、opr 0 8(两者作比较)解决了这个问题。2.循环体的跳转问题,比较复杂。简单来说,三点跳转的关键点:一,循环体头的判断跳转;二,循环倒数第二个操作,跳出c
11、ase语句操作;三,最后的回填条件跳转操作。(2)扩充代码: 1)在头文件pl0.h中的符号symbol中增加所要求增加的符号,用加粗倾斜红色字体标出:2)源代码:if(sym=casesym) /*case 语句*/getsymdo;if(sym!=ident)error(14);/* case后应为标识符*/ elseint blpst=i=postion(id, *ptx);/*将变量的position保存在blpst中*/if(i=0)error(11);/* 标识符未找到 */elseif(tablei.kind!=variable)error(38);/* case后的标识符应该为
12、变量 */getsymdo;if(sym!=colon)error(39);/*应该为冒号*/elseint casenum=0;/*casenum记录情况个数*/int cxjmpadr50;/*cxjmpadr用于存储各 种情况中转移指令的地址*/int cxb=cx;/*cxb存储case语句开始的指令地址*/int cjpc;/*当前情况处理完常量标号后的跳转指令地址*/int varpst=i;/*存放case后面变量的position*/int conpst;/*存放当前处理情况的常量标号的position*/int jjj;for(jjj=0;jjj<50;jjj+)cxj
13、mpadrjjj=0; do getsymdo; if(sym!=ident)/*是否为标识符*/error(37);/*case语句体中,冒号前面应该为标识符*/elseconpst=i=postion(id, *ptx);if(i=0)error(11);/* 标识符未找到 */else if(tablei.kind!=constant)error(40);/* 标识符应该为常量 */getsymdo;if(sym!=colon)error(39);/*应该为冒号*/memcpy(nxtlev, fsys, sizeof(bool)*symnum);nxtlevsemicolon=true
14、;nxtlevcolon=true;nxtlevendcasesym=true;/* 后跟符号为分号或end */getsymdo; gendo(lod,lev-tableblpst.level,tableblpst.adr);/*将case后变量放到栈顶*/ gendo(lit,lev-tableconpst.level,tableconpst.val);/*将当前常量放到栈顶*/gendo(opr,0,8);/*将当前栈顶和次栈顶比较,看是否相等,是为真,否为假放到 次 栈顶*/cjpc=cx;/*记住跳转语句代码地址*/gendo(jpc,0,0);/*设置条件跳转,地址暂时未知*/st
15、atementdo(nxtlev, ptx, lev);cxjmpadrcasenum+=cx;/*记住当前情况的jmp语句代码地址*/gendo(jmp,0,0);/*设置跳出case语句,跳转地址暂时未知*/codecjpc.a=cx;/*回填jpc跳转地址*/printf("%dn",codecjpc.a);while(sym=semicolon);if(sym!=endcasesym) error(36);/*结束符号因该为endcase*/*回填各个情况处理中的jmp语句的跳转地址*/for(jjj=0;jjj<casenum;jjj+)codecxjmpa
16、drjjj.a=cx;getsymdo;5. 相关代码的修改说明:修改部分为红色加粗字体1).h中文件的修改:/* 关键字个数 */#define norw 17/* 符号 */enum symbolnul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,colon,period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym
17、,varsym,procsym,forsym,casesym,endcasesym;#define symnum 362)初始化函数 init()中的修改:/* 设置保留字名字 */strcpy(&(word00),"begin");strcpy(&(word10),"call");strcpy(&(word20),"case");strcpy(&(word30),"const");strcpy(&(word40),"do");strcpy(&(w
18、ord50),"end");strcpy(&(word60),"endcase");strcpy(&(word70),"for");strcpy(&(word80),"if");strcpy(&(word90),"odd");strcpy(&(word100),"procedure");strcpy(&(word110),"read");strcpy(&(word120),"then&quo
19、t;);strcpy(&(word130),"var");strcpy(&(word140),"while");strcpy(&(word150),"write");/* 设置保留字符号 */wsym0=beginsym;wsym1=callsym;wsym2=casesym;wsym3=constsym;wsym4=dosym;wsym5=endsym;wsym6=endcasesym;wsym7=forsym;wsym8=ifsym;wsym9=oddsym;wsym10=procsym;wsym11=readsym;wsym12=thensym;wsym13=varsym;wsym14=whilesym;wsym15=writesym;3) 新增错误编号及含义: 33 read语句缺少右括号 34 read语句缺少左括号 35 read()中的标识符应为声明过的变量 36 case中丢了endcase 37 case语句体开头应为标识符 38 case后的标识符应为变量 39 case变量后应为冒号 40 case语句体开头因为常量5 测试数据及结果:测试用例一1.测试代码:文件名:success.txt代码:const a=1,c=2,d=3;var b,i,k;begin read(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《疫苗及接种医学》课件
- 《眼的解剖》课件
- 地理-山东省淄博市2024-2025学年第一学期高三期末摸底质量检测试题和答案
- 小学五年级数学上期小数点乘除法计算习题
- 小学数学新人教版一年级下册20以内口算练习题大全
- 【金榜学案】七年级历史上册第一单元第2课原始的农耕生活达标检测岳麓版
- 勇敢地化蝶高考语文阅读理解
- 《智慧医疗解决方案》课件
- 《炉内冒正压的机理》课件
- 高锰钢铸件裂纹缺陷形成原因
- 中国雷暴日多发区特征及雷电发展变化
- 20232023山东省高中学业水平测试会考题及答案政治
- 独一味(正式稿2)
- 山西太原晋阳湖总体规划城市设计景观方案文本
- 干部业绩相关信息采集表
- 八年级上综合性学习 我们的互联网时代 练习卷(含答案)
- 中西文化概论(第三版)PPT完整全套教学课件
- 食品批发销售记录制度
- 2024学年上海市浦东新区物理高二上期末联考试题含解析
- 粉尘应急演练记录
- 持续交付2 0:业务引领的DevOps精要(增订本)
评论
0/150
提交评论