Author: 王景诗 山东大学 SDU
试验题目编译原理
班级 学号
姓名 日期 2007,12,10
软件环境
Microsoft Visual C++ 6.0
程序功能描述
程序是一个简单的对 pl/0 语言的解释执行程序。编译的课程还未结束,我们所学
的知识还不是足够充分;一个完备的编译程序要考虑到方方面面的细节问题,这对
于我们来说十分困难,所以我对编译进行了很多简单化处理。其中一些处理的简单
化程度是令人不可饶恕的。
在程序中,pl/0 语言编写的程序放在一个文件“code_le.text”中,当编译程序时,自
己编写的编译器会自动使用文件流打开文件,对其中的程序进行编译。编译后的中
间代码在控制台打印出来。
Author: 王景诗 山东大学 SDU
程序输入输出
一、程序输入:
程序输入是在文本文件 code_le.text 中。
code_le.text 中的内容如下:
CONST A=10;
VAR B,C;
PROCEDURE P;
BEGIN
C=B+A
END;
BEGIN
READ(B);
WHILE B#0 DO
BEGIN
CALL P;
WRITE (2*C);
READ(B);
END
END
二、程序输出:
程序在控制台中输出编译后的中间代码,代码如下:
Author: 王景诗 山东大学 SDU
程序主要代码
1.编译程序主要函数接口定义如下:
1.1 词法分析部分
void GetChar();//将下一个字符读到 ch 中
void GetBC();//检查 ch 中是否为空白
void Concat();//将 ch 中的字符连接到 strToken 之后
bool IsLetter();//判断 ch 中是否为字母
bool IsDigit();//判断 ch 中是否为数字
int Reserve();//返回保留字编码
void Retract();//回调一个字符
int InsertId();//将 strToken 中的标志符插入符号表,返回符号表的指针
int InsertConst();//将 strToken 中的标志符插入常数表,返回常数表指针
void GETSYM();//词法分析
文件结束
1.2 语法分析部分
void block(int lev,int dx,int tab_i);//语法分析
void create_const(int lev);//造常数表
void create_var(int lev);//造变量表
void create_pro(int lev);//造过程表
void output_tab();//输出 table
1.3 中间代码生成部分
void translate_pl();//翻译模式
int pos();//返回 table 表指针
void out_code();//显示代码
void sub_begin_pro();//子过程调用
void begin_pro();//开始函数
int pos_pro();//查找地址
2.编译程序主要函数代码:(注:由于词法分析与语法分析的程序已经交上
了,所以这里只给出中间代码生成的主要函数代码)
2.1 翻译的总控函数
//翻译 语言为中间代码
int i; //循环使用的变量
int pro_i; //记录变量在 tab 表中的索引
int var_num=0; //记录一个过程中所定义的变量的个数
string mid_name[5]; //用于存储部分中间变量
block(0,0,0); //语法分析,生成 tab 表
goback(); //返回文件头,在进行一次扫描
while(ifend()) //函数没有结束
{
GETSYM(); //读取一个字符
if(SYM=="PROCEDURESYM")//子过程的声明
{GETSYM();
Author: 王景诗 山东大学 SDU
程序主要代码
GETSYM();
GETSYM();
if(SYM=="BEGINSYM")//子过程调用
{
mem_pl[0].pro=pro_na;//记录过程名
mem_pl[0].addr=code_pc;//记录子过程的起始地址
sub_begin_pro(); //对子过成进行翻译
}//end if(SYM=="BEGINSYM")//子过程调用
}//end if(SYM=="PROCEDURESYM")//子过程的声明
if(SYM=="BEGINSYM")//pl/0 程序的主过程调用开始
{
begin_pro();//主过程调用
}//end if(SYM=="BEGINSYM")
}
2.1 子过程的翻译
void accidence::sub_begin_pro()
{ int i; //计数变量
int pro_i; //记录在 tab 表中的索引
int var_num=0; //变量的数目
int old_level=pro_level;//记录下上一层的层号
find=pro_na;
pro_i=pos();//名称的 tab 表位置
pro_level=tab[pro_i].level+1;//所在层的层号
for(i=0;i<adr;i++)
if(tab[i].level==pro_level)
var_num++; //计算变量的数目
code_pl[code_pc].code_p="int ";
code_pl[code_pc].code_a=tab[pro_i].level;
code_pl[code_pc].code_b=3+var_num;//开辟空间
code_pc++; //移动指针
//++++++++++++++++++++
GETSYM();
GETSYM(); //获取下一个字符
if(SYM=="IDENT")//处理赋值语句
{
mid_name[0]=strToken;
GETSYM();
Author: 王景诗 山东大学 SDU
程序主要代码
!"翻译赋值语句
!#$调用词法分析程序
%%&'($)
!#$调用词法分析程序
%%&*($)+,
!#$调用词法分析程序
%%&-($)
处理第一个变量
.%%&'(
获取第一个变量在 $ 表中的位置
处理变量,生成相应得中间代码
&(/)01
&(/
&(/,&(/
&(/&(/2+-
++
&(/)34"$
&(/
&(/
&(/
++
处理第二个变量
.%%&-(
&(/)01
&(/
&(/,&(/
&(/&(/2+-
++
&(/)34"$
&(/
&(/
&(/
++