编译原理课程设计ifelse条件语句翻译三地址简单优先法 1.docx

上传人:b****5 文档编号:7553116 上传时间:2023-01-24 格式:DOCX 页数:44 大小:239.37KB
下载 相关 举报
编译原理课程设计ifelse条件语句翻译三地址简单优先法 1.docx_第1页
第1页 / 共44页
编译原理课程设计ifelse条件语句翻译三地址简单优先法 1.docx_第2页
第2页 / 共44页
编译原理课程设计ifelse条件语句翻译三地址简单优先法 1.docx_第3页
第3页 / 共44页
编译原理课程设计ifelse条件语句翻译三地址简单优先法 1.docx_第4页
第4页 / 共44页
编译原理课程设计ifelse条件语句翻译三地址简单优先法 1.docx_第5页
第5页 / 共44页
点击查看更多>>
下载资源
资源描述

编译原理课程设计ifelse条件语句翻译三地址简单优先法 1.docx

《编译原理课程设计ifelse条件语句翻译三地址简单优先法 1.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计ifelse条件语句翻译三地址简单优先法 1.docx(44页珍藏版)》请在冰豆网上搜索。

编译原理课程设计ifelse条件语句翻译三地址简单优先法 1.docx

编译原理课程设计ifelse条件语句翻译三地址简单优先法1

课程设计任务书

题目:

IF-ELSE条件语句的翻译程序设计(简单优先法、输出三地址表示)

初始条件:

理论:

学完编译课程,掌握一种计算机高级语言的使用。

实践:

计算机实验室提供计算机及软件环境。

如果自己有计算机可以在其上进行设计。

要求完成的主要任务:

(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)

(1)写出符合给定的语法分析方法的文法及属性文法。

(2)完成题目要求的中间代码三地址表示的描述。

