PLX编译程序改进与扩展设计书.docx

上传人:b****3 文档编号:11204626 上传时间:2023-05-29 格式:DOCX 页数:34 大小:379.10KB
下载 相关 举报
PLX编译程序改进与扩展设计书.docx_第1页
第1页 / 共34页
PLX编译程序改进与扩展设计书.docx_第2页
第2页 / 共34页
PLX编译程序改进与扩展设计书.docx_第3页
第3页 / 共34页
PLX编译程序改进与扩展设计书.docx_第4页
第4页 / 共34页
PLX编译程序改进与扩展设计书.docx_第5页
第5页 / 共34页
PLX编译程序改进与扩展设计书.docx_第6页
第6页 / 共34页
PLX编译程序改进与扩展设计书.docx_第7页
第7页 / 共34页
PLX编译程序改进与扩展设计书.docx_第8页
第8页 / 共34页
PLX编译程序改进与扩展设计书.docx_第9页
第9页 / 共34页
PLX编译程序改进与扩展设计书.docx_第10页
第10页 / 共34页
PLX编译程序改进与扩展设计书.docx_第11页
第11页 / 共34页
PLX编译程序改进与扩展设计书.docx_第12页
第12页 / 共34页
PLX编译程序改进与扩展设计书.docx_第13页
第13页 / 共34页
PLX编译程序改进与扩展设计书.docx_第14页
第14页 / 共34页
PLX编译程序改进与扩展设计书.docx_第15页
第15页 / 共34页
PLX编译程序改进与扩展设计书.docx_第16页
第16页 / 共34页
PLX编译程序改进与扩展设计书.docx_第17页
第17页 / 共34页
PLX编译程序改进与扩展设计书.docx_第18页
第18页 / 共34页
PLX编译程序改进与扩展设计书.docx_第19页
第19页 / 共34页
PLX编译程序改进与扩展设计书.docx_第20页
第20页 / 共34页
亲,该文档总共34页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

PLX编译程序改进与扩展设计书.docx

《PLX编译程序改进与扩展设计书.docx》由会员分享,可在线阅读,更多相关《PLX编译程序改进与扩展设计书.docx(34页珍藏版)》请在冰点文库上搜索。

PLX编译程序改进与扩展设计书.docx

PLX编译程序改进与扩展设计书

PL/X编译程序改进及扩展设计书

1介绍

1.1前言

根据课程设计要求制作PL/X语言的编译器,完成词法分析、语法分析、语义分析及代码生成、出错处理和解释运行程序,并添加一定的扩展,最终实现一个PL/X的编译器。

所完成扩展点说明:

1)支持三种注释

a)单行注释

b)/*---*/多行注释

c)(*---*)多行注释

2)支持read语句,因此可从终端获取输入

3)支持write语句,因此可从终端输出

4)支持for语句

5)支持do…while语句

6)call过程

7)求余运算%

8)整数的奇偶odd

9)幂运行**

10)求阶乘!

11)求和$

关于出错处理:

分为词法分析错误、句法分析错误、运行时错误(如除数为0)

允许变量名或函数名重复,但访问的时候以最后一次声明的为有效

2编译器

2.1PL/X编译器结构概述

图1PL/X编译程序的结构图

图2PL/X的解释执行结构

图3PL/X编译程序总体流程图

语法分析过程PROG是整个编译过程的核心,是指开始由主程序调用GETSYM取一个单词,再调用语法分析过程PROG,PROG由当前单词根据语法规则再调用其它过程,如说明处理、代码生成或出错处理等过程进行分析,当分析完一个单词后,PROG再调用GETSYM取下一个单词,一直重复到当前单词为结束符"."表明源程序已分析结束。

若未取到结束符".",而源程序已没有输入符号,这时表明源程序有错误,无法再继续分析。

 

图4PL/X过程调用相关示意图

2.2语法元素

关键字:

"and","begin","call","case","constant","do","else","end","false","for","if","integer","logical","not","or",“odd”,"procedure","program","read","repeat","switch","then","true","until","while","write"

操作符:

".",";","**","++",“--","+","-","*","/","%","=","<","<=",">",">=","==","!

","+=","-=","*=","/="

2.3语法图

程序

 

