编译原理课程设计PL0编辑器扩充Word格式.docx

上传人:b****3 文档编号:14365787 上传时间:2022-10-22 格式:DOCX 页数:20 大小:187.08KB
下载 相关 举报
编译原理课程设计PL0编辑器扩充Word格式.docx_第1页
第1页 / 共20页
编译原理课程设计PL0编辑器扩充Word格式.docx_第2页
第2页 / 共20页
编译原理课程设计PL0编辑器扩充Word格式.docx_第3页
第3页 / 共20页
编译原理课程设计PL0编辑器扩充Word格式.docx_第4页
第4页 / 共20页
编译原理课程设计PL0编辑器扩充Word格式.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

编译原理课程设计PL0编辑器扩充Word格式.docx

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

编译原理课程设计PL0编辑器扩充Word格式.docx

:

=<

表达式>

TO<

DO<

语句>

②FOR<

DOWNTO<

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

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

(3)增加运算:

++和--。

选做内容(成绩评定范围扩大到:

“优”和“良”)

(1)增加类型:

①字符类型;

②实数类型。

(2)扩充函数:

①有返回值和返回语句;

②有参数函数。

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

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

二、结构设计方案

1、结构设计说明:

PL/0的编译程序以语法分析程序为核心,词法分析程序和代码生成程序都作为一个独立的过程,当语法分析需要读单词时就用词法分析程序,而当语法分析正确需生成相应的目标代码时,则调用代码生成程序。

此外,用表格管理程序建立变量,常量和过程标识符的说明与引用之间的信息联系。

用出错处理程序对词法和语法分析遇到的错误给出在源程序中出错的位置和错误性质。

2、各功能模块图示:

3.各功能模块作用表:

1

PL0

主程序

2

Error

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

3

GetCh

漏掉空格,读取一个字符

4

GetSym

词法分析,读取一个单词

5

Gen

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

6

TEST

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

7

ENTER

登录名字表

8

POSITION

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

9

ConstDeclaration

常量定义处理

10

VarDeclaration

变量说明处理

11

ListCode

列出目标代码清单

12

FACTOR

因子处理

13

TERM

项处理

14

EXPRESSION

表达式处理

15

CONDITION

条件处理

16

STATEMENT

语句部分处理

17

Block

分程序分析处理过程

18

BASE

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

19

Interpret

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

3.符号名字表结构:

structtablestruct

{

charname[al];

/*名字*/

enumobjectkind;

/*类型:

const,var,arrayorprocedure*/

intval;

/*数值,仅const使用*/

intlevel;

/*所处层,仅const不使用*/

intadr;

/*地址,仅const不使用*/

intsize;

/*需要分配的数据区空间,仅procedure使用*/

};

4.保留关键字枚举结构:

