WHILE循环语句的翻译程序设计.docx

上传人:b****7 文档编号:16374653 上传时间:2023-07-13 格式:DOCX 页数:15 大小:47.52KB
下载 相关 举报
WHILE循环语句的翻译程序设计.docx_第1页
第1页 / 共15页
WHILE循环语句的翻译程序设计.docx_第2页
第2页 / 共15页
WHILE循环语句的翻译程序设计.docx_第3页
第3页 / 共15页
WHILE循环语句的翻译程序设计.docx_第4页
第4页 / 共15页
WHILE循环语句的翻译程序设计.docx_第5页
第5页 / 共15页
WHILE循环语句的翻译程序设计.docx_第6页
第6页 / 共15页
WHILE循环语句的翻译程序设计.docx_第7页
第7页 / 共15页
WHILE循环语句的翻译程序设计.docx_第8页
第8页 / 共15页
WHILE循环语句的翻译程序设计.docx_第9页
第9页 / 共15页
WHILE循环语句的翻译程序设计.docx_第10页
第10页 / 共15页
WHILE循环语句的翻译程序设计.docx_第11页
第11页 / 共15页
WHILE循环语句的翻译程序设计.docx_第12页
第12页 / 共15页
WHILE循环语句的翻译程序设计.docx_第13页
第13页 / 共15页
WHILE循环语句的翻译程序设计.docx_第14页
第14页 / 共15页
WHILE循环语句的翻译程序设计.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

WHILE循环语句的翻译程序设计.docx

《WHILE循环语句的翻译程序设计.docx》由会员分享,可在线阅读,更多相关《WHILE循环语句的翻译程序设计.docx(15页珍藏版)》请在冰点文库上搜索。

WHILE循环语句的翻译程序设计.docx

WHILE循环语句的翻译程序设计

WHILE循环语句的翻译程序设计(递归下降法、输出三地址表示)

1系统描述

按照课程设计的要求,写一个能识别while循环语句的文法,通过一定的变换使它符合递归下降法的要求,然后按照这个文法编写一个程序,该程序能识别输入的语句是否符合while语句的文法,或者能不能通过文法的开始符号推导出该语句。

该程序应该包括词法分析器,能对输入的语句进行词法分析,然后再对结果进行语法分析。

词法分析器应能识别关键字,标示符,常量,操作符等。

该程序的语法分析器能对输入的语法进行分析,判断输入语句能否满足while循环语句的文法。

通过递归下降的方法对语句进行分析,看能否通过开始符号推导出来。

该程序的语义分析器就是对分析结果进行输出,要求输出结果是三地址形式的。

2文法及属性文法的描述

2.1文法描述

语句>:

:

