课 程 设 计
课程名称 编译原理
题目名称 PL/0编译器的扩充
学生学院 计算机学院
专业班级 计算机科学与技术(7)
学 号 3110006131
学生姓名 陈日燊
指导教师 林 志 毅
2011 年 1 月 8 日
一. 课程设计目的与要求正月初一过新年
1、课程设计目的:
在分析理解一个教学型编译程序(如PL/0)的基础上,对其词法分析程序、语法分析程序和语义处理程序进行部分修改扩充。达到进一步了解程序编译过程的基本原理和基本实现方法的目的。
2、课程设计要求:
对PL/0作以下修改扩充:
(1)增加单词:保留字 ELSE,FOR,TO,DOWNTO,RETURN
运算符 +=,-=,++,--,
(2)修改单词:不等号# 改为 <>天边歌曲
(3)增加条件语句的ELSE子句,要求:写出相关文法,语法图,语义规则。
二.实验环境与工具
(1)计算机及操作系统:PC机,WindowsXP
(2)程序设计语言: VC++ 6.0, C/C++语言
(3)教学型编译程序:PL/0
三. 结构设计方案
1、 结构设计说明:
PL/0的编译程序以语法分析程序为核心,词法分析程序和代码生成程序都作为一个独立的过程,当语法分析需要读单词时就用词法分析程序,而当语法分析正确需生成相应的
目标代码时,则调用代码生成程序。此外,用表格管理程序建立变量,常量和过程标识符的说明与引用之间的信息联系。用出错处理程序对词法和语法分析遇到的错误给出在源程序中出错的位置和错误性质。
2、 各功能模块图示:
3. 各功能模块作用表:
1 | PL0 | 主程序 |
2 | Error | 出错处理,打印出错位置和错误编码 | 停薪留职
3 | GetCh | 漏掉空格,读取一个字符 |
4 | GetSym | 词法分析,读取一个单词 |
5 | Gen | 生成目标代码,并送入目标程序区 |
6 | TEST | 测试当前单词符号是否合法 |
7 | ENTER | 登录名字表 | 眼影的画法
8 | POSITION | 查找标识符在名字表中的位置 |
9 | ConstDeclaration | 常量定义处理 |
10 | VarDeclaration | 变量说明处理 |
11 | ListCode | 列出目标代码清单 |
12 | FACTOR | 因子处理 |
13 | TERM | 项处理 现实政治 |
14 | EXPRESSION | 表达式处理 |
15 | CONDITION | 条件处理 |
16 | STATEMENT | 语句部分处理 |
17 | Block | 普通话考试短文 分程序分析处理过程 |
18 | BASE | 通过静态链求出数据区的基地址 |
19 | Interpret | 对目标代码的解释执行程序 |
| | |
3. 符号名字表结构:
struct tablestruct
{
char name[al]; /*名字*/
enum object kind; /*类型:const,var,array or procedure*/
int val; /*数值,仅const使用*/
int level; /*所处层,仅const不使用*/
int adr; /*地址,仅const不使用*/
int size; /*需要分配的数据区空间,仅procedure使用*/
};
4. 保留关键字枚举结构:
大冷
enum symbol{
nul, ident, number, plus, minus,
times, slash, oddsym, eql, neq,
lss, leq, gtr, geq, lparen,
rparen, comma, micolon, period, becomes,
beginsym, endsym, ifsym, thensym, whilesym,
writesym, readsym, dosym, callsym, constsym,
varsym, procsym, elsym, forsym, tosym,
downtosym, returnsym, pluql, minuql, plusplus,
minusminus,
};
5.名字表中标识符枚举类型:
enum object{
constant, /*常量*/
variable, /*变量*/
procedur, /*过程*/
};
6.虚拟机
enum fct{ /* 虚拟机代码*/
lit, opr, lod,
sto, cal, inte,
jmp, jpc,
};
struct instruction /* 虚拟机代码结构*/
{
enum fct f; /* 虚拟机代码指令*/
int l; /* 引用层与声明层的层次表*/
int a; /* 根据f的不同而不同*/
};
7. 扩充部分语法描述图:
8. 运行时存储组织和管理
对于源程序的每一个过程(包括主程序),在被调用时,首先在数据段中开辟三个空间,存放静态链SL、动态链DL和返回地址RA。静态链记录了定义该过程的直接外过程(或主程序)运行时最新数据段的基地址。动态链记录调用该过程前正在运行的过程的数据段基址。返回地址记录了调用该过程时程序运行的断点位置。对于主程序来说,SL、DL和RA的值均置为0。静态链的功能是在一个子过程要引用它的直接或间接父过程(这里的父过程是按定义过程时的嵌套情况来定的,而不是按执行时的调用顺序定的)的变量时,可以通过静态链,跳过个数为层差的数据段,找到包含要引用的变量所在的数据段基址,然后通过偏移地址访问它。
在过程返回时,解释程序通过返回地址恢复指令指针的值到调用前的地址,通过当前段基址恢复数据段分配指针,通过动态链恢复局部段基址指针。实现子过程的返回。对于主程序来说,解释程序会遇到返回地址为0的情况,这时就认为程序运行结束。
解释程序过程中的ba珠海九洲岛函数的功能,就是用于沿着静态链,向前查找相差指定层数的局部数据段基址。这在使用sto、lod、stoArr、lodArr等访问局部变量的指令中会经常用到。
类PCODE代码解释执行的部分通过循环和简单的ca判断不同的指令,做出相应的动作。当遇到主程序中的返回指令时,指令指针会指到0位置,把这样一个条件作为终至循环的条件,保证程序运行可以正常的结束。