编译原理课程设计报告Word文档格式.docx

上传人:b****6 文档编号:19685146 上传时间:2023-01-08 格式:DOCX 页数:18 大小:53.86KB
下载 相关 举报
编译原理课程设计报告Word文档格式.docx_第1页
第1页 / 共18页
编译原理课程设计报告Word文档格式.docx_第2页
第2页 / 共18页
编译原理课程设计报告Word文档格式.docx_第3页
第3页 / 共18页
编译原理课程设计报告Word文档格式.docx_第4页
第4页 / 共18页
编译原理课程设计报告Word文档格式.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

编译原理课程设计报告Word文档格式.docx

《编译原理课程设计报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计报告Word文档格式.docx(18页珍藏版)》请在冰豆网上搜索。

编译原理课程设计报告Word文档格式.docx

二、结构设计说明和各功能模块描述

PL/0语言编译过程采用一趟扫描方式,以语法分析程序为核心,词法分析程序和代码生成程序都作为一个独立的过程,当语法分析需要读单词时就调用词法分析程序,而当语法分析正确需生成相应的目标代码时,则调用代码生成程序.此外,用表格管理程序建立变量、常量和过程标识符的说明与引用之间的信息联系.用出错处理程序对词法和语法分析研究遇到的错误给出在源程序中出错的位置和错误性质.当源程序编译正确时,PL/0编译程序自动调用解释执行,并按用户程序要求输入数据和输出运行结果.

1、编译和解释执行的结构图:

词法分析程序

程序

2、程序总体流程图

3、PL/0编译程序的过程或函数的功能表

过程或函数名

简要功能说明

P10

主程序

error

出错处理

getsym

词法分析,读取一个单词

Getch

漏掉空格,读取一个字符

Gen

生成目标代码,并送入目标程序区

Test

测试当前单词符号是否合法

Block

分程序分析处理过程

Enter

登录名字表

Position

查找标识符在名字表中的位置

Constdeclaration

常量定义处理

Vardeclaration

变量说明处理

Listcode

列出目标代码清单

Statement

语句部分处理

Expression

表达式处理

Term

项处理

Factor

因子处理

Condition

条件处理

Interpret

对目标代码的解释执行程序

Base(函数)

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

4、功能扩充:

(1)增加单词:

保留字ELSE,FOR,TO,DOWNTO运算符+=,-=,++,--,先在SYMBOL中增加ELSESYM,FORSYM,TOSYM,DOWNTOSYM,DOUBLEPLUS,DOUBLEMINUS,PLUSBECOMES,MINUSBECOMES;

然后在保留字表中增加ELSE,FOR,TO,DOWNTO

在词法分析程序里增加下面的程序段:

Else

if(CH=='

+'

){

GetCh();

if(CH=='

='

){SYM=PLUSBECOMES;

GetCh();

}

else

){SYM=DOUBLEPLUS;

elseSYM=PLUS;

}