程序体

const

ident

number

=

var

;

ident

procedure

ident

;

;

程序体

;

 

 

语句序列

 

语句

 

条件

表达式

odd

表达式

=

<>

<

>

<=

>=

表达式

 

表达式

 

因子

因子

/

*

++

%

**

--

 

因子

 

 

1)prog="program"ds{proc}"begin"ss"end""."

2)proc="procedure"aident[ds]"begin"ss"end"

3)ds=d{";"d}

4)d="integer"aident{","aident}|

"logical"bident{","bident}|

"constant"aident"="number{","aident"="number}

5)ss=s{;s}

6)s=aident":

="ae|

bident":

="be|

"if"be"then"ss["else"ss]"end"|

"while"be"do"ss"end"|

"repeat"ss"until"be|

"write"ae.

"read"aident|bident

"for"s;be;s"do"ss"end"

"call"procedure

"do"ss".""while"be"end"

7)ae=["-"]at{("-"|"+")at}

8)at=af1{("*"|"/")af1}.

9)af1=af{("%"|"**")af}.//扩展的求余运算

10)af=aident|number|"("ae")"|constant

11)be=bt{"or"bt}

12)bt=bf{"and"bf}

13)bf=bident|"true"|"false"|"not"bf|"("be")"|re1

14)re1=oddre

15)re=(aident|number)("="|">"|">="|"<"|"<="|"/=")ae

16)ds=d{";"d}

2.4判断是否符合两条限制规则

1)结构:

B1={proc}

First(B1)={“procedure”};

Follow(B1)={“begin”};

B2=[ds]

First(B2)={“integer”,“logical”,“constant”};

Follow(B1)={“begin”};

B3={";"d}

First(B3)={“;”};

Follow(B3)={“procedure”,“begin”};

B4={","aident}

First(B4)={“,”};

Follow(B4)={“;”,“procedure”,“begin”};

B5={","bident}

First(B5)={“,”};

Follow(B5)={“;”,“procedure”,“begin”};

B6={","aident"="number}

First(B6)={“,”};

Follow(B6)={“;”,“procedure”,“begin”};

B7={;s}

First(B7)={“;”};

Follow(B7)={“end”,“until”,“else”};

B8=["else"ss]

First(B8)={“else”};

Follow(B8)={“end”};

B9=["-"]

First(B9)={“-”};

Follow(B9)={“(”,“aident”,“number”,“constant”};

B10={("-"|"+")at}

First(B10)={“-”,“+”};

Follow(B10)={“end”,“until”,“else”,“)”,“and”,“or”};

B11={"or"bt}

First(B11)={“or”};

Follow(B11)={“then”,“do”,“;”,“)”,“end”,“until”,“else”};

B12={("*"|"/")af}

First(B12)={"*","/"};

Follow(B12)={“+”,“-“,“end”,“until”,“else”,“)”,“and”,“or”};

B13={"and"bf}

First(B13)={"and”};

Follow(B13)={“or”,“then”,“do”,“;”,“)”,“end”,“until”,“else”};

2).判断是否符合两条限制规则

规则1:

找出图中每一个分支点,考察每个分支点的各个分支的头符号是否相异

规则2:

找出图中每一个结构,考察每个结构的头符号集合与其跟随符号是否相异

非终结符名

开始符号集合

后继符号集合

分程序

constvarprocedureidentifcallbeginwhilereadwrite

.;

语句

identcallbeginifwhilereadwrite

.;end

条件

odd+-(

identnumber

thendo

表达式

+-(

identnumber

.;)

ropendthendo

identnumber(

.;)

rop+-

endthendo

因子

identnumber(

.;+

-*/

endthendo

表5PL/X文法非终结符的开始符号与后继符号集合表

判断结果:

根据两条限制规则,发现该语法图分析符合两条限制规则

2.5语法出错表定义

无,出错信息均以字符串的形式在程序中标出。

3虚拟机

3.1虚拟机组织结构

程序存储器指令存储器数据存储区

程序地址寄存器基本地址寄存器地址寄存器

1)程序存储器

指令类型

enumfct{lit,opr,lod,sto,cal,

Int,jmp,jpc

};

指令

typedefstructinstruction{

fctf;

intl;

inta;

}Instruction;

指令数组

Instructioncode[InMax];

2)指令寄存器

