编译原理实践报告
- 格式:doc
- 大小:518.00 KB
- 文档页数:20
编译原理
课程实践报告书
学员姓名:
学 号:
专 业:
年 级:
年 月 日
课程实践报告书
2 1、课程实践目的
本次是实践的目的旨在加强学生对编译过程的整体认识,通过扩充PL语言编译器,加深对词法分析、语法分析和中间代码生成的原理的理解。
2、任务概述
本次实践的任务包括源程序的分析,扩充repeat、for、case等语言成分。
3、实现方法
3.1、准备工作:
1、在词法库中添加repeat、until、for、to、case等;
2、添加repeat、for、case等语句的分析函数;
3、修改初始化工作(修改void INITIAL()函数);
4、增加相应常量的定义。
3.2、repeat语句的扩充方法:
PL语言中的repeat语句语法如下:
repeat
S1
until E;
其中E为布尔表达式。
实现函数如下:
void REPEATMENT(SYMLIST * list) //repeat 语句的分析
{
TYPEITEM typeItem;
int jumpback; 课程实践报告书
3
JUMADRTAB[JX]=CX;
JX++;
jumpback=CX; //纪录repeat循环执行时需要往前返回的地址
getASymbol();
while(CurSymbol->type!=UNTILSYM)
{
STATEMENT(list); //分析语句
if(CurSymbol->type==SEMICOLON)
getASymbol();
}
if(CurSymbol->type==UNTILSYM)
getASymbol();
/////////////////////////////////////////////////////////////////
SYMLIST * tempList=new SYMLIST;
COPYLIST(tempList,listAddSym(list,UNTILSYM));
EXPRESSION(tempList,typeItem);
delete tempList;
/////////////////////////////////////////////////////////////////
if(typeItem.typ!=BOOLS)
error(32); //if或while或until后面的表达式类型应该是布尔类课程实践报告书
4 型
GEN(JPC,0,jumpback);
}
词法分析器识别repeat后,调用REPEATMENT()函数,进行语法分析。REPEATMENT()函数首先翻译repeat语句的循环体S1,识别until后翻译条件表达式E。E的false出口为语句S1,true的出口为下一语句。
3..3、for语句的扩充方法:
PL语言中的for语句语法如下:
for Q1 to V do
S1
其中Q1为赋值语句,V为整型表达式。
实现函数如下:
void FORMENT(SYMLIST * list) //for 语句的分析
{
TYPEITEM typeItem;
int jumpback,fillBackFalse;
int a_level,a_address;//记录循环变量的层次和地址
getASymbol();
int x;
x=GETPOSITION(CurSymbol->value.lpValue); //查表
if(x!=0)
{
a_level = NAMETAB[x].level; 课程实践报告书
5 a_address = NAMETAB[x].unite.address;
}
STATEMENT(list); //分析语句
JUMADRTAB[JX]=CX;
JX++;
jumpback=CX; //纪录for循环执行时需要往前返回的地址
if(CurSymbol->type==TOSYM)
getASymbol();
else
error(44);//应该是'to'
GEN(LOD,a_level,a_address);//取a
/////////////////////////////////////////////////////////////////
SYMLIST * tempList=new SYMLIST;
COPYLIST(tempList,listAddSym(list,DOSYM));
EXPRESSION(tempList,typeItem);
delete tempList;
/////////////////////////////////////////////////////////////////
if(typeItem.typ!=INTS)
error(45); //to后面的表达式类型应该是整型
GEN(LE,0,0);//比较a<=b 课程实践报告书
6
fillBackFalse=CX; //条件测试失败后从哪里往循环“外”跳
GEN(JPC,0,0);
if(CurSymbol->type==DOSYM)
getASymbol();
else
error(9);//应该是'do'
STATEMENT(list); //分析语句
GEN(LODA,a_level,a_address);//取a地址
GEN(LOD,a_level,a_address);//取a值
GEN(LIT,0,1);//取常量1
GEN(ADD,0,0);//a自增
GEN(STO,0,0);
GEN(JMP,0,jumpback);
CODE[fillBackFalse].address=CX; //回填
JUMADRTAB[JX]=CX;
JX++;
}
词法分析器识for后,调用FORMENT()函数,进行语法分析。FORMENT()函数首先翻译赋值语句Q1,识别to后解释表达式V,后将赋值语句中的变量与V做比较,true的出口为下一语句,false出口为for语句的后继。最后翻译语句S1,并产生jmp指令跳回到V表达式解释的一步。 课程实践报告书
7 3.4、case语句的扩充方法:
PL语言中的repeat语句语法如下:
case V of
C1: S1;
C2: S2;
„
Cn-1:Sn-1;
otherwise: Sn
其中V为变量。
实现函数如下:
void CASEMENT(SYMLIST * list) //case 语句的分析
{
TYPEITEM typeItem;
int e_level=0,e_address=0;
int back[100];//goto next
int backFalse[100];//跳到下一个判断
int num=0;
int leap=0;
getASymbol();
if(CurSymbol->type==IDENT)
{
int x;
x=GETPOSITION(CurSymbol->value.lpValue); //查表
if(x!=0) 课程实践报告书
8 {
e_level = NAMETAB[x].level;
e_address = NAMETAB[x].unite.address;
if(NAMETAB[x].kind!=VARIABLE)
error(16);//应该是变量
}
}
else
error(14);//应该是标识符
getASymbol();
if(CurSymbol->type==OFSYM)
getASymbol();
else
error(10);
GEN(LOD,e_level,e_address);
//////////////////////////////////////////////////////////
SYMLIST * tempList=new SYMLIST;
COPYLIST(tempList,listAddSym(list,COLON));
EXPRESSION(tempList,typeItem);
delete tempList;
//////////////////////////////////////////////////////////
if(CurSymbol->type==COLON)