(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。

(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

(5)设计报告格式按附件要求书写。

课程设计报告书正文的内容应包括:

1系统描述(问题域描述);

2文法及属性文法的描述;

3语法分析方法描述及语法分析表设计;

4按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;

5编译系统的概要设计;

6详细的算法描述(流程图或伪代码);

7软件的测试方法和测试结果;

8研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);

9参考文献(按公开发表的规范书写)。

时间安排:

设计安排一周:

周1、周2:

完成系统分析及设计。

周3、周4:

完成程序调试及测试。

周5:

撰写课程设计报告。

设计验收安排:

设计周的星期五第1节课开始到实验室进行上机验收。

设计报告书收取时间:

设计周的次周星期一上午10点。

指导教师签名:

2013年月日

系主任(或责任教师)签名:

2013年月日

IF-ELSE条件语句的翻译程序设计(简单优先法、输出三地址表示)

 

1系统描述

1.1题目

IF-ELSE条件语句的翻译程序设计(简单优先法、输出三地址表示)

1.2.目的

通过设计、编制、调试一个条件语句的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。

1.3.设计内容及步骤

对条件语句:

IF〈布尔表达式〉THEN〈赋值语句〉ELSE〈赋值语句〉

(1)按给定的题目写出符合语法分析方法要求的文法和属性文法描述。

(2)按给定的题目给出语法分析方法的思想及分析表设计。

(3)按给定的题目给出中间代码序列的结构设计。

(4)完成相应的词法分析、语法分析和语义分析程序设计。

(5)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

2文法及属性文法的描述

2.1文法

文法是用于描述语言的语法结构的形式规则(即语法规则)。

这些规则必须是准确的、易于理解的以及有相当强的描述能力。

由这种规则所产生的程序语言应有利于句子分析和翻译,而且,最好能通过这些规则自动产生有效的语法分析程序。

IF-ELSE条件语句的文法G[S]如下所示:

(1)S->CM

(2)S->TM

(3)M->beginLend

(4)C->ifBthen

(5)T->CMelse

其中非终结符B为布尔表达式,其文法G[B]如下:

(1)B->B1orB2

(2)B->B1andB2

(3)B->notB1

(4)B->(B1)

(5)B->id1ropid2

(6)B->true

(7)B->false

而在文法G[S]中非终结符L表示赋值语句块,其文法G[L]如下:

(1)L->L1A;

(2)L->A;

(3)A->id=M

(4)M->E

(5)E->E1+E2

(6)E->E1*E2

(7)E->-E1

(8)E->(E1)

(9)E->id

2.2属性文法

属性文法是在上下文无关文法的基础上,为每个文法符号(终结符或者非终结符)配备若干相关的“值”(与文法符号相关的属性)。

在一个属性文法中,对应于每个产生式A→a都有一套与之相关联的语义规则,每规则的形式为:

b:

=f(c1,c2,…,ck)其中f是一个函数,而且或者①b是A的一个综合属性并且c1,c2,…,ck是产生式右边文法符号的属性或者②非终结符既可有综合属性也可有继属性,文法开始符号的所有继承属性作为属性计算前的初始值[1]。

2.2.1语义变量和语义动作说明

对于文法G[L],首先对id表示的单词定义一属性id.name,用做语义变量,用Lookup(id.name)语义函数审查id.name是否出现在符号表中,如在,则返回一指向该登陆项的指针,否则返回nil。

语义过程emit表示输出四元是到输出文件上。

语义过程newtmp表示生产一临时变量,每调用一次,生成一新的临时变量。

语义变量E.place,表示存放E值的变量名在符号表的登陆项或一整数码(若此变量时一个临时变量)[2],

2.2.1给出了翻译赋值语句块到三地址的语义描述。

2.2.1G[S]的属性文法为:

(1)S->CM{S.chain:

=merge(C.chain,M.chain)}

(2)S->TM{S.chain:

=merge(T.chain,M.chain)}

(3)M->beginLend{M.chain:

=L.chain}

(4)C->ifBthen{bakpatch(B.true,nextstat)

C.chain:

=B.false}

(5)T->CMelse{q:

=nextstat

emit(‘GOTO’--)

backpatch(C.chain,nextstat)

T.chain:

=merge(M.chain,q)}

2.2.2G[B]的属性文法为:

(1)B->B1orB2{backpatch(B1.false,B2.codebgin);

B.codebegin:

=B1.codebegin;

B.true:

=merge(B1.true,B2.true);

B.false:

=B2.false}

(2)B->B1andB2{backpatch(B1.true,B2.codebegin);

B.codebegin:

=B1.codebegin;

B.true:

=B2.true;

B.false:

=merge(B1.false,B2.false);}

(3)B->notB1{B.true:

=B1.false;

B.codebegin:

=B1.codebegin;

B.false:

=B1.true;}

(4)B->(B1){B.true:

=B1.true;

B.codebegin:

=B1.codebegin;

B.false:

=B1.false;}

(5)B->id1ropid2{B.true:

=nextstat;

B.codebegin:

=nextstat;

B.false:

=nextstat+1;

emit(‘if’id1.place‘rop’id2.place‘goto’--);

emit(‘goto’--)}

(6)B->true{B.true:

=nextstat;

B.codebegin:

=nextstat;

emit(‘goto’--)}

(7)B->false{B.false:

=nextstat;

B.codebegin:

=nextstat;

emit(‘goto’--)}

其中nextstat给出在输出序列中下一三地址式子的序号。

emit过程没调用一次,nextstat增加1

2.2.3G[L]的属性文法为:

(1)L->L1A;{L.chain:

=A.chain}

(2)L->A;{L.chain:

=A.chain}

(3)A->id:

=M{p:

=lookup(id.name);

ifp≠nilthen

emit(p‘:

=’E.place);

elseerror}

(4)M->E{}

(5)E->E1+E2{E.place:

=newtemp;

emit(E.place‘:

=’E1.place‘+’E2.place)}

(6)E->E1*E2{E.place:

=newtemp;

emit(E.place‘:

=’E1.place‘*’E2.palce)}

(7)E->-E1{E.palce:

=newtemp;

emit(E.place‘:

=’‘minus’E1.place)}

(8)E->(E1){E.place:

=E1.place}

(9)E->id(6)A->num{p:

=lookup(id.name);

ifp≠nilthen

E.palce:

=p

elseerror}

3语法分析方法描述及语法分析表设计

3.1简单优先法的定义构造及优缺点

3.1.1简单优先法定义构造

一个文法G,若它不含ε产生式,也不含任何右部相同的不同产生式,并且它的任何符号对(X,Y),或者没有关系,或者存在下述三种关系:

=、<、>之一,则称该文法是一个简单优先文法。

A)X=Y当且仅当G中含有形如P→…XY…的产生式