inti;

3)数据存储器

intstack[StMax]

4)程序地址寄存器

intp;

5)基本地址寄存器

intb;

6)地址寄存器

intt;

 

3.2虚拟机指令格式

编译程序所产生的目标代码是一个假想栈式计算机的汇编语言,可称为类PCODE指令代码,它不依赖任何具体计算机,其指令集极为简单,指令格式也很单纯,其格式如下:

f

l

a

其中f代表功能码,l表示层次差,也就是变量或过程被引用的分程序与说明该变量或过程的分程序之间的层次差。

a的含意对不同的指令有所区别,对存取指令表示位移量,而对其它的指令则分别有不同的含义,见下面对每条指令的解释说明。

目标指令有8条:

①LIT:

将常量值取到运行栈顶。

a域为常数值。

②LOD:

将变量放到栈顶。

a域为变量在所说明层中的相对位置,l为调用层与说明层的层差值。

③STO:

将栈顶的容送入某变量单元中。

a,l域的含意同LOD指令。

④CAL:

调用过程的指令。

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

⑤INT:

为被调用的过程(或主程序)在运行栈中开辟数据区。

a域为开辟的单元个数。

⑥JMP:

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

⑦JPC:

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

⑧OPR:

关系运算和算术运算指令。

将栈顶和次栈顶的容进行运算,结果存放在次栈顶,此外还可以是读写等特殊功能的指令,具体操作由a域值给出。

(详见解释执行程序)。

指令功能表

LIT0a

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

LODla

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

STOla

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

CALla

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

INT0a

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

JMP0a

无条件跳转至a地址

JPC0a

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

OPR00

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

OPR01

栈顶元素取反

OPR02

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

OPR03

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

OPR04

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

OPR05

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

增加了除数为0的判断

OPR06

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

OPR07

OPR08

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

OPR09

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

OPR010

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

OPR011

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

OPR012

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

OPR013

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

OPR014

栈顶值输出至屏幕

OPR015

屏幕输出换行

OPR016

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

OPR017

扩展求余

OPR018

扩展求幂

4程序设计

4.1全局变量、全局常量

#defineNumber26//保留字的个数

#defineTXMAX100//标识符表的长度

#defineInMax200//指令最多条数

#defineLeMax3//过程最大嵌套层次

#defineStMax500//最大栈长

#defineIMax10//标识符最长长度

#defineDMax14//数字允许的最长位数v

#defineAddMax2048//最址

charch;//最近一次从程序中读出的字符

charsym[IMax];//最近读出的符号

charid[IMax];//最近读出的标识符

intnum;//最近读出的数值

intcc;//行缓冲区指针

intll;//行缓冲区长度

intkk;//提高性能

charline[100];//行缓冲区

chara[IMax];//存放当前正在分析的词

intlineno;//当前分析的行号

inttx=0;//符号表序号

intindex;//指令索引

charssym[13][IMax];//符号对应的符号表

charfsym[33][IMax];//用于出错处理

interr;//记录错误数量

intstack[StMax];

FILE*file;//指向要编译的源文件

charword[Number][IMax]={//保留字

"and",

"begin",

"call",

"case",

"constant",

"do",

"else",

"end",

"false",

"for",

"if",

"integer",

"logical",

"not",

"or",

"odd",

"procedure",

"program",

"read",

"repeat",

"switch",

"then",

"true",

"until",

"while",

"write"

};

charwsym[Number][IMax]={//保留字对应的符号表

"andsym",

"beginsym",

"callsym",

"casesym",

"constsym",

"dosym",

"elsesym",

"endsym",

"falsesym",

"forsym",

"ifsym",

"intesym",

"logisym",

"notsym",

"orsym",

"oddsym",

"procsym",

"progsym",

"readsym",

"repeasym",

"switcsym",

"thensym",

"truesym",

"untilsym",

"whilesym",

"writesym"

};

 

charD_first[4][IMax]={//声明语句头符号集

"intesym",

"logisym",

"constant",

"over"

};

charD_follow[3][IMax]={//声明语句跟随符号集

"beginsym",

"procsym",

"over"

};

