编译原理实践报告

  • 格式: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)