-'

){SYM=MINUSBECOMES;

){SYM=DOUBLEMINUS;

elseSYM=MINUS;

(2)扩充赋值运算:

+=,-=.此功能扩充只需在语句分析里面进行增加如下代码:

if(SYM==BECOMES||SYM==PLUSBECOMES||SYM==MINUSBECOMES){

if(SYM==BECOMES)

{

GetSym();

EXPRESSION(FSYS,LEV,TX);

if(SYM==PLUSBECOMES||SYM==MINUSBECOMES)

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

if(SYM==PLUSBECOMES){

FACTOR(FSYS,LEV,TX);

GEN(OPR,0,2);

if(SYM==MINUSBECOMES){

GEN(OPR,0,3);

if(i!

=0)

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

(3)扩充FORTO和FORDOWNTO语句,此功能的关键是如何判断条件是否成立,并如何进行程序跳转.在这里用到了几条指令,和地址回填技术.扩充代码如下:

caseFORSYM:

if(SYM!

=IDENT)Error(31);

//FOR后面要标识符

i=POSITION(ID,TX);

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

else

if(TABLE[i].KIND!

=VARIABLE){/*ASSIGNMENTTONON-VARIABLE*/

Error(12);

//变量

}

=BECOMES)

Error(13);

EXPRESSION(SymSetUnion(SymSetNew(TOSYM,DOWNTOSYM,DOSYM),FSYS),LEV,TX);

//表达式

if(SYM==DOWNTOSYM)

CX1=CX;

//保存结果至变量单元

//重新调入栈顶

EXPRESSION(SymSetAdd(DOSYM,FSYS),LEV,TX);

GEN(OPR,0,11);

//判断运算

CX2=CX;

GEN(JPC,0,0);

//如果栈顶非真跳转

///重新调入栈顶

GEN(LIT,0,1);

//送1到栈顶

//减运算

if(SYM==DOSYM){

STATEMENT(FSYS,LEV,TX);

GEN(JMP,0,CX1);

CODE[CX2].A=CX;

elseif(SYM==TOSYM)

GetSym();

//保存结果至变量单元

/重新调入栈顶

//表达式分析

GEN(OPR,0,13);

GEN(LIT,0,1);

//回填地址

elseError(35);

break;

(4)增加运算:

++,--.这两个运算又分为前加,后加,前减,后减.可以单独做为一个语句,也可以放在因子里,所以必须对语句分析程序和因子进行扩充.为了实现在因子里++,--运算特别写了两个函数OPDOUBLE和DOUBLEOP对因子进行操作:

voidDOUBLEOP(){//前加

inti,TX;

SYMBOLDOP;

DOP=SYM;

if(SYM==IDENT){

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

elseif(TABLE[i].KIND==VARIABLE)

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

//将变量放到栈顶

Error(25);

//运算符后必须是变量

//将1取到运行栈顶

if(DOP==DOUBLEPLUS)

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

//存结果

voidOPDOUBLE(inti){//后加

if(i==0)

Error(11);

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

if(SYM==DOUBLEPLUS)

三、主要成分描述

1、符号表

struct{

ALFANAME;

OBJECTSKIND;

union{

intVAL;

/*CONSTANT*/

struct{intLEVEL,ADR,SIZE;

}vp;

/*VARIABLE,PROCEDUR:

*/

};

}TABLE[TXMAX];

在编译程序中符号表用来存放语言程序中出现的有关标识符的属性信息,这些信息集中反映了标识符的语义特征属性.符号表的主要功能如下:

1、收集符号属性

2、上下文语义合法性检查的依据

3、作为目标代码生成阶段地址分配的依据.

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

当源程序经过语法分析,如果未发现错误时,由编译程序调用解释程序,对存放在CODE中的代码CODE[0]开始进行解释执行.当废弃结束后,记录源程序中标识符的TABLE表已没有作用.因此存储区只需以数组CODE存主的只读目标程序和运行机制时的数据区S,S是由解释程序定义的一维整数型数组.解释执行时的数据空间S为栈式计算机的在座空间,遵循后进先出规则,对每个过程(包括主程序)当调用时,才分配数据空间,退出过程进,则所分配原则的数据空间被释放.

解释程序还定义了4个寄存器:

1、指令寄存器.存放当前正在解释的一条目标指令2、程序地址寄存器.指向下一条要执行的目标程序的地址3、栈顶寄存器.4、基址寄存器.指向每个过程被调用时,在数据区S中给它分配原则的数据段起始地址,也称基地址.

3、语法分析方法

语法分析的任务是识别由词法分析给出的单词符号序列在结构上是否符合给定的文法规则.PL/0编译程序的语法分析采用了自顶向下的递归子程序法.粗略地说:

就是对应每个非终结符语法单元,编一个独立的处理过程(或子程序).语法分析研究从读入第一个单词开始由非终结符’程序即开始符出发,沿语法描述图箭头所指出的方向进行分析.当遇到非终结符时,则调用相应的处理过程,从语法描述图看也就进入了一个语法单元,再沿当前所进入的语法描述图的箭头方向进行分析,当遇到描述图中是终结符时,则判断当前读入的单词是否与图中的终结符相匹配,若匹配,则执行相应的语义程序(就是翻译程序).再读取下一个单词继续分析.遇到分支点时将当前的单词与分支点上的多个终结符逐个相比较,若都不匹配时可能是进入下一非终结符语法单位或是出错.

如果一个PL/0语言程序的单词序列在整修语法分析中,都能逐个得到匹配,直到程序结束’.’,这时就说所输入的程序是正确的.对于正确的语法分析做相应的语义翻译,最终得出目标程序.

4、中间代码表示

中间代码表示格式如下:

f

L

a

其中f代表功能码,l表示层次差,也就是变量或过程被引用的分程序与说明该变量或过程的分程序之间的层次差.a的含意对不同的指令有所区别,见下面对每条指令解释说明.

目标指令有8条:

1、LIT:

将常量值取到运行栈顶.a域为常数值.

2、LOD:

将变量放到运行栈顶.a域为变量在所说明层中的相对位置,l为调用层与说明层的层差值.

3、STO:

将栈顶的内容送入某变量单元中.a,l域的含意同LOD指令.

4、CAL:

调用过程的指令.a为被调用过程的目标程序入口地址,l为层差.

5、INT:

为被调用的过程(或主程序)在运行栈中开辟数据区.a域为开辟的单元个数.

6、JMP:

无条件转移指令,a为转向地址.

7、JPC:

条件转移指令,当栈顶的布尔值为非真时,转向a域的地址,否则顺序执行.

8、OPR:

关系运算符和算术运算指令.将栈顶和次栈顶的内容进行运算,结果存放栈顶.具体操作由a域值给出.

四、测试用例

1、后加测试用例:

===COMPILEPL0===

0PROGRAMAA;

0VARI,J;

1BEGIN

2I:

=1;

4J:

=100;

6I:

=J++;

12WRITE(I);

15WRITE(J);

18END.

0JMP01

1INI05

2LIT01

3STO03

4LIT0100

5STO04

6LOD04

7LOD04

8LIT01

9OPR02

10STO04

11STO03

12LOD03

13OPR014

14OPR015

15LOD04

16OPR014

17OPR015

18OPR00

***RUNPL0***

100

101

***ENDPL0***

2、前加测试用例:

===COMPILEPL0===

0PROGRAMMM;

0VARA,B,C;

2A:

=10;

4B:

6++A;

10--B;

14WRITE(A);

17WRITE(B);

20END.

1INI06

2LIT010

4LIT010

6LOD03

7LIT01

8OPR02

9STO03

10LOD04

11LIT01

12OPR03

13STO04

14LOD03

15OPR014

16OPR015

17LOD04

18OPR014

19OPR015

20OPR00

11

9

3、ELSE语句测试用例

0PROGRAMEX01;

=2;

6IFA>

BTHEN

9WRITE(A)

12ELSE

14WRITE(B);

17IFA<

20WRITE(A)

23ELSE

25WRITE(B);

28END.

4LIT02

8OPR012

9JPC014

10LOD03

11OPR014

12OPR015

13JMP017

14LOD04

17LOD03

18LOD04

19OPR010

20JPC025

21LOD03

22OPR014

23OPR015

24JMP028

25LOD04

26OPR014

27OPR015

28OPR00

2

1

4、FORTO语句测试用例

0VARA;

2FORA:

=0TO5

6DO

11WRITE(A);

15END.

1INI04

2LIT00

4LOD03

5LIT05

6OPR013

7JPC015

8LOD03

9LIT01

10OPR02

11LOD03

12OPR014

13OPR015

14JMP03

15OPR00

3

4

5

5、FORDOWNTO语句测试用例

=5DOWNTO0

2LIT05

5LIT00

6OPR011

10OPR03

6+=语句测试用例

*****PL/0CompilerDemo*****

0PROGRAMMAIN;

4A+=1;

8WRITE(A);

11A-=1;

15WRITE(A)

17END.

5LIT01

6OPR02

7STO03

9OPR014

10OPR015

12LIT01

13OPR03

14STO03

15LOD03

五、开发过程与完成情况

经过一周的编译原理课程设计,使我加深了对编译理论知识的理解和掌握,并能达到基本上的运用。

同时也增强了动手和实践的能力。

虽然在遇到了不少困难,但是正因为这些困难,我也学到了更多的东西。

首先,要勇于面对困难,只要敢于去做,并将所学灵活运用,定能取得成功;

其次,我也更好的了解到合作的重要性,在和同学探讨和认真分析后,最终找到解决方案。

程序的最终顺利运行,是离不开同学的互相帮助的。

通过课程设计,知道自己知识的匮乏,认识问题的不全面及在平时的学习中很不扎实,更让自己懂得了学习应该踏踏实实。

最后,我完成了对一些符号,-=,+=运算和FOR语句的扩充,并完成了--,++运算功能的扩充.

这学期的实验和课程设计比较多,在期末的紧张复习的同时,我们也在为课程设计而努力着,虽然时间比较紧,我们还是享受了课程设计过程带给自己对时间的充实、对知识的坚固与扩展。

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

当前位置:首页 > 幼儿教育 > 家庭教育

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

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