charS_first[11][IMax]={//语句的头符号集

"adient",

"ifsym",

"whilesym",

"repeasym",

"writesym",

"forsym",

"callsym",

"readsym",

"dosym",

"switcsym",

"over"

};

charS_follow[7][IMax]={//语句的跟随符号集

"endsym",

"elsesym",

"untilsym",

"dosym",

"period",

"over"

};

 

enumfct{//指令类型

lit,

opr,

lod,

sto,

cal,

Int,

jmp,

jpc

};

enumobjekt{//标识符类型

integer,

logical,

procedure,

constant

};

typedefstructinstruction{

fctf;

intl;

inta;

}Instruction;

Instructioncode[InMax];//指令数组

 

typedefstructTable{//符号表定义

charname[IMax];

objektkind;

intadr;

intlevel;

intsize;

}Table;

Tabletable[TXMAX];//符号表

4.2函数接口

函数原型

voidgetch()

参数描述

函数描述

从源文件中读取字符

返回值

函数原型

voidgetsym()

参数描述

函数描述

从源文件中取出字符串

返回值

函数原型

voidinit()

参数描述

函数描述

初始化ssym

返回值

 

函数原型

voidError(char*s1)

参数描述

s1:

出错信息

函数描述

打印错误

返回值

函数原型

voidenter(objekttype,int*pdx,intlev)

参数描述

type:

符号类型

pdx:

当前层次偏移量

lev:

符号层次

函数描述

符号记入符号表

返回值

函数原型

boolIsIn(chars1[][IMax])

参数描述

s1符号字符串数组

函数描述

检查当前符号是否在期望符号集合中

返回值

true:

在false:

不在

函数原型

boolss(intlev)

参数描述

lev:

当前层次

函数描述

ss=s{;s}

返回值

函数原型

intposition(char*id)

参数描述

id:

所查询的符号

函数描述

在符号表中查询符号

返回值

id在符号表中序号,返回-1表示不存在

函数原型

voidUnion(chars1[][IMax],chars2[][IMax])

参数描述

S1,s2为要合并的字符串数组

函数描述

用于出错处理:

合并开始符与跟随符集合

返回值

函数原型

voidtest(chars1[][AL],chars2[][AL],char*err)

参数描述

S1:

此程序段的跟随符集合

S2:

此程序段的开始符集合

err:

错误信息

函数描述

当前符号是否在期望符号集中,否则报错并跳过

返回值

函数原型

voidgen(fctx,inty,intz)

参数描述

x:

指令名

y,z:

指令对应参数

函数描述

生成指令

返回值

 

函数原型

boolprog()

参数描述

函数描述

prog="program"ds{proc}"begin"ss"end""."

返回值

函数原型

boolproc(intlev)

参数描述

lev:

此过程层次

函数描述

proc="procedure"aident[ds]"begin"ss"end"

返回值

 

函数原型

boolds(int*pdx,intlev)

参数描述

pdx:

当前层次偏移量

lev:

当前层次

函数描述

ds=d{";"d}

返回值

 

函数原型

boold(int*pdx,intlev)

参数描述

pdx:

当前层次偏移量

lev:

当前层次

函数描述

d="integer"aident{","aident}|

"logical"bident{","bident}|

"constant"aident"="number{","aident"="number}

返回值

 

函数原型

bools(intlev)

参数描述

lev:

当前层次

函数描述

aident":

="ae|

bident":

="be|

"if"be"then"ss["else"ss]"end"|

"while"be"do"ss"end"|

"repeat"ss"until"be|

"write"ae.

"read"aident|bident

"for"s;be;s"do"ss"end"

"call"aident

"do"ss".""while"be"end"

返回值

函数原型

boolae(intlev)

参数描述

lev:

当前层次

函数描述

ae=["-"]at{("-"|"+")at}

返回值

 

函数原型

boolat(intlev)

参数描述

lev:

当前层次

函数描述

at=af1{("*"|"/")af1}

返回值

函数原型

boolaf1(intlev)

参数描述

lev:

当前层次

函数描述

af1=af{("**"|"%")af}

返回值

函数原型

boolaf(intlev)

参数描述

lev:

当前层次

函数描述

af=

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

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2