B)X

C)X>Y当且仅当Y为G的终结符,G中含有形如P→…QR…的产生式,其中Q,R为非终结符,且Q→…X,Y∈First(R)

D)对任何X,若文法开始符号S→X…,则##。

[3]

3.1.2简单优先法的优缺点

优点:

准确、规范,技术简单。

缺点:

适用的范围小,构造的分析表太大,分析效率较低。

3.2语法分析

为实现简单优先算法,可以使用工作栈.用以寄存操作数或运算结果.算法的基本思想是:

(1)置初始状态:

S

(1):

=‘#’,i:

=1,j:

=1

(2)若S(i)与T(j)无任何关系,则出错停机

(3)若S(i)=T(j)或S(i)〈T(j),则把T(j)送入S栈中,读下一符,转

(2)。

(4)若S(i)〉T(j),则从S栈顶开始往前栈串Sj1,Sj1+1,…,Si

其中Sj1为第一个使Sj1-1〈Sj1,然后用Sj1,Sj1+1,…Si去查生产式表,

若查到有相同右部的产生式即U→Sj1,Sj1+1,…Si,则从栈中退掉子串Sj1,Sj1+1,…Si,并把U进栈;然后转

(2)。

若查不到转出错处理。

(5)若T(j)=‘#’,并且S栈的内容为#Z(Z为文法开始符号)则正确停机。

否则,出错停机。

3.3语法分析表设计

3.3.1G[S]的优先关系表如表1:

表1G[S]的优先关系矩阵

S

C

T

M

begin

L

end

if

B

then

else

#

S

<

>

C

=

<

T

=

<

M

=

>

begin

<

=

L

end

>

>

if

=

B

=

then

>

>

else

>

>

#

<

<

<

<

<

<

注:

表中空白表示无优先关系,分析过程中查找到无优先关系的两个文法符号则表示出错,下同。

3.3.2G[B]的优先关系表如表2:

表2G[B]的优先关系矩阵

B

or

and

not

id

rop

true

fasle

#

B

=

=

=

>

or

<

<

<

and

<

<

not

<

>

>

id

>

>

=

>

rop

=

true

>

>

>

false

>

>

>

#

<

<

<

<

注:

表中id代表标识符,rop代表关系运算符,下同。

3.3.2G[L]的优先关系表如表3:

表3G[L]的优先关系矩阵

L

A

;

:

=

id

+

-

M

E

*

#

L

=

<

>

A

=

>

;

>

>

:

=

<

<

<

=

<

<

=

>

<

id

>

=

>

>

>

+

>

<

<

=

-

<

<

=

M

>

E

>

<

=

=

=

*

>

<

<

=

#

<

<

<

4.中间代码形式的描述及中间代码序列的结构设计

4.1中间代码形式描述

此设计要求使用的是三地址的中间代码,三地址代码是由下面一般形式构成的语句序列:

x:

=yopz;

其中x,y,z为变量名,常数或编译时产生的临时变量;op代表运算符号如标点,浮点运算符号等等。

每个语句的右边只能有一个运算符。

表达式x+y*z翻译成的三地址语句序列是:

t1:

=y*z

t2:

=x+t1

常用的三地址语句有:

赋值语句x:

=yopz,x:

=opy,x:

=y

无条件转移gotoL

条件转移ifxrelopygotoL

过程调用paramx和callp,n

过程返回returny

索引赋值x:

=y[i]和x[i]:

=y

地址和指针赋值x:

=&y,x:

=*y和*x:

=y

4.2中间代码序列的结构设计

本次课程设计采用四元式的中间代码形式,例如

赋值语句x:

=y*z*a的三地址表示如下:

001:

T1:

=a*z

002:

T2:

=T1*y

003:

x:

=T2

if-else语句块:

ifa>bandc

begin

p=q+r+s;

c=w;

end

的三地址表示如下:

001:

ifa>bgoto3

002:

goto--

003:

ifc

004:

goto--

005:

T1:

=s+r

006:

T2:

=T1+q

007:

p:

=T2

008:

c:

=w

其中前面的数字表示三地址的序列号或者说是中间代码的地址,Ti为中间代码翻译过程中产生的临时变量,符号‘—’,表示在后续的翻译过程中待回填的goto语句转移地址。

