# **编译原理实验报告**
## **一、整体概括**
目录结构如下图所示,其中fileio包负责底层文件读入,scanner是语法分析器,parser是词法分析器,interpret是解释执行器。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.001.png)
## **二、词法分析器**
Symbol符号结构体有三个域,分别记录Symbol的类型,文字,如果是整数就记录数的大小
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.002.png)
初始化的时候传入文件路径,并置行号为1,行号为了后面报错能够精确到某一行
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.003.png)
词法分析器主函数一开始先去除遗留的空格,知道遇到第一个非空白符,如果读到结束符就结束
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.004.png)
如果是字符,就有可能是一个单词,不断向后扫描,知道遇到第一个空白符为止,当长度过长时就报错。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.005.png)
如果是数字开头,就有可能是一个数字,不断向后扫描,知道遇到第一个非数字,在扫描过程中计算数字的大小
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.006.png)
如果遇到 :、>、< 这三个符号,就有可能是:=\>=\<=,需要再看一位才能确定,如果是其他符号就返回相应的Symbol
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.007.png)
读取一个字符的函数,如果遇到换行符需要给行号加一
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.008.png)
一些辅助方法,判断字符的类型
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.009.png)
## **三、语法分析器**
在语法分析过程中需要维护两个表格,一个是符号表,另一个是中间代码表。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.010.png)
对于每一个标识符都有三种可能,常量、变量、过程,这里准备一种类型进行记录并准备好判断的方法供后面使用。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.011.png)
对于符号表,需要准备好存储在符号表中的每个符号的结构体,每一个符号都需要保存它的文字、类型、层级、地址,如果是数字需要保存它是值。
还需要准备好向符号表中添加一项的方法enter.
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.012.png)
对于中间代码,我使用一个结构体asm来存储每一项的操作符、操作数、层级
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.013.png)
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.014.png)
```
/* lit 0, a : load constant a
opr 0, a : execute operation a
lod l, a : load variable l, a
sto l, a : store variable l, a
cal l, a : call procedure a at level l
Int 0, a : increment t-register by a
jmp 0, a : jump to a
jpc 0, a : jump conditional to a */
```
在遇到一个符号调用时需要判断这个标识符是否已经在符号表中存在
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.015.png)
同时我还需要准备一个方法判断当前栈顶单词是否在select集中
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.016.png)
做好准备工作,开始正式进入语法分析。
我用的是递归下降的分析方法,需要针对每一个产生式写一个分析方法,让后让语法分析程序从顶层函数block开始自动递归的进入其他分支过程,完成语法分析。
当出现const关键词后需要进入常量声明过程,紧接着是标识符、赋值号、数字,这个过程如果没有问题的话就可以通过enter加入符号表了,如果后面接着逗号,需要再次进入这个过程,知道遇到分号结束。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.017.png)
当出现var关键词,需要进入变量声明过程,与常量声明类似。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.018.png)
如果下一步应该是一个引子,则进入因子的处理函数。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.019.png)
当判定是一个项时就进入项的处理函数。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.020.png)
当判断下面应该是一个表达式的时候,就进入表达式的处理函数。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.021.png)
如果是if while判断,需要是一个条件,就进入条件的处理函数。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.022.png)
语句的产生式比较多,在函数里面需要进行更多的switch和if判断,判断进入哪个产生式的处理流程。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.023.png)
最顶层的block函数处理整个代码
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.024.png)
## **四、解释执行器**
解释执行器需要解析每一条中间代码,模拟栈并进行相应的运算。
因为有层级的存在,所以需要一个专门的函数计算真正的内存地址
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.025.png)
同时需要维护四个寄存器,分别如图所示。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.026.png)
Opr指令是比较特殊的,需要根据后面的操作数来选择操作类型。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.027.png)
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.028.png)
## **五、测试**
我用pl0编写了两个程序,分别是求最大值和累加,用来验证程序的正确性。
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.029.png)
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.030.png)
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.031.png)
![](img/Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.030.png)
## **六、总结**
通过这次实验,对编译器的词法分析和语法分析过程更加了解了,更加深刻的认识了中间代码的生成过程。
## 说明
## PL0 compiler
### 概述
该项目是编译原理课程的课程作业,为简化版pl0语言写一个编译器,生成中间代码并解释执行
- 题目要求和实验报告见 `docs` 文件夹
- 两个pl0程序示例见 `bin` 文件夹
### 使用方法
使用 go 1.13+ 版本都可以正常编译
#### 编译
```
go build -ldflags "-w -s" -trimpath -o pl0compiler.exe .
```
#### 运行
```
pl0compiler.exe pl0程序文件名
例如
pl0compiler.exe bin/maxif.txt
```
没有合适的资源?快使用搜索试试~ 我知道了~
基于C语言实现简化版pl0语言写一个编译器(编译原理)【100012209】
共57个文件
png:31个
go:18个
docx:3个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 115 浏览量
2023-05-15
11:05:24
上传
评论
收藏 2.33MB ZIP 举报
温馨提示
fileio包负责底层文件读入,scanner是语法分析器,parser是词法分析器,interpret是解释执行器。
资源推荐
资源详情
资源评论
收起资源包目录
100012209-基于C语言实现简化版pl0语言写一个编译器(编译原理).zip (57个子文件)
pl0compiler_01
go.mod 44B
token
token_test.go 634B
token.go 6KB
LICENSE 1KB
scanner
error.go 2KB
scanner.go 3KB
docs
题目要求.docx 30KB
实验报告.docx 1.02MB
~$实验报告.docx 162B
img
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.017.png 65KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.022.png 89KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.012.png 51KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.007.png 57KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.027.png 35KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.005.png 33KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.030.png 75KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.014.png 22KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.023.png 83KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.002.png 7KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.015.png 41KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.004.png 14KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.018.png 20KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.024.png 126KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.016.png 38KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.025.png 8KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.003.png 10KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.009.png 29KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.029.png 5KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.020.png 57KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.021.png 73KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.006.png 20KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.008.png 13KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.011.png 47KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.001.png 14KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.031.png 9KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.026.png 34KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.013.png 10KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.019.png 149KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.010.png 24KB
Aspose.Words.982da196-695c-46bb-94f0-cf0dfc711921.028.png 55KB
interpret
interpret.go 2KB
rw.go 368B
bin
while.txt 158B
maxif.txt 112B
parser
printout.go 916B
selectset
expression.go 255B
declare.go 207B
factor.go 212B
statement.go 226B
fct
fct.go 613B
ident
ident.go 457B
parser.go 15KB
error.go 132B
asm
asm.go 163B
fileio
fileio.go 467B
README.md 7KB
main.go 935B
共 57 条
- 1
资源评论
神仙别闹
- 粉丝: 2662
- 资源: 7639
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功