PL-0功能拓展及基于VSCode的IDE配置

发布于:2025-08-02 ⋅ 阅读:(19) ⋅ 点赞:(0)

title: PL/0功能拓展及基于VSCode的IDE配置
date: 2024-08-06 22:46:38
tags: 做过的实验||项目复盘
top: true

概述

PL/0语言可以看成PASCAL语言的子集,它的编译程序是由C语言编写的编译解释执行系统。PL/0能充分展示高级语言的最基本成分。

拓展了pl0语言的基础功能(浮点数实现、出错处理、实现整型数组以及格式化输入输出),增加了整型数组求和、平均值、最大最小值系统函数,基于VSCode插件来实现代码补全和自动高亮。

项目地址:https://github.com/GorwayWong/Compiler-Theory-Assignment-PL-0-extend

PL/0基础功能扩展实现

符号总览以及格式化输入/输出

在编译器源文件中添加以下新拓展:

其中 printfsym 代表格式化输出,scanfsym 代表格式化输入。

请添加图片描述
请添加图片描述
请添加图片描述

保留字符号及名字均按照字母表顺序进行排列。

其中printf是格式化输出符号,scanf是格式化输入符号;同时没有删除pl0本来的输入输出函数write和read,是因为一些情况下用这些更方便。

设置printfsym以及scanfsym为语句的开始符号。

在statement函数中添加对printf语句以及scanfsym语句的处理。二者的基本代码与write、read结构类似,就是多了对’d’以及’f’的处理,遇见d时以整型进行输入输出,而f则是浮点型。相对而言,scanf的处理更加复杂,由于浮点类型的读入与整型类型的读入存在区别,而原本的opr指令中只支持对整型的处理,所以我增加了一条新的指令(opr 0 17 0),与(opr 0 16 0)相互配合处理不同的类型输入。

同时将原来的整型数据栈s改成了float类型,整型浮点型都用这个栈进行操作。

请添加图片描述

格式化输入输出测试结果:

请添加图片描述

请添加图片描述

给PL/0添加浮点数以及浮点数上下取整系统函数

首先设置floatsym为因子开始符号。

在getsym中进行修改,如果识别到一个词有可能是数字,则如果在识别过程中遇到了小数点,则认为其是浮点类型:

请添加图片描述

上下取整采用系统函数的方式实现,即操作格式为:ceil(浮点数) floor(浮点数)。增加了两个新的关键字符号ceilsym和floorsym,将二者设置成因子开始符号。

二者的处理思想较为类似,即将被上下取整操作之后的浮点数当作因子返回。在factor函数中增加对这两个sym的识别以及处理。在对ceilsym的处理中,如果括号里的数是浮点数变量,则生成lod指令,最后一位参数为2(在前面已经提到,修改lod使得其能将浮点数转换成int后加1放到栈顶)。如果是常量,则将其转换成int类型再+1放到栈顶。

编写的.plg测试文件以及结果:

请添加图片描述
请添加图片描述

其他功能

还扩展了整数数组、浮点数组、出错处理模块,具体请看GitHub地址源码:

项目地址:https://github.com/GorwayWong/Compiler-Theory-Assignment-PL-0-extend

PL/0高级功能扩展实现

实现了四个系统的统计函数:sum(数组(求和范围)),avg(数组(求平均范围)),max(数组(求最大值范围)),min(数组(求最小值范围))。

这里的“范围”可以是数组大小,也可以是大于0小于数组大小的一个数,比如有一个大小为3的数组list, sum(list(2))则是求前两个数的和。

实现思路与浮点数上下取整功能实现类似,将处理之后的数字当作因子参与运算。于是在factor中增添了四个关键字符号的识别:sumsym,avgsym,maxsym,minsym。

对于求和函数sum:分别对整型数组和浮点数组进行处理,但二者的不同之处在于对于s栈顶数据的操作一个是整型一个是浮点型。求和思路为:依次将数组中的元素取到栈顶(使用lod方法,lod方法对不同的数据类型有不同的操作,具体请见源代码),然后使用opr 0 2 0对栈顶元素进行两两相加,最后栈顶留下的元素就是数组的和了。

对于求平均值函数avg,前面的步骤与求和类似,在栈顶元素是数组之和之后,将求平均的范围,也就是数组后跟的括号里的数(存在全局变量num中)存到栈顶,此时栈顶为数组大小,次栈顶为数组之和,再生成opr 0 5 0除法指令,得到的就是平均数了,存在栈顶。

对于求最大值函数max,将数组中的各个元素取到栈顶之后,调用opr 0 18 0指令(新增的DIY指令,将栈顶和次栈顶比较,将最大值存在次栈顶,原栈顶去掉,即t-1)若干次,次数为数组大小-1,完成后栈顶元素就是最大值了。

对于求最小值函数min,将数组中的各个元素取到栈顶之后,调用opr 0 19 0指令(新增的DIY指令,将栈顶和次栈顶比较,将最小值存在次栈顶,原栈顶去掉,即t-1)若干次,次数为数组大小-1,完成后栈顶元素就是最小值了。

效果图:

请添加图片描述
请添加图片描述

编译原理的魅力

基于VSCode实现PL/0支持插件

效果:

请添加图片描述

对于特定后缀的文件.plg,通过编写自定义的vscode插件实现了关键字、标识符、以及其他符号的高亮。

同时,该vscode插件还可以实现自动补全(对于.plg文件),以下是效果图一览:

请添加图片描述


网站公告

今日签到

点亮在社区的每一天
去签到