5编译系统的概要设计

5.1程序总体描述

本设计体现语法制导翻译的思想,采用单遍的翻译方法,在语法分析的过程中同时完成词法分析和中间代码的翻译。

 

图1程序总体概要设计

5.2数据结构设计

5.2.1用于“回填”和“拉链”的链表结构设计如下:

structChain{

intlabel;//三地址代码语句的序号

Chain*next;//下一个节点指针

};

5.2.2属性单词Token的数据结构如下:

structToken{

charname[20];//名字

Classifykind;//类型

Chain*trueChain;//“真链”

Chain*falseChain;//“假链”

Chain*chain;//待“回填”的链

intcodeBegin;//非终结符的第一个三地址语句序号

intweight;//该变量用于计算归约用的的产生式序号

intpos;//文法符号在优先关系表中的位置

intplace;//属性单词在符号表中的登陆项

doublevalue;//数值型单词的值,其他类型无定义

intlineNumber;//单词所在源文件的行号

charorig[20];//如为非终结符,该变量用于保存被规约

//成该非终结符的终结符,否则无定义

}

5.2.3三地址码数据结构设计

structTripleCode{

CodeKindkind;//三地址语句格式种类

charop;//运算符

charresult[20];//运算结果

charopn1[20];//操作数1

charopn2[20];//操作数2

intdestination;//goto语句的转移地址

boolterm0;//结果变量是否是终结符

boolterm1;//操作数1是否是终结符

boolterm2;//操作数2是否是终结符

intserial0;//如结果为临时变量,用于保存该临时变量的序列号

intserial1;//如果操作数1为临时变量,用于保存该临时变量的

//序列号

intserial2;//如果操作数2为临时变量,用于保存该临时变量的

//序列号

};

根据产生式的序号和产生式右边文法符号的个数,给产生式右边每个文法符号赋予一定的weight值,在规约的时候,产生式右边各个文法符号的weight域相加的和为该产生式的序号,从而确定用哪条产生式规约。

三地址代码的格式设计为5种,分别是“if-goto”型、“goto”型、赋值型、单目运算型和双目运算型

5.3程序接口声明

5.3.1.1词法分析器类Lexical的类图

图2Lexical类

classLexical

Attributes

privatecharch

privateintU_inde

privateintlineNum

privateintlen

privateintbuffEnd

privatedoublevalue

privateifstreamfin

privateofstreamfout

privatestringoutputFile

privatestaticintserial

privatestaticintnextstat

privatecharline[100]

privatecharword[40]

privateintbuffer[MAX_BUFFER_SIZE]

privateTokentokens[MAX_SYMBOL_SIZE]

privateTripleCodecodes[MAX_CODE_NUM]

privatecharseparators[SEPARATOR_COUNT]

privatechar*keywordTable[KEYWORD_COUNT]

privatechar*operators[OPERATOR_COUNT]

Operations

publicLexical()

public~Lexical()

publicToken*getNextToken()

publicToken*getNewToken()

publicintlookup()

publicvoidemit()

publicvoidgenCode()

publicvoidprintCode()

publicvoidbackpatch()

publicvoidputBackToken()

publicvoidwriteCodeToFile()

publicstaticinlineintgetNextStat()

publicstaticintgetSerialNum()

privateintgetChar()

privatevoidgetWord()

privatevoidskipSlash()

privatevoidgetLine()

privateintfindKeyword()

privateintfindSeparator()

privatevoidreadOperator()

privatedoublestring2Double()

 

5.3.1.2Lexical类主要接口说明

publicToken*getNextToken()//返回源文件中的下一个属性单词的指针

publicToken*getNewToken()//返回符号表中下一个可用新项目的指针

publicintlookup()//语义函数,查找给定名字的单词是否在符号表中

publicvoidemit()//语义函数,生成一条三地址代码并保存到三地址代

//码数组中,emit过程每调用一次,nextstat增加1

publicvoidgenCode()//语义函数,作用同emit,genCode每调用一次,

//nextstat也增加1

publicvoidprintCode()//输出三地址码到屏幕

publicvoidbackpatch()//用于回填的函数

publicvoidputBackToken()//将属性单词

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

当前位置:首页 >

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

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