源码链接
一、实验目的
本综合实验要求学生根据已经掌握的编译技术,读懂读通世界著名科学家N.Wirth先生编写的“PL/0 编译程序”,并根据要求修改编译源程序,在符合PL/0语言基本词法、语法规则的前提下,对PL/0语言的功能进行扩充。同时考察学生设计和撰写实验报告和汇报PPT的能力。
二、实验要求
1.使用 Easystructure或Visual Paradigm工具画出PL/0编译程序主程序、各个函数的程序流程图,并简要说明功能。
2. IDE配置或开发:完成基于VS-code 编程工具的PL/0语言开发环境配置,或自己设计实现PL/0编程IDE(语言不限)。
(1)配置环境,实现PL/0程序编写,并可以在VS-code中编译运行;
(2)实现不同类型保留字高亮显示;
(3)程序编写,函数输入提示功能;
(4)代码格式化功能,自动规整化;
3.基本功能扩展
(1) I/O 的功能扩展:增加格式化输入、格式化输出。
(2)数据结构的扩展:增加浮点数。
(3)出错处理:增加至少5类编译错误的报错提示。
(4)增加数组功能:实现整形数组和浮点型数组。
(5)浮点数操作:实现浮点数向下取整和向上取整。
4.高级功能扩展,以下条目只需实现一项
(1)数组运算:数组加减乘除运算。
(2)统计函数:构建可实现数组元素平均、最大值、最小值、求和四个系统函数。
(3)求次方函数:构建可计算2次方,3次方系统函数。
5.报告及PPT撰写
(1)实验报告:注意格式、逻辑、素材、引文等。
(2)报告PPT:注意格式、逻辑、素材等。
三、基本功能完成
1、数据结构的扩展:增加浮点数(并实现浮点数加减乘除、比较运算等)。
浮点数扩展声明格式为:“varf 变量名,变量名,…;”。
浮点数赋值格式为: “变量名:=表达式;”。
浮点数声明要在整数声明之后。
以下为操作步骤:
(1)在PL0源程序的基础上定义浮点数类型的关键字varf,symbol枚举类型中增加varfsym,并将二者关联
(2)init函数中将varfsym添加到声明开始符号集。
(3)在block函数中增添浮点数声明模块(浮点数处理逻辑与整数处理逻辑一致,因此与整数处理逻辑一致)
(4)在getsym函数中修改number类型的取值算法,并修改num为float类型,使num可以接受浮点数。
(5)修改虚拟机代码结构,使其在使用lid指令时,可以对浮点数进行操作(增加的浮点型a1变量,只为lid指令服务)。
(6)新增浮点栈s1,其运算方式与整数栈一致,以供进行浮点运算,即定义一个浮点变量时,浮点栈运算与整数栈同步,在虚拟代码指令中增加对浮点栈的操做,从而实现浮点数加减乘除,比较运算、存取等操作。如下:
测试结果与格式化输入输出一起展示
2、I/O 的功能扩展:增加格式化输入、格式化输出。
格式化输入输出书写形式为:
read(%d,变量名,%f,变量名,…);
write(%d,变量名,%f,变量名,…);
以下为修改步骤:
(1)新增格式化字符%,并在枚举类型中添加format关键字符号,并将二者关联
(2)改变虚拟机指令,opr,使其输入输出虚拟指令可进行格式化输入与输出。
(3)在statement函数中修改输入read与输出write的语法结构,使其翻译为相对应的虚拟机指令。
(4)结果展示:
3、浮点数操作:实现浮点数向下取整和向上取整(并实现参与表达式运算)。
浮点数向下向上取整使用两个函数实现,downint与upint,使用格式为:downint(变量名),upint(变量名)。downint与upint可参与赋值以及表达式运算。以下为修改步骤。
(1)在枚举类型symbol中增加downintsym与upintsym关键字符号,并将其与downint,upint绑定。
(2)将downintsym与upintsym加入到因子开始符号集中。
(3)修改factor函数,使其可以对downint与upint进行识别,进行赋值以及表达式运算。
(4)结果展示
4、增加数组功能:实现整形数组和浮点型数组。
修改pl0编译器源码,增加数组声明arr。
定义格式为:“arr 变量名(数组大小);”
使用格式为:“变量名(数组下标)”。
数组声明要在整型与浮点型声明之后。
由增加浮点数功能可知,由于定义了浮点栈与整数栈,因此通过增加关键字arr就可以实现整数数组与浮点型数组,即arr关键字定义的是混合型数组,既是整型也是浮点型,想是整型,就调用整数栈,想是浮点型,就调用浮点栈。
(1)在枚举类型symbol中增加arrsym关键字符号,并实现arrsym与arr的绑定
(2)增加名字表中标识符的类型array
(3)修改enter函数,在名字表中添加定义的数组的相关信息(数组名字,数组基地址,数组大小等)。
(4)增添数组声明处理函数arrdeclaration
(5)修改statement函数中的赋值模块,实现对数组元素的赋值,arrnum为数组下标,table[i].adr为数组基地址,基地址加偏移量(数组下标)即为数组元素地址。
(6)修改read与write,使其可以对数组元素进行输入输出。如下图,为read输入,由于本次扩展选择的高级功能是实现数组的加减乘除运算,而write输出参数可以是表达式,因此可在修改了factor函数后实现数组的加减乘除运算时,数组输出也就完成了,因此不在statement函数中单独增加数组输出的模块。若想单独增加,仿照read的数组读入模块实现write的数组输出即可。
(7)结果展示:与高级功能数组的加减乘除一起展示。
5、出错处理:增加至少5类编译错误的报错提示。
下图为error模块遇到各种错误代码,输出警告。
(1)error(40)浮点数输入格式错误。
(2)error(41);//格式化字符输入错误(%后应为d或f)。
(3)error(42); //请先输入格式化字符%。
(4)error(43)//downint后应跟左括号。
(5)error(44)//upint后应跟左括号
(6)error(45);//数组大小输入错误
(7)error(46);//请输入数组大小
(8)error(47);//数组声明缺少右括号
(9)error(48);//数组声明缺少左括号
(10)error(49);//数组调用缺少左括号
(11)error(50);//数组调用异常
(12)error(51);//数组调用缺少右括号
(13)error(52); //数组越界
(14)结果展示:
四、高级功能
1、数组运算:数组加减乘除运算。
(1)实现数组加减乘除运算,修改表达式处理模块即可,在factor函数中,增添数组处理模块,使表达式可以识别数组元素。从而实现数组加减乘除运算。
(2)结果展示