课
课
课
课
程
程
程
程
设
设
设
设
计
计
计
计
课程名称 编译原理
题目名称 PL/0 扩充
学生学院 计算机学院
专业班级 06 级计算机科学与技术 1 班
学 号 3106006394
学生姓名 方锐洲
指导教师 吴伟民
2009 年 1 月 7 日
编译原理课程设计《 PL/0 扩充》 — 3106006394 方锐洲
第 2
2
2
2
页 共 16
16
16
16
页
一、课程设计要求和内容
基本内容
基本内容
基本内容
基本内容
( 1 )扩充赋值运算: += 和 -=
( 2 )扩充语句 REPEAT
< 语句序列 >
DOWHILE < 条件 >
其中, < 条件 > 是循环条件,即条件成立时,重复执行循环体的 < 语句序列 >
选做内容
选做内容
选做内容
选做内容
( 1 )增加运算: ++ 和 -- 。
( 2 )增加类型: ① 字符类型; ② 实数类型。
( 3 )扩充函数: ① 有返回值和返回语句; ② 有参数函数。
( 4 )增加一维数组类型(可增加指令) 。
( 5 )其他典型语言设施。
本次课程设计实现的内容有:
本次课程设计实现的内容有:
本次课程设计实现的内容有:
本次课程设计实现的内容有:
( 1 )基本内容全部实现;
( 2 ) 选作内容实现了增加运算符 ++
,
--
,
*=
,
/=
,
% 运算符, 增加了 for … .to/downto … ..do … ..
语句,增加错误信息原因提示,增加一维数组类型(增加了 6
条指令) ,
二、实验环境与工具
( 1 )计算机及操作系统: PC 机, WindowsXP
( 2 )程序设计编程开发环境: VC++ 6.0
( 3 )教学型编译程序: PL/0
三 . 结构设计说明
《一》各功能模块描述
PL/0 的编译程序采用一趟扫描方式,以语法分析程序为核心,词法分析程序和代码生
成程序都作为一个独立的过程, 当语法分析需要读单词时就用词法分析程序, 而当语法分 析
正确需生成相应的目标代码时,则调用代码生成程序。此外,用表格管理程序建立变量, 常
量和过程标识符的说明与引用之间的信息联系。 用出错处理程序对词法和语法分析遇到的 错
误给出在源程序中出错的位置和错误性质。
《二》各功能模块作用表:
1
PL0
主程序
2
Error
出错处理,打印出错位置和错误编码
3
GetCh
漏掉空格,读取一个字符
4
GetSym
词法分析,读取一个单词
5
Gen
生成目标代码,并送入目标程序区
编译原理课程设计《 PL/0 扩充》 — 3106006394 方锐洲
第 3
3
3
3
页 共 16
16
16
16
页
《三》符号名字表结构
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 ,array 使用 */
};
struct tablestruct table[txmax]; /* 名字表 */
《四》保留关键字的枚举结构
enum symbol{
nul, ident, number, plus, minus,
times, slash, oddsym, eql, neq,
lss, leq, gtr, geq, lparen,
rparen, comma, semicolon,period, becomes,
beginsym, endsym, ifsym, thensym, whilesym,
writesym, readsym, dosym, callsym, constsym,
varsym, procsym,
elsesym, repeatsym, dowhilesym, returnsym,
forsym,tosym,downtosym,// 增加 for 语句关键字
addbecomes,// 运算符 +=
minusbecomes,// 运算符 -=
timesbecomes,// 运算符 *=
slashbecomes,// 运算符 /=
incsym,// 运算符 ++
decsym,// 运算符 --
lepa,// 数组的左括号 [
ripa,// 数组的右括号 ]
mod,// 取余
};
《五》标识符的类型属性
enum object{
constant,
variable,
procedur,
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
对目标代码的解释执行程序
编译原理课程设计《 PL/0 扩充》 — 3106006394 方锐洲
第 4
4
4
4
页 共 16
16
16
16
页
array,
};
《六》虚拟机代码指令操作码
enum fct{
lit, opr, lod, sto, cal, inte, jmp, jpc,
gar,// 根据栈顶的偏移地址从数组中取值到新的栈顶
sar,// 根据次栈顶的偏移地址把栈顶的值存入数组
shd,// 将栈顶的值下移到次栈顶,栈顶出栈,即次栈顶成为栈顶
del,// 出栈顶
jud,// 判断数组下标合法性
tra,// 将数组的下标范围入栈, gendo(tra,0, 数组下标最大值 );
};
#define fctnum 14
《七》错误信息表 : 采用错误原因说明字符数组来保存错误信息表
char *errortxt[]=
{
// 错误原因 // 出错编号
"", //0 没使用
" 常数说明中的 \"=\" 写成 \":=\"", //1
" 常数说明中的 \"=\" 后应是数字 ", //2
" 常数说明中的标识符后应是 \"=\"", //3
"const,var,procedure 后应为标识符 ", //4
" 漏掉了 \",\" 或者 \";\"", //5
" 过程说明后的符号不正确 //6
(应是语句开始符,或过程定义符) ",
" 应是语句开始符 ", //7
"repeat 语句缺少 \"dowhile\"", //8
" 程序结尾丢了句号 \".\"", //9
" 语句之间漏了 \";\"", //10
" 标识符未说明 ", //11
" 赋值语句中,赋值号左部标识符属性应是变量 ", //12
" 赋值语句左部标识符后应是 //13
赋值号 \":=\" 、 \"+=\" 、 \"-=\" 、 \"*=\" 、 \"/=\"",
"call 后应为标识符 ", //14
"call 后标识符属性应为过程 ", //15
" 条件语句中丢了 \"then\"", //16
" 丢了 \"end\" 或者 \";\"", //17
"while 型循环语句中丢了 \"do\"", //18
"for 语句后跟赋值语句,赋值语句左部是变量,缺少变量 ", //19
" 运算符不是关系运算符 ", //20
" 表达式内标识符属性不能是过程 ", //21
" 表达式中漏掉右括号 ", //22
" 因子后的非法符号 ", //23
" 表达式的开始符不正确 ", //24
" 数组下标定义不符合规定,应为常量 ", //25
" 数组缺少右中括号 \"]\"", //26
" 数组变量后跟着 \"[\"", //27
" 数组下标越界 ", //28
"for 语句中缺少了 \"do\"", //29
" 数字的长度太长 ", //30
" 数超出规定的界限 ", //31
" 当前分程序所在层层次超过规定的最大层次 ", //32
"read 和 write 语句中,缺少右括号 \")\"", //33
"read 和 write 语句中,缺少左括号 ", //34
"read 语句中, () 里必须是标识符 " //35
};
编译原理课程设计《 PL/0 扩充》 — 3106006394 方锐洲
第 5
5
5
5
页 共 16
16
16
16
页
《七》 PL/0 分程序和主要语句的语法描述: 【包括扩充功能的语法描述
】
1 、分程序语法描述:
--------------------------------------------------------------------