enumsymbol{

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,elsesym,forsym,tosym,

downtosym,returnsym,pluseql,minuseql,plusplus,

minusminus,

5.名字表中标识符枚举类型:

enumobject{

constant,/*常量*/

variable,/*变量*/

procedur,/*过程*/

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

对于源程序的每一个过程(包括主程序),在被调用时,首先在数据段中开辟三个空间,存放静态链SL、动态链DL和返回地址RA。

静态链记录了定义该过程的直接外过程(或主程序)运行时最新数据段的基地址。

动态链记录调用该过程前正在运行的过程的数据段基址。

返回地址记录了调用该过程时程序运行的断点位置。

对于主程序来说,SL、DL和RA的值均置为0。

静态链的功能是在一个子过程要引用它的直接或间接父过程(这里的父过程是按定义过程时的嵌套情况来定的,而不是按执行时的调用顺序定的)的变量时,可以通过静态链,跳过个数为层差的数据段,找到包含要引用的变量所在的数据段基址,然后通过偏移地址访问它。

  在过程返回时,解释程序通过返回地址恢复指令指针的值到调用前的地址,通过当前段基址恢复数据段分配指针,通过动态链恢复局部段基址指针。

实现子过程的返回。

对于主程序来说,解释程序会遇到返回地址为0的情况,这时就认为程序运行结束。

  解释程序过程中的base函数的功能,就是用于沿着静态链,向前查找相差指定层数的局部数据段基址。

这在使用sto、lod、stoArr、lodArr等访问局部变量的指令中会经常用到。

  类PCODE代码解释执行的部分通过循环和简单的case判断不同的指令,做出相应的动作。

当遇到主程序中的返回指令时,指令指针会指到0位置,把这样一个条件作为终至循环的条件,保证程序运行可以正常的结束。

7.扩充赋值运算:

+=和-=设计:

对于+=、-=、*=和/=赋值运算符,在程序中出现的情况只有如下一种,文法的EBNF表示为:

赋值语句:

=<

标识符>

[+=|-=]<

(1)扩充的语法描述见结构设计中的PL/0分程序和主要语句的语法描述中的描述图;

(2)分析区别赋值运算符采用:

读标识符后再读一个字符,后根据读到的字符转去不同的赋值语句执行。

(3)中间代码生成情况:

+=运算符,其他赋值运算符架构是一样的,只是执行加法改为相应的算数运算。

elseif(sym==pluseql)//检测到+=符号

{

i=position(id,*ptx);

//把类x+=3的x的地址取出来

gendo(lod,lev-table[i].level,table[i].adr);

/*找到变量地址并将其值入栈*/

getsymdo;

if(sym==semicolon)

{

getsymdo;

}

memcpy(nxtlev,fsys,sizeof(bool)*symnum);

expressiondo(nxtlev,ptx,lev);

gendo(opr,0,2);

if(i!

=0)

gendo(sto,lev-table[i].level,table[i].adr);

}

elseif(sym==minuseql)//检测到-=符号

//把类x-=3的x的地址取出来

gendo(opr,0,3);

8.扩充语句(Pascal的FOR语句):

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

Fori:

=E1toE2doS1循环语句ALGOL等价于:

i:

=E1;

gotoOVER;

AGAIN:

i:

=i+2

OVER:

ifi<

E2then

BeginS1;

gotoagainend;

注意程序中基础用到循环控制变量i,因此entry(i)必须被保存下来,而Pascal这样的语言中,循环变量在循环外也是可见的,本次扩充约定循环步长为2或者-2。

具体需要在程序staement()添加for的句法判断:

elseif(sym==forsym)//检测到for语句

getsymdo;

if(sym==ident)

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

else

if(table[i].kind!

=variable)//赋值语句中,赋值号左部标识符属性应是变量

{

error(12);

i=0;

}

else

getsymdo;

if(sym!

=becomes)error(13);

//赋值语句左部标识符后应是赋值号:

=

elsegetsymdo;

memcpy(nxtlev,fsys,sizeof(bool)*symnum);

nxtlev[tosym]=true;

//后跟符to和downto

nxtlev[downtosym]=true;

expressiondo(nxtlev,ptx,lev);

//处理赋值语句右部的表达式E1

gendo(sto,lev-table[i].level,table[i].adr);

//保存初值

switch(sym)

{

casetosym:

//步长为的向上增加

getsymdo;

cx1=cx;

//保存循环开始点

//将循环判断变量取出放到栈顶

gendo(lod,lev-table[i].level,table[i].adr);

memcpy(nxtlev,fsys,sizeof(bool)*symnum);

//处理表达式E2

nxtlev[dosym]=true;

//后跟符do

expressiondo(nxtlev,ptx,lev);

gendo(opr,0,13);

//生成比较指令,i是否小于等于E2的值

cx2=cx;

//保存循环结束点

//生成条件跳转指令,跳出循环,跳出的地址未知

gendo(jpc,0,0);

if(sy

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

当前位置:首页 > 初中教育 > 语文

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

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