# 基于MFC实现的PL/0编译系统
# 引言
PL/0编译系统,语言:C++,MFC界面,IDE:VS2015。编译系统包含词法分析、语法分析、符号表管理、语义分析及目标代码Pcode的生成、错误处理以及Pcode的解释执行。整个编译器以语法分析程序为中心,调用词法分析程序识别单词,生成相应的代码,查询或填写相应的符号表项,在出错时调用错误处理程序,报告错误,同时跳过出错部分继续进行语法分析。
# 一、PL/0语言
## 1.1 PL/0描述
PL0是一种十分简单的“高级”程序设计语言,它只有整数一种类型,但却具有相当完全的可嵌套型的分程序结构。PL/0可进行常量定义、变量说明和过程调用,并具有通常程序设计语言所必需的的最基本的语句,如赋值语句、条件语句、循环语句、过程调用语句和复合语句。考虑到输入/输出的需要,我们添加了简单的读、写语句。PL/0过程没有参数,但可以递归调用,因此,过程所加工的数据只能通过全局变量进行传递。
PL/0语言是一种类PASCAL语言,是教学用程序设计语言,它比PASCAL语言简单,作了一些限制。比如:数据类型只有无符号整数;标识符类型只有简单变量(var)和常量(const);嵌套的层数最大值为3等。
## 1.2 PL/0语言文法
```pascal
<程序> ::= <分程序>.
<分程序> ::= [<常量说明部分>][变量说明部分>][<过程说明部分>]<语句>
<常量说明部分> ::= const<常量定义>{,<常量定义>};
<常量定义> ::= <标识符>=<无符号整数>
<无符号整数> ::= <数字>{<数字>}
<标识符> ::= <字母>{<字母>|<数字>}
<变量说明部分>::= var<标识符>{,<标识符>};
<过程说明部分> ::= <过程首部><分程序>;{<过程说明部分>}
<过程首部> ::= procedure<标识符>;
<语句> ::= <赋值语句>|<条件语句>|<当型循环语句>|<过程调用语句>|<读语句>|<写语句>|<复合语句>|<重复语句>|<空>
<赋值语句> ::= <标识符>:=<表达式>
<表达式> ::= [+|-]<项>{<加法运算符><项>}
<项> ::= <因子>{<乘法运算符><因子>}
<因子> ::= <标识符>|<无符号整数>|'('<表达式>')'
<加法运算符> ::= +|-
<乘法运算符> ::= *|/
<条件> ::= <表达式><关系运算符><表达式>|odd<表达式>
<关系运算符> ::= =|<>|<|<=|>|>=
<条件语句> ::= if<条件>then<语句>[else<语句>]
<当型循环语句> ::= while<条件>do<语句>
<过程调用语句> ::= call<标识符>
<复合语句> ::= begin<语句>{;<语句>}end
<重复语句> ::= repeat<语句>{;<语句>}until<条件>
<读语句> ::= read'('<标识符>{,<标识符>}')'
<写语句> ::= write'('<标识符>{,<标识符>}')'
<字母> ::= a|b|...|X|Y|Z
<数字> ::= 0|1|2|...|8|9
```
## 1.3 PL/0编译系统结构
PL/0编译系统是一个编译-解释执行程序,整个编译过程分两个阶段进行。第一阶段先把PL/0源程序编译成假想计算机的目标程序(P-code指令),第二阶段再对该目标程序进行解释执行,得到运行结果。PL/0编译程序采用一遍扫描,即以语法分析为核心,由它调用词法分析程序取单词,在语法分析过程中同时进行语义分析处理,并生成目标指令。如遇到语法、语义错误,则随时挑用出错处理程序,打印出错信息。在编译过程中要利用符号表的登录和查找来进行信息之间的联系。一边扫描的PL/0编译和P-code解释执行框图如图1所示。
**PL/0编译系统结构框图**
![](http://www.writebug.com/myres/static/uploads/2021/10/19/b7adcac6b327186ac963663ab6ec6f4f.writebug)
# 二、分析与实现
## 2.1 PL/0的词法分析
PL/0编译系统中所有的字符和字符串的类型可简单分为七类,为如下表格:
**PL/0编译系统字符/字符串类型**
| 保留字 | Begin, end, if, then, else, const, procedure, var, do, while, odd, call, read, write, repeat, until |
| ----- | ---------------------------------------- |
| 算数运算符 | + | - | * | / |
| 比较运算符 | <> | < | <= | > | >= | = |
| 赋值符 | := | = |
| 标识符 | 变量名,过程名,常数名 |
| 常数 | 整数 |
| 界符 | , | . | ; | ( | ) |
PL/0的词法分析程序getsym作为一个独立的子程序有语法分析程序调用,它的主要功能及代码结构如下:
- 跳过源程序中的空格、缩进、换行等字符
- 识别单词符号,并把其类别以枚举变量值存入sym中
- 用变量id存放标识符,二分法查找保留字数组word[]
- 若读取无符号整数,则将相应数字自妇产转换为整数存于变量num中
- 通过调用getch取得一个字符,为了优化读取字符效率,每次读取一行源程序,存入缓冲区line,变量ll为源程序当前行的长度,cc为当前正在读取的字符位置
**词法分析getsym函数**
![](http://www.writebug.com/myres/static/uploads/2021/10/19/77f22152eb68a06d6ec67c7036b61df4.writebug)
PL/0的语法分析采用了“单符号先行”技术,即在进入某个语法成分的分析子程序之前,先读取一个单词放入sym中,相对应的,在getsym中,也总是先读取一个字符存放在变量ch中。整个编译过程是先读一个单词加一个字符。
## 2.2 PL/0的符号表管理
### 2.2.1符号表结构
符号表数组table存放所有的符号表项,其中符号表项结构体定义如下:
```c++
//符号表项
struct tab {
string name; //名字
objecttype kind; //类型(const/var/proc)
int val; //值,const专用
int level; //层次,var/proc专用
int adr; //地址,var/proc专用
};
```
### 2.2.2 符号表管理
**PL/0符号表管理函数**
![](http://www.writebug.com/myres/static/uploads/2021/10/19/2befa263002d447fb292c15126ca6324.writebug)
- 登录符号表,即新增符号表项
- **k**:标识符的种类,可以为const,var或procedure
- **dx**:当前应分配的变量的相对地址,分配后要增加1
- **lev**:标识符所在的层次
- **tx**:符号表尾指针的指针,可以直接改变符号表尾指针的值
- 查询符号表,查找标识符在符号表中的位置从tx开始倒序查找标识符
- 找到则返回在符号表中的位置,否则返回0
- **id**:要查找的标识符名字
- **tx**:当前符号表尾指针(倒序查找)
## 2.3 PL/0的语法分析
PL/0采用了递归子程序法进行语法分析,即为每一个语法成分编写一个分析子程序,根据当前读取的符号,可以选择相应的子程序进行语法分析。采用不带回溯的递归子程序法,对语言文法有一定的要求:
- 文法必须是非左递归
- 文法的任一非终结符,其规则右部多个选择所生成的FIRST集合两两不相交
- 若文法具有形如:
![](http://www.writebug.com/myres/static/uploads/2021/10/19/3663699b6fae63506d9a399670de757f.writebug)
则
![](http://www.writebug.com/myres/static/uploads/2021/10/19/b0586d770dc1103339a90d9da77e2d3e.writebug)
根据PL/0的文法BNF表达,下表中列出了PL/0有关的语法成分的FIRST集合FOLLOW集,可以判断出满足递归子程序的要求。表说明:R表示关系运算符,id和num分别表示标识符和无符号整数。
**PL/0文法非终结符的开始符号集与后继符号集**
| 非终结符 | FIRST集 | FOLLOW集 |
| ------------- | ---------------------------------------- | --------------------------- |
| 分程序block | const var procedure id if call begin while repeat read write | . ; |
| 语句statement | Id call begin if while read wr
没有合适的资源?快使用搜索试试~ 我知道了~
精选_基于MFC实现的PL/0编译系统_源码打包
共53个文件
txt:13个
h:13个
cpp:10个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 160 浏览量
2022-03-09
17:46:04
上传
评论
收藏 1.09MB ZIP 举报
温馨提示
基于MFC实现的PL/0编译系统
资源推荐
资源详情
资源评论
收起资源包目录
4322223719948388.zip (53个子文件)
pl0_compilation_system
src
PL0CompilerMFC
sysTab.h 306B
stdafx.h 1KB
interpret.h 242B
interpret.cpp 2KB
input.txt 4B
pcode.h 235B
sysTab.cpp 910B
1.txt 270B
pcode.cpp 647B
lexica.h 255B
5.txt 173B
resource.h 2KB
PL0CompilerMFC.rc 13KB
PL0CompilerMFC.cpp 2KB
Init.h 2KB
6.txt 82B
outError.txt 1KB
res
PL0CompilerMFC.rc2 684B
PL0CompilerMFC.ico 66KB
error.h 143B
3.txt 485B
4.txt 638B
console.h 299B
PL0CompilerMFCDlg.cpp 9KB
output.txt 3B
ReadMe.txt 4KB
PL0CompilerMFCDlg.h 828B
lexica.cpp 2KB
inCode.txt 510B
PL0CompilerMFC.h 460B
PL0CompilerMFC.vcxproj.filters 3KB
right1.pl0 33B
wrong1.pl0 509B
PL0CompilerMFC.vcxproj 11KB
7.txt 108B
PL0CompilerMFC.aps 107KB
2.txt 273B
outPcode.txt 1KB
syntax.cpp 10KB
syntax.h 666B
stdafx.cpp 139B
targetver.h 232B
right.pl0 309B
console.cpp 3KB
error.cpp 354B
.vs
PL0CompilerMFC
v14
.suo 72KB
Release
PL0CompilerMFC.exe 145KB
ReadMe.md 2KB
PL0CompilerMFC.sln 1KB
15211041_朱辉_PL0编译系统.docx 733KB
Debug
PL0CompilerMFC.exe 376KB
LICENSE 1KB
README.md 22KB
共 53 条
- 1
资源评论
工具盒子
- 粉丝: 61
- 资源: 1313
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功