=while(<条件表达式>(<赋值语句>|语句>

<条件表达式>:

:

=(<标识符>|<无符号整数>)<条件运算符>(<标识符>|<无符号整数>

<标识符>:

:

=<字母>(<字母>|<数字>

<条件运算符>:

:

=>|<|=

<无符号整数>:

:

=<数字>(<数字>

<赋值语句>:

:

=<标识符>=(<标识符>|<数字><算术运算符>(<标识符>|<数字>

<算术运算符>:

:

=+|-|*|/

<赋值语句>:

:

=<标识符>=<标识符>|<数字>

2.2递归文法

while语句文法:

S->while(BS|i=E

B->ErelopE

relop-><|=|>

E->E+E|E-E|E*E|E/E|(E|i|n

在编写程序的时候用到的是递归下降法,而递归下降法对文法的要求是不能包含左递归,对上述的文法进行消除左递归之后,得到如下的递归文法:

S->while(BS|i=E

B->ErelopE

relop-><|=|>

E->(EF|iF|nF

F->+EF|-EF|*EF|/EF|ε

2.3属性文法的描述

产生式

属性文法

S->while(BS1

S.begin:

=newlabel;

S.next:

=newlabel;

B.true:

=newlabel;

B.false:

=S.next;

S1.next:

=S.begin;

S.code:

=gen(S.begin,‘:

’||B.code||gen(S.true,‘:

’||

S1.code||gen(‘goto’,S.begin||gen(B.false,‘:

||gen(‘gotoLnext’;

B->E1relopE2

B.place:

=newlabel;

B.code:

=E1.code||relop.code||E2.code||

gen(B.place‘:

=’,E1.place,relop.place,E2.place;

relop-><|=|>

relop.place:

=newlabel;

relop.code:

=gen(‘<’||gen(‘=’||gen(‘>’;

E->(E1F

E.place:

=newlabel;

E.code:

=E1.code||F.code||

gen(E.place‘:

=’,‘(’,E1.place,‘’,F.place;

E->iF

E.palce:

=newlabel;

E.code:

=i.code||F.code||

gen(E.palce‘:

=’,i.place,F.place;

E->nF

E.place:

=newlabel;

E.code:

=n.code||F.code||

gen(E.place‘:

=’,n.place,F.place;

F->+EF1

F.place:

=newlabel;

F.code:

=E.code||F1.code||

gen(F.place‘:

=+’,E.place,F1.place;

F->-EF1

F.place:

=newlabel;

F.code:

=E.code||F1.code||

gen(F.place‘:

=-’,E.place,F1.place;

F->*EF1

F.place:

=newlabel;

F.code:

=E.code||F1.code||

gen(F.place‘:

=*’,E.place,F1.place;

F->/EF1

F.place:

=newlabel;

F.code:

=E.code||F1.code||

gen(F.place‘:

=/’,E.place,F1.place;

F->ε

F.place:

=newlabel;

F.code:

=gen(F.code‘:

=ε’;

图1属性文法

3语法分析方法描述

按照递归下降分析技术,递归下降识别程序是由一组子程序组成,每个子程序对应于一个非终结符号。

该子程序处理相应句型中相对于此非终结符号的产生式。

在定义文法时,是递归定义的,所以这些子程序也是递归的。

当一个子程序调用另一个子程序时,总是先执行被调用的子程序,然后再执行后继的程序。

在本程序中,首先要做的就是将设计的文法根据递归下降分析技术对文法的要求改为非左递归的文法。

程序中5个子程序,其中S是开始符号,也是递归下降分析的入口,通过调用intGetsymbol(对输入的字符串进行单词分析,并返回当前所分析到的单词,然后在递归语法分析中根据这个单词分析下一步要执行的子程序。

4中间代码形式的描述

4.1三地址代码

在本程序中用到了三地址语句的输出包括以下的种类:

赋值语句:

x:

=yopz

复制语句:

x:

=y

条件转移语句:

ifxrelopygotoL

例如,本程序中语句while(BS,可以输出三地址代码为:

ifBgotoLelsegotoLnext;

而E->(EF可以输出三地址代码为:

E1:

=(E2F。

4.2本程序中的三地址代码

S->while(BS

L0:

=if(BgotoL1elsegotoLnext

S->i=E

L:

=i=E

B->ErelopE

B:

=E1relopE2

relop-><

relop:

=<

relop->=

relop:

==

relop->>

relop:

=>

E->(EF

E1:

=(E2F

E->iF

E:

=IF

E->nF

E:

=nF

F->+EF

F1:

=+EF2

F->-EF

F1:

=-EF2

F->*EF

F1:

=*EF2

F->/EF

F1:

=/EF2

F->ε

F:

图2三地址代码

5概要设计

5.1简要分析

递归下降分析技术就是通过对每个非终结符编写一个子程序来实现它的操作,然后通过递归的调用来实现对输入字符串的分析,这其中还包括对输入字符串的词法分析。

在词法分析的时,得到的字符单词要和关键字比较,看是否是关键字,根据比较结果进行返回相应的单词类型。

单词类型主要包括变量,关键字,常量,各种符号等,每种符号都是一种类型。

在语法分析程序中,根据词法得到的结果,进行判断是否是当前需要的单词类型,如果不是就说明输入字符串不能由该文法推导出来;如果是当前需要的类型,就相应得做该单词类型分支程序。

根据文法可以得到这个递归下降程序可以分析包含有while嵌套的语句,在文法的开始符号S中就嵌套了S本身,因此这个文法的递归中就要考虑到while的自身嵌套。

在递归子程序中,在嵌套调用其他子程序时都是有一定条件的,当满足这个条件的时候该程序可以按照满足的条件执行下去,当没有满足程序中的条件时就会报错。

5.2程序的概要设计

在本程序中,Getsymbol(子程序就是对当前输入的字符串进行词法分析,包括对变量,常量,关键字,各种符号的分析。

主程序main(主要就是进行各种变量的初始化,调用递归分析程序的入口子程序。

子程序间的嵌套关系如下:

voidmain(

{S(;}

voidGetsymbol({…}

voidERROR({…}

voidS(

{re=Getsymbol(;

if(re==‘while’(关键字{B(;S(;}

else(re==i(变量

{re=Getsymbol(;

if(re===E(;}}

voidB(

{E(;relop(;E(;}

voidE(

{re=Getsymbol(;

if(re==(

{E(;re=Getsymbol(;if(re==F(;}

elseif(re==iF(;

elseif(re==nF(;}

voidF(

{re=Getsymbol(;

if(re==+{E(;F(;}

elseif(re==-{E(;F(;}

elseif(re==*{E(;F(;}

elseif(re==/{E(;F(;}}

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

关闭文件

6.1main(主函数的算法描述

图3mian(流程图

主程序执行时首先会测试input.txt文件是否存在,因为程序就是通过该文件得到需要进行递归下降分析方法分析的输入符号串;然后建立output.txt文件,问以后的输出结果做基础;接着调用递归下降分析法的入口程序S(来开始对文件中的输入字符串进行词法,语法和语义分析;最后关闭文件结束程序。

6.2Getsymbol(子程序的算法描述

IntGetsymbol(

{sym=fgetc(intput;//取当前文件指针指向的字符

While(sym不为空

{if(sym是a-z的字符

{将该字符保存在token1数组中;

继续取下一个是a-z的字符保存在数组中;

当sym不是字符时,则判断该数组中的符号串是不是关键字,是就返回16(while的机内码);不是就返回13(变量的机内码);

}

Elseif(sym是0-9之间的数字)

{将该数字保存在token2数组中;

继续取下一为0-9的数字,并保存到数组中去;

当sym不是数字是,就返回12(常数的机内码);

}

Elseif(sym是+)

返回4;

Elseif(sym是-)

返回3;

Elseif(sym是*)

返回2;

Elseif(sym是/)

返回1;

Elseif(sym是<)

返回11;

Elseif(sym是=)

返回10;

Elseif(sym是>)

返回9;

Elseif(sym是;)

返回20;

}

该程序就是对输入串进行分析,分析到不同的数据类型就相应返回它的机内码,这样方便在语法分析中进行分析。

本程序还保存了变量和常量在结构数组中,方便在语义分析的时候使用。

6.3S(子程序的算法描述

voidS(

{re=Getsymbol(;//取下一个字符的机内码

if(re==关键字//执行S->while(BS

{re=Getsymbol(;//取下一个字符的机内码

If(re==左括号

{调用B(;

re=Getsymbol(;//取下一个字符的机内码

if(re==右括号

调用S(;

}}

Elseif(re==变量//执行S->i=E

{re=Getsymbol(;//取下一个字符的机内码

If(re==等号

调用E(;}

Else

ERROR(;

}

该程序就是对通过Getsymbol(词法分析程序得到的单词,进行不同的程序语句执行。

当得到了while是就分析下一个是不是(,是的话就调用B(;否则就出错。

取下一个单词,是就调用S(;否则也出错。

当得到的是变量i时,去下一个单词,如果是=就调用E(。

6.4B(和relop(子程序的算法描述

在B(子程序中,不用判断任何的单词,就依次调用E(,relop(,E(,执行B->ErelopE

Voidrelop(

{re=Getsymbol(;//取下一个字符的机内码

If(sym==大于号;//执行relop-><

Elseif(sym==等于号;//执行relop->=

Elseif(syn==小于号;//执行relop->>

Else

ERROR(;

}

在relop程序中就主要上判断当前取得的单词是不是条件运算符。

6.5E(子程序的算法描述

VoidE(

{re=Getsymbol(;//取下一个字符的机内码

if(re==左括号//执行E->(EF

{E(;

re=Getsymbol(;//取下一个字符的机内码

if(re==右括号

F(;

}

Elseif(re==变量//执行E->iF

F(;

Elseif(re==常量//执行E->nF

F(;

}

6.6F(子程序算法描述

VoidF(

{re=Getsymbol(;//取下一个字符的机内码

If(re==加号//执行F->+EF

{E(;F(;}

Elseif(re==减号//执行F->-EF

{E(;F(;}

Elseif(re==乘号//执行F->*EF

{E(;F(;}

Elseif(re==除号//执行F->/EF

{E(;F(;}

}

这个子程序和E(合起来就是一个完整的可递归的算术操作运算,但由于递归下降分析方法不能含有左递归文法,所以消去左递归后就成了两个子程序。

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

由于该程序是用递归下降分析法来编写的,根据文法可以知道它可以对while语句进行嵌套,条件判断,赋值语句等的语句进行分析。

而且赋值语句也可以嵌套。

根据这些,我们在选择测试用例的时候就要选择比较典型的,尽量找到文法中有但程序中没能很好实现的地方。

下面就用到了几个典型的用例:

输入字符串:

while(n<10a=(b+c*d;

测试分析:

这个输入字符串是正确的,是最简单的while语句

测试结果:

图4输出结果

输入字符串:

whil(n<10a=b+c;

测试分析:

该字符串不符合本程序的文法,其中是while出错

测试结果:

图5输出结果

输入字符串:

while(tomn<10while(tomm<10toma=(tomb+c23*d45;

测试分析:

该字符串符合文法,它嵌套了while语句,而且变量名包含数字和字符

测试结果:

图6测试结果

输入字符串:

while(tomn<10whil(tomm>10toma=tomb+c23;

测试分析:

在嵌套的语句中,第二个while书写错误

测试结果:

图7测试结果

8研制报告

这次的课程设计要求比较严格,但是题目给得比较早,我在做第一个课程设计的时候就开始了该次课程设计的分析工作。

对递归下降分析方法的了解,递归分析方法的实现原理,三地址输出等都做了详细的了解。

并且在编程之前就已经将程序的概要设计都做出来了,所以在编写程序的时候相对比较容易。

词法分析,语法分析都是很容易的,只要你理解了分析方法的实现原理,编写程序判断输入字符串是否满足给定的文法是比较简单的。

比较麻烦的就是语义分析输出三地址代码,由于在递归下降分析技术中,是推导出输入字符串的,所以对变量的使用要保存好以待下次使用。

例如E->(EF中,等E(执行完了才能执行F(,但是在执行E(的时候就已经嵌套的执行了好多次的F(,所以等回到这个产生式在执行F(时,就很容易和前面E(中调用的F(混淆。

在这个程序的输出三地址中,详细的描述了当输入字符串符合该文法时,是怎么样都开始符号推导出来的。

当输入的字符串不满足该文法时,就相应的可以在输出结果中看到是在哪一步推倒时出现了错误。

在该程序中实现了赋值语句中算术运算的嵌套,可以进行多步的算术运算。

本程序的不足之处就是对条件语句的判断不够详细,只进行了三个简单的条件判断,而条件的增加就可以修改文法,再在程序中添加相应的代码即可。

由于递归下降分析方法完全是按照文法而写的,所以对文法的添加后,对程序做相应的添加就可以了。

对于以后的课程设计,我觉得不应该有这么多的相似之处,一半的都是程序是一样的,只是输出不一样,有些同学也做得很简单,那的确是没有错的,因为在任务书中没有明确说明要做哪些内容。

所以在实现的功能上有一些区别,在文法的构造上也有区别,有的是太简单,但有的的确是太复杂了,把什么都考虑到了,到最后程序的确太庞大而编写不出来了。

最后还是得感谢老师和同学在课程设计中对我的帮助。

9参考文献

[1]陈火旺,刘春林等著,编译原理,北京:

国防工业出版社,2002.6

[2]钱能著,C++程序设计教程,北京:

清华大学出版社,2002.7

[3]张幸儿,计算机编译原理—编译程序构造实践:

科学出版社,2005.7

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

当前位置:首页 > 经管营销 > 经济市场

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

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