实验报告 彭韬 一、实验概要 本次实验为PL/0编译器的文法分析及P-code代码的生成与解释执行。 由于我用的VC6.0显示中文注释全是乱码,我的注释基本都是用英文写的。在开发的过程中陆陆续续地写了些笔记,也不是很完整。 二、功能实现 1.实验的所有基本要求,老师给的测试集全部通过。 2.扩展功能 a.在变量的定义中增加了类型声明,声明格式示例:var a,b,c(2:5):int;x,y:bool; 为跟老师给的测试集兼容,保留未加类型声明的语法,不声明则为默认的int型。带类型检查。(在后一个实现中间代码生成及优化的版本中取消了类型检查,具体参看note.txt) b.增加bool类型及true,false常量。增加bool运算。 c.增加取模及乘方运算。用%,^作分别作运算符。 d.增加for to/downto do语句 e.扩展了指令集,但扩展的时候考虑栈机实现的可操作性,增加的指令都是栈顶操作指令,所有运算都在栈顶进行。增加的指令有: LODX:加载数组元素;STOX:存数组元素;POP:弹栈;INC:自增/减;CPY:拷栈顶;SHT:移位;NOP:空指令 f.参数传递及递归实现 g.中间代码生成及优化 我用三元组作赋值表达式的中间代码,外加一个type的域用来表示本中间代码的操作数(其实为冗余信息,只是为了方便操作,本质还是三元组)。中间代码进行多趟扫描的优化,以一个表达式为块,各块之间互相独立,各块分别生成、分别优化、分别翻译成P-code,整个流程由语法分析控制。由于时间问题,没能做控制流程的优化及更进一步的DAG优化。具体实现参看note.txt。 h.出错信息集中处理。前30条出错信息的文本参考网上信息。后面的为自定义。 i.名字表添加了para,beginindex,endindex,size;type;属性,主要是处理过程参数和数组还有数据类型是加的。 j. 保留有调试用的各种函数。例如打印名字表,跟踪栈顶,跟踪中间代码生成,跟踪代码优化,等等。 k. 优化数组保存方式:只保存声明的区段。 l. 目标代码采取多趟的窥孔优化 三、实验心得 这几天我都泡在本次实验上,(因此被舍友称为“编译王子”)。感觉编译器简单的可以很简单,复杂的也可以很复杂,这次实验还是很有挑战性的。编译原理跟编译技术还是有点差别的。对比之下发现自己的代码优化这一块学得不是很好。因为是第一次做编译器,很多细节都不会,不少地方还能改进,应该有更好的实现方法。明天考试了,编译原理课还没怎么复习,希望本次实验对考试能起到复习的作用吧。