《 编译原理 》
课程设计报告
实验时间: 2013.01.02
实验班级: 计科 10(5)班
姓
学
名: 郭倩娜
号: 3210006073
实验教师:
蒋艳荣
计算机学院
广东工业大学
1
编译原理课程设计报告
一、 实验目的与要求
目的:在分析理解一个教学型编译程序(如 PL/0)的基础上,对其词法分析
程序、语法分析程序和语义处理程序进行部分修改扩充。达到进一步了解程序编译
过程的基本原理和基本实现方法的目的。
课程设计
基本内容(成绩范围:“中”、“及格”或“不及格”)
(1)扩充赋值运算:*= 和 /=
(2)扩充语句(Pascal 的 FOR 语句):
①FOR <变量>:=<表达式> TO <表达式> DO <语句>
②FOR <变量>:=<表达式> DOWNTO <表达式> DO <语句>
其中,语句①的循环变量的步长为 2,
语句②的循环变量的步长为-2。
(3)增加运算:++ 和 --。
选做内容(成绩评定范围扩大到:“优”和“良”)
(1)增加类型:① 字符类型;
(2)扩充函数:① 有返回值和返回语句;② 有参数函数。
(3)增加一维数组类型(可增加指令)。
(4)其他典型语言设施。
② 实数类型。
二、实验环境与工具
(1)计算机及操作系统:PC 机,Windows2000,WindowsXP
(2)程序设计语言:C++Builder5,VC 6.0
(3)教学型编译程序:PL/0
三、设计方案
(1) 概述:
PL/0 程序 Pascal 版本
源语言:
目标语言: 目标代码
实现平台:
运行平台:
C++Bulider 6
Windows 7
(2)结构设计说明:各功能模块描述:
(1)PL/0 编译程序由词法分析、语法分析、语义分析、代码生成以及代码优化这
几个主要部分组成。
2
表
格
管
理
程
序
(2)
Pl0 源 程 序
词法分析程序
语法分析程序
代码生产程序
目 标 程 序
出
错
处
理
程
序
(2)PL/0 的解释执行结构
PL/0 语言目标程序
PL/0 语言解释执行程序
(3)PL/0 编译程序总体流程图
输入数据
输出数据
启动
置初值
调用 GETSYM 取单词
调用 BLOCK 过程
当前单词是否为
程序结束符“.”
出错
源程序中是
否有错误
打印出错
调 用 解 释 过 程
INTERPRET 解释执行目
结束
3
(4)GETSYM 词法分析模块
该模块的功能是为语法语义分析提供单词,把输入的字符串形式的源程序分
割成一个个单词符号传递给语法语义分析。
单词的种类有 5 种:基本字(即保留字)、运算符、标识符、常数、界符。
词法分析程序主要完成以下功能:
过滤空格
识别保留字
识别标识符
拼数
拼复合词
输出源程序
GETCH
Y
N
Y
打印出错信息
停止编译
缓冲区是否还有
字符
N
源程序文件是否
结束
读入一行源程序放入在 LINE 中并输出,
置 CC:=0
返回
4
(5)词法分析模块
PL/0 编译程序的语法分析采用了自顶向下的递归的子程序法。语法分析同时也
根据程序的语义生成相应三元代码,并提供了出错处理的机制。
语法分析主要有以下分析过程:
BLOCK
分程序分析处理过程
ConstDeclaration 常量定义处理
Vardeclaration 变量说明处理
Statement
语句处理
Expression
表达式处理
Term
Factor
Condition
Error
Gen
Test
Enter
Position
Listcode
项处理
因子处理
条件处理
出错处理,打印出错位置和错误编码
生成目标代码,并送入目标程序区
测试当前单词符号是否合法
登录名字表
查找标识符在名字表中的位置
列出目标代码清单
这些过程在结构上构成一个嵌套的层次结构。由 PL/0 的语法图可知:一个完整
的 PL/0 程序是由分程序和句号构成的。因此,本编译程
序在运行的时候,通过主程序中调用分程序处理过程
block 来分析分程序部分(分程序分析过程中还可能会
递归调用 block 过程),然后,判断最后读入的符号是否
为句号。如果是句号且分程序分析中未出错,则是一个
合法的 PL/0 程序,可以运行生成的代码,否则就说明源
PL/0 程序是不合法的,输出出错提示即可。
(6)语义分析模块
PL/0 编译程序语法、语义分析是整个编译程序设计
5
与实现的核心部分. PL/0 编译程序的语法分析采用了自顶向下的递归子程序法。
语法分析子程序采用了自顶向下的递归子程序法,语法分析同时也根据程序的
语意生成相应的代码,并提供了出错处理的机制。语法分析主要由分程序分析过程
( block )、 常 量 定 义 分 析 过 程 ( constdeclaration )、 变 量 定 义 分 析 过 程
(vardeclaration)、语句分析过程(statement)、表达式处理过程(expression)、
项处理过程(term)、因子处理过程(factor)和条件处理过程(condition)构成。
(3)主要成分描述
① 符号表
(1)TABLE 符号表中的信息,在原来的基础上扩展了实数和字符型数据
后,在表中添加 TYPE 属性,用来记录数据的类型
NAME KIND
A
B
C
D
E
P
CONSTANT
CONSTANT
VARIABLE
VARIABLE
VARIABLE
PROCEDUR
G
…
VARIABLE
……
VAL/LEVEL
35
49
LEV
LEV
LEV
LEV
LEV+1
……
ADR
SIZE
DX
DX+1
DX+2
DX+3
DX
……
4
TYPE
INT
CHAR
INT
CHAR
REAL
(2)指令功能表
OPR 0 15 屏幕输出换行
OPR 0 16 从命令行读入一个输入置于栈顶
LIT 0 a 将常数值取到栈顶,a 为常数值
LOD l a 将变量值取到栈顶,a 为偏移量,l 为层差
STO l a 将栈顶内容送入某变量单元中,a 为偏移量,l 为层差
CAL l a 调用过程,a 为过程地址,l 为层差
INT 0 a 在运行栈中为被调用的过程开辟 a 个单元的数据区
JMP 0 a 无条件跳转至 a 地址
JPC 0 a 条件跳转,当栈顶布尔值非真则跳转至 a 地址,否则顺序执行
OPR 0 0 过程调用结束后,返回调用点并退栈
OPR 0 1 栈顶元素取反
OPR 0 2 次栈顶与栈顶相加,退两个栈元素,结果值进栈
6
OPR 0 3 次栈顶减去栈顶,退两个栈元素,结果值进栈
OPR 0 4 次栈顶乘以栈顶,退两个栈元素,结果值进栈
OPR 0 5 次栈顶除以栈顶,退两个栈元素,结果值进栈
OPR 0 6 栈顶元素的奇偶判断,结果值在栈顶
OPR 0 7
OPR 0 8 次栈顶与栈顶是否相等,退两个栈元素,结果值进栈
OPR 0 9 次栈顶与栈顶是否不等,退两个栈元素,结果值进栈
OPR 0 10 次栈顶是否小于栈顶,退两个栈元素,结果值进栈
OPR 0 11 次栈顶是否大于等于栈顶,退两个栈元素,结果值进栈
OPR 0 12 次栈顶是否大于栈顶,退两个栈元素,结果值进栈
OPR 0 13 次栈顶是否小于等于栈顶,退两个栈元素,结果值进栈
OPR 0 14 栈顶值输出至屏幕
② 运行时存储组织和管理
L/0 语言的目标程序时一种假想栈式的汇编语言,解释执行时的数据空间 S 为栈式
存储空间。遵循后进先出的规则,对每个过程当被调用时,才分配数据空间,退出
程序时,所分配的数据空间将被释放。
解释程序定义四个寄存器:指令寄存器 I、程序地址寄存器 P、栈顶寄存器 T、
基址寄存器 B。
在程序调用时,系统在栈顶分配 SL 静态链、DL 动态链、RA 返回地址。其中静
态链的作用是通过层次差找到变量的基址,动态链则是指向正在运行过程的数据段
的基地址,返回地址用于被调用程序运行完后返回调用点后的地址,以便程序继续
进行。
③ 语法分析方法
PL/0 编译程序的语法分析采用了自顶向下的递归子程序法。就是说对应每个非
终结符语法单元,编一个独立的处理程序。语法分析从读入第一个单词开始有开始
符程序出发,沿语法描述图箭头所指的方向进行分析。当遇到非终结符时,则条用
相应的处理过程,从语法描述图看也就进入了一个语法单元,再沿当前所进入的语
法描述图的箭头方向进行分析,但遇到事终结符时则判断当前读入的单词是否与图
中的终结符相匹配,若匹配,则执行相应的语义程序。再读取下一个单词继续分析。
遇到分支点时将当前的单词与分支点上的多个终结符逐个比较,若都不匹配时可能
是进入下一非终极符语法单位或是出错。
④ 中间代码表示
7
PL/0 编译程序中间代码称为类 PCODE 指令代码,其指令格式如下:
其中 f 代表功能码,l 表示层次差(引用变量或过程的分程序与说明该变量或过程的
分程序之间的层次差)。a 的含义对不同的指令有所区别。
四、测试用例
1.测试*=、/=++、--功能:
测试用例:SUANFA.pl0
PROGRAM YUNSUAN;
VAR A;
BEGIN
A := 5;
A *= 10;
WRITE(A);
A /= 2;
WRITE(A);
A++;
WRITE(A);
++A;
WRITE(A);
A--;
WRITE(A);
--A;
WRITE(A);
END.
运行结果为:=== COMPILE PL0 ===
0 PROGRAM YUNSUAN;
0 VAR A;
1 BEGIN
2
4
8 WRITE(A);
A := 5;
A *= 10;
8