最新版编译原理毕业课程设计与报告.docx

上传人:b****5 文档编号:11692519 上传时间:2023-03-30 格式:DOCX 页数:27 大小:40.48KB
下载 相关 举报
最新版编译原理毕业课程设计与报告.docx_第1页
第1页 / 共27页
最新版编译原理毕业课程设计与报告.docx_第2页
第2页 / 共27页
最新版编译原理毕业课程设计与报告.docx_第3页
第3页 / 共27页
最新版编译原理毕业课程设计与报告.docx_第4页
第4页 / 共27页
最新版编译原理毕业课程设计与报告.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

最新版编译原理毕业课程设计与报告.docx

《最新版编译原理毕业课程设计与报告.docx》由会员分享,可在线阅读,更多相关《最新版编译原理毕业课程设计与报告.docx(27页珍藏版)》请在冰豆网上搜索。

最新版编译原理毕业课程设计与报告.docx

最新版编译原理毕业课程设计与报告

 

课程设计

课程名称__编译原理_

题目名称PL/0语言的扩充

学生学院___计算机学院______

专业班级_软件工程07级4班__

学号

学生姓名

指导教师____李小妹________

 

2008年1月5日

课程设计实验报告

一、概述:

源语言:

PL/0

目标语言:

目标代码(生成的文件后缀为*.COD)

实验工具:

BorlandC++Builder6

运行平台:

WindowsXP

目的:

在分析理解一个教学型编译程序(如PL/0)的基础上,对其词法分析程序、语法分析程序和语义处理程序进行部分修改扩充。

达到进一步了解程序编译过程的基本原理和基本实现方法的目的。

要求:

对PL/0作以下修改扩充:

基本内容

(1)扩充赋值运算:

+=和-=

(2)扩充语句(Pascal的FOR语句):

①FOR<变量>:

=<表达式>TO<表达式>DO<语句>

②FOR<变量>:

=<表达式>DOWNTO<表达式>DO<语句>

其中,语句①的循环变量的步长为1,

语句②的循环变量的步长为-1。

选做内容

(1)增加运算:

++和--。

(2)增加类型:

①字符类型;②实数类型。

(3)扩充函数:

①有返回值和返回语句;②有参数函数。

(4)增加一维数组类型(可增加指令)。

(5)其他典型语言设施。

二、结构设计说明:

各功能模块描述

Error()

出错处理,打印出错位置和错误编码

GetCh()

漏掉空格,读取一个字符

GetSym()

词法分析,读取一个单词

GEN()

目标代码生成过程,本过程用于把生成的目标代码写入目标代码数组,供后面的解释器解释执行

TEST()

测试当前单词是否合法过程test

ENTER()

登陆符号表过程enter

POSITION()

在符号表中查找指定符号所在位置的函数position

VARDECLARATION()

变量声明处理

LISTCODE()

输出目标代码清单;

FACTOR()

因子处理过程factor

TERM()

项处理过程term;

EXPRESSION()

表达式处理过程

CONDITION()

条件处理过程

STATEMENT()

语句处理过程

BLOCK()

编译程序主体,语法分析过程

BASE()

通过静态链求出数据区基地址的函数,

INTERPRET()

对目标代码解释运行过程

Pl0编译程序的结构

编译程序的总体流程图

词法分析状态转换图

.○表示状态,对应每个状态编一段程序,每个状态调用取字符程序,根据当前字符转到不同的状态,并做相应操作。

◎表示终态,已识别出一个单词

语法调用关系图

主要成分描述

1.符号表

在编译程序中符号表用来存放语言程序中出现的有关标识符的属性信息,符号表中所登记的信息在编译的不同阶段都要用到。

在语义分析中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的说明是否一致)和产生中间代码。

在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的依据。

对一个多遍扫描的编译程序,不同遍所用的符号表也往往各有不同。

因为每遍所关心的信息各有差异。

一张符号表的每一项(或称入口才包含两大栏(或称区段、字域),即名字栏(NAME)信息栏(INFORMATION)

 信息栏包含许多子栏和标志位,用来记录相应名字和种种不同属性,由于查填符号表一般是通过匹配名字来寮现的,因此,名字栏也称主栏。

主栏的内容称为关键字(keyword)。

2.运行时存储组织和管理

由于编译时目标程序运行的数据空间大小已经规定,所以存储组织属于静态存储。

源程序的标识符存放在TABLE表中,目标代码存放在CODE中,S是由解释程序定义的一维整型数组,是程序运行时的数据存储空间。

3.语法分析方法

自顶向下的语法分析:

<程序>

<分程序>.

<变量说明部分><语句>

VAR<标识符>;<复合语句>

ABEGIN<语句>END

<读语句>

READ(<标识符>)

A

4.中间代码表示

对PL/0编译程序的目标代码的指令格式描述如下:

fla

其中f代表功能码,l表示层次差,a的含意对不同的指令有所区别,见下面对每条指令的解释说明:

lit0a

将常数值取到栈顶,a为常数值

Lodla

将变量值取到栈顶,a为偏移量,l为层差

Stola

将栈顶内容送入某变量单元中,a为偏移量,l为层差

Calla

调用过程,a为过程地址,l为层差

Int0a

在运行栈中为被调用的过程开辟a个单元的数据区

jmp0a

无条件跳转至a地址

Jpc0a

条件跳转,当栈顶布尔值非真则跳转至a地址,否则顺序执行

opr00

过程调用结束后,返回调用点并退栈

opr01

栈顶元素取反

opr02

次栈顶与栈顶相加,退两个栈元素,结果值进栈

opr03

次栈顶减去栈顶,退两个栈元素,结果值进栈

opr04

次栈顶乘以栈顶,退两个栈元素,结果值进栈

opr05

次栈顶除以栈顶,退两个栈元素,结果值进栈

opr06

栈顶元素的奇偶判断,结果值在栈顶

opr07

opr08

次栈顶与栈顶是否相等,退两个栈元素,结果值进栈

opr09

次栈顶与栈顶是否不等,退两个栈元素,结果值进栈

opr010

次栈顶是否小于栈顶,退两个栈元素,结果值进栈

opr011

次栈顶是否大于等于栈顶,退两个栈元素,结果值进栈

opr012

次栈顶是否大于栈顶,退两个栈元素,结果值进栈

opr013

次栈顶是否小于等于栈顶,退两个栈元素,结果值进栈

opr014

栈顶值输出至屏幕

opr015

屏幕输出换行

opr016

从命令行读入一个输入置于栈顶

三、程序代码:

扩充后修改的部分代码

typedefenum{

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,PROGSYM,

PLUSBK,MINUSBK,

SQLPAREN,SQRPAREN,

INC,DEC,ELSESYM,FORSYM,TOSYM,DOWNTOSYM,

RETURNSYM

}SYMBOL;

//添加SQLPAREN,SQRPAREN,INC,DEC,ELSESYM,FORSYM,TOSYM,DOWNTOSYM,RETURNSYM

char*SYMOUT[]={

"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","PROGSYM",

"PLUSBK","MINUSBK",

"SQLPAREN","SQRPAREN",

"INC","DEC","ELSESYM","FORSYM","TOSYM","DOWNTOSYM",

"RETURNSYM"

};//添加"INC","DEC","ELSESYM","FORSYM","TOSYM","DOWNTOSYM"

//设置保留字名字

strcpy(KWORD[1],"BEGIN");

strcpy(KWORD[2],"CALL");

strcpy(KWORD[3],"CONST");

strcpy(KWORD[4],"DO");

strcpy(KWORD[5],"DOWNTO");//downto

strcpy(KWORD[6],"ELSE");//else

strcpy(KWORD[7],"END");

strcpy(KWORD[8],"FOR");//for

strcpy(KWORD[9],"IF");

strcpy(KWORD[10],"ODD");

strcpy(KWORD[11],"PROCEDURE");

strcpy(KWORD[12],"PROGRAM");

strcpy(KWORD[13],"READ");

strcpy(KWORD[14],"RETURN");//return

strcpy(KWORD[15],"THEN");

strcpy(KWORD[16],"TO");//to

strcpy(KWORD[17],"VAR");

strcpy(KWORD[18],"WHILE");

strcpy(KWORD[19],"WRITE");

//设置保留字符号

WSYM[1]=BEGINSYM;

WSYM[2]=CALLSYM;

WSYM[3]=CONSTSYM;

WSYM[4]=DOSYM;

WSYM[5]=DOWNTOSYM;//downto

WSYM[6]=ELSESYM;//else

WSYM[7]=ENDSYM;

WSYM[8]=FORSYM;//for

WSYM[9]=IFSYM;

WSYM[10]=ODDSYM;

WSYM[11]=PROCSYM;

WSYM[12]=PROGSYM;

WSYM[13]=READSYM;

WSYM[14]=RETURNSYM;//return

WSYM[15]=THENSYM;

WSYM[16]=TOSYM;//to

WSYM[17]=VARSYM;

WSYM[18]=WHILESYM;

WSYM[19]=WRITESYM;

词法分析,获取一个符号

voidGetSym(){

longi,J,K;ALFAA;

while(CH<='')GetCh();

if(CH>='A'&&CH<='Z'){/*IDORRESERVEDWORD*/

K=0;

do{

if(K

GetCh();

}while((CH>='A'&&CH<='Z')||(CH>='0'&&CH<='9'));

A[K]='\0';

strcpy(ID,A);

i=1;J=NORW;

do{

K=(i+J)/2;

if(strcmp(ID,KWORD[K])<=0)J=K-1;

if(strcmp(ID,KWORD[K])>=0)i=K+1;

}while(i<=J);

if(i-1>J)SYM=WSYM[K];//if(SYM==ELSESYM)

elseSYM=IDENT;

}

else

if(CH>='0'&&CH<='9'){/*NUMBER*/

K=0;NUM=0;SYM=NUMBER;

do{

NUM=10*NUM+(CH-'0');

K++;GetCh();

}while(CH>='0'&&CH<='9');

if(K>NMAX)Error(30);

}

else

if(CH==':

'){

GetCh();

if(CH=='='){SYM=BECOMES;GetCh();}

elseSYM=NUL;

}

else/*THEFOLLOWINGTWOCHECKWEREADDED

BECAUSEASCIIDOESNOTHAVEASINGLECHARACTERFOR<=OR>=*/

if(CH=='<'){

GetCh();

if(CH=='='){SYM=LEQ;GetCh();}

else

if(CH=='>'){SYM=NEQ;GetCh();}//3修改不等号<>

elseSYM=LSS;

}

else

if(CH=='>'){

GetCh();

if(CH=='='){SYM=GEQ;GetCh();}

elseSYM=GTR;

}

else//4添加+=,-=,++,--

if(CH=='+'){

GetCh();

if(CH=='=')

{

SYM=PLUSBK;

GetCh();

}

else

if(CH=='+')

{

SYM=INC;

GetCh();

}

else{SYM=PLUS;}

}

else

if(CH=='-'){

GetCh();

if(CH=='=')

{

SYM=MINUSBK;

GetCh();

}

else

if(CH=='-')

{

SYM=DEC;

GetCh();

}

else{SYM=MINUS;}

}

else

if(CH=='/'){

charc=LINE[CC];

if(c=='/')

{

CC=LL;//for(inti=0;i<81;i++)LINE[i]='';

GetCh();

GetSym();

}

else

{//Form1->printls("JJJ",55);

SYM=SLASH;GetCh();

}

}

else

{

SYM=SSYM[CH];GetCh();

}

//语句处理

voidSTATEMENT(SYMSETFSYS,intLEV,int&TX){/*STATEMENT*/

inti,CX1,CX2,CX3,tm=0,jk=0;

FCTSTOMode[3]={STO,STOARR,STOVAR};

FCTLODMode[3]={LOD,LODARR,LODVAR};

SYMBOLTemp;

switch(SYM){

caseIDENT:

i=POSITION(ID,TX);

if(i==0)Error(11);

else

if(TABLE[i].KIND!

=VARIABLE){/*ASSIGNMENTTONON-VARIABLE*/

Error(12);i=0;

}

GetSym();

switch(SYM)

{//添加INC,DEC,PLUSBK,MINUSBK

caseBECOMES:

GetSym();

EXPRESSION(FSYS,LEV,TX);

if(i!

=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);

break;

caseINC:

//++运算

GetSym();

GEN(LODMode[jk],LEV-TABLE[i].vp.LEVEL+tm,TABLE[i].vp.ADR);

GEN(LIT,0,1);

GEN(OPR,0,2);

GEN(STOMode[jk],LEV-TABLE[i].vp.LEVEL+tm,TABLE[i].vp.ADR);

break;

caseDEC:

//--运算

GetSym();

GEN(LODMode[jk],LEV-TABLE[i].vp.LEVEL+tm,TABLE[i].vp.ADR);

GEN(LIT,0,1);

GEN(OPR,0,3);

GEN(STOMode[jk],LEV-TABLE[i].vp.LEVEL+tm,TABLE[i].vp.ADR);

break;

casePLUSBK:

caseMINUSBK:

intflag=SYM;//flag是一个局部整型变量

GetSym();

GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);

EXPRESSION(FSYS,LEV,TX);

if(flag==PLUSBK)GEN(OPR,0,2);

elseGEN(OPR,0,3);

GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);

break;

//default:

Error(13);GetSym();

}

break;

caseREADSYM:

GetSym();

if(SYM!

=LPAREN)Error(34);

else

do{

GetSym();

if(SYM==IDENT)i=POSITION(ID,TX);

elsei=0;

if(i==0)Error(35);

else{

GEN(OPR,0,16);

GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);

}

GetSym();

}while(SYM==COMMA);

if(SYM!

=RPAREN){

Error(33);

while(!

SymIn(SYM,FSYS))GetSym();

}

elseGetSym();

break;/*READSYM*/

caseWRITESYM:

GetSym();

if(SYM==LPAREN){

do{

GetSym();

EXPRESSION(SymSetUnion(SymSetNew(RPAREN,COMMA),FSYS),LEV,TX);

GEN(OPR,0,14);

}while(SYM==COMMA);

if(SYM!

=RPAREN)Error(33);

elseGetSym();

}

GEN(OPR,0,15);

break;/*WRITESYM*/

caseCALLSYM:

GetSym();

if(SYM!

=IDENT)Error(14);

else{

i=POSITION(ID,TX);if(i==0)Error(11);

GetSym();

if(SYM==LPAREN)

{

GetSym();

intk=0;

EXPRESSION(SymSetUnion(SymSetNew(RPAREN,COMMA),FSYS),LEV,TX);

GEN(PUSH,0,k);

k++;

while(SYM==COMMA)

{

GetSym();

EXPRESSION(SymSetUnion(SymSetNew(RPAREN,COMMA),FSYS),LEV,TX);

GEN(PUSH,0,k);

k++;

}

if(SYM==RPAREN)GetSym();

elseForm1->printls("错误CALL",400);

//Strings=IntToStr(i);

//Form1->printls(s.c_str(),700);

GEN(CAL,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);

}

else

{

if(TABLE[i].KIND==PROCEDUR)

GEN(CAL,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);

elseError(15);

}

}

break;

caseIFSYM:

GetSym();

CONDITION(SymSetUnion(SymSetNew(THENSYM,DOSYM,ELSESYM),FSYS),LEV,TX);

if(SYM==THENSYM)GetSym();

elseError(16);

CX1=CX;

GEN(JPC,0,0);

STATEMENT(SymSetUnion(SymSetNew(IDENT,ELSESYM,SEMICOLON),FSYS),LEV,TX);

if(SYM!

=SEMICOLON)Form1->printls("错误IF",300);

elseGetSym();

if(SYM!

=ELSESYM)

{

b=1;

CODE[CX1].A=CX;

return;

}

else//6添加else

{

GetSym();

CX2=CX;

GEN(JMP,0,0);

STATEMENT(FSYS,LEV,TX);

CODE[CX1].A=CX2+1;

CODE[CX2].A=CX;

}

break;

caseBEGINSYM:

GetSym();

STATEMENT(SymSetUnion(SymSetNew(SEMICOLON,ENDSYM),FSYS),LEV,TX);

while(SYM==IDENT||SymIn(SYM,SymSetAdd(SEMICOLON,STATBEGSYS))){

if(SYM==SEMICOLON||b){if(b)b=0;elseGetSym();}

elseError(10);

STATEMENT(SymSetUnion(SymSetNew(SEMICOLON,ENDSYM),FSYS),LEV,TX);

}

if(SYM==ENDSYM)GetSym();

elseError(17);

break;

caseWHILESYM:

CX1=CX;GetSym();CONDITION(SymSetAdd(DOSYM,FSYS),LEV,TX);

CX2=CX;GEN(JPC,0,0);

if(SYM==DOSYM)GetSym(

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1