算符优先分析过程模拟.docx

上传人:b****6 文档编号:7907499 上传时间:2023-01-27 格式:DOCX 页数:10 大小:61.88KB
下载 相关 举报
算符优先分析过程模拟.docx_第1页
第1页 / 共10页
算符优先分析过程模拟.docx_第2页
第2页 / 共10页
算符优先分析过程模拟.docx_第3页
第3页 / 共10页
算符优先分析过程模拟.docx_第4页
第4页 / 共10页
算符优先分析过程模拟.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

算符优先分析过程模拟.docx

《算符优先分析过程模拟.docx》由会员分享,可在线阅读,更多相关《算符优先分析过程模拟.docx(10页珍藏版)》请在冰豆网上搜索。

算符优先分析过程模拟.docx

算符优先分析过程模拟

算符优先分析过程模拟

一、需求分析......................................................................1

二、概要设计......................................................................2

三、详细设计......................................................................5

四、测试结果....................................................................10

五、总结............................................................................12

华东交通大学课程设计报告

算符优先分析是自底而上分析方法的一种,这种方法是对输入符号

串自左向右进行扫描,并将输入符逐个移入一个后进先出栈中,边移入边

分析,一旦栈顶符号串形成某个句型的句柄或可规约串时(该句柄或可归

约串对应产生式的右部),就用该产生式的左部非终结符代替相应右部的文

法符号串,重复这样的归约过程,一直到只剩文法的开始符号时则为分析

成功,也就是确认输入串是该文法的句子。

而算符优先分析的基本思想则是只规定算符之间的优先关系,也就

是只考虑终结符之间的优先关系,由于算符优先分析不考虑非终结符之间

的优先关系,在归约过程中只要找到可归约的串就归约,并不考虑归约到

那个非终结符名。

在定义具体的由于算符优先关系之前,先说明由于算符优先关系符

的定义,有三中由于算符优先关系符,分别是>,<,=

设G是一个不含ε产生式的算符文法,a,b是任意两个终结符,A,

B,C是非终结符,算符优先关系=,<,>定义如下:

(1)a=b当且仅当G中含有形如A->„ab„或A->„aBb„的产生式

(2)a„aB„的产生式,且B可以多

步推导出b„或B可以多步推倒出Cb„

(3)a>b当且仅当G中有型如A->„Bb„的产生式,且B可以多

步推导出„a或B可以多步推导出„Ac

因为算符优先关系运算的次序只与运算符有关,而与运算对象无关,

明显,对于算符优先文法的设计成为了关键。

第1页共13页

华东交通大学课程设计报告

算符优先分析只考虑算符(终结符)之间的优先关系,先设计文法G为:

(1)S->v=E

(2)E->E+E

(3)E->E-E

(4)E->E*E

(5)E->E/E

(6)E->(E)

(7)E->v

(8)E->i

通常在算术表达式求值过程中,运算次序是先乘除后加减,这说明了

乘除运算先级别高于加减运算的优先级,乘除为同一优先级但运算符在前

边的先做,这叫作左结合,同样加减运算也是如此,这也说明了运算的次

序只与运算符有关,而与运算对象无关,因而我根据这样的基本原理开始

设计运算符之间的优先关系。

(1)*,/的优先级别较高,高于+,-,遵循左结合。

相当于*>*,*>/,

/>/,/>*。

(2)+,-的优先级别较低,遵循左结合相当于+>+,+>-,->-,->+。

(3)对‘(’‘)’规定括号的优先性大于括号外的运算符,小于括号内

的运算符。

(4)对于句子括号‘#’号规定与它相邻的任何运算符号的优先性都比

它高。

(5)运算对象的终结符i,它优先级别最高。

第2页共13页

华东交通大学课程设计报告

算符优先关系表

+-*/()i#+>><<<><>->><<<><>*>>>><><>/>>>><><>(<<<<<=<)>>>>>>I>>>>>>#<<<<<<=

对于算符优先分析方法,在文法G下,预计总控程序的输出结果为:

对输入串i+i*i的归约过程

步骤栈S当前输入符剩余串动作

1#i+i*i#移进

2#i+i*i#归约E->i

3#E+i*i#移进

4#E+i*i#移进

5#E+i*i#归约E->i

6#E+E*i#移进

7#E+E*i#移进

8#E+E*i#归约E->i

9#E+E*E#归约E->E*E

10#E+E#归约E->E+E

11#E#接受

第3页共13页

华东交通大学课程设计报告

分析过程:

1、S栈中的“#”优先级小于当前输入符号i,移进。

2、栈顶符号“i”优先级大于当前输入符号+,对终结符i进行归约。

3、栈顶符号“#”优先级小于当前输入符号+,移进。

4、栈顶符号“+”优先级小于当前输入符号i,移进。

5、栈顶符号“i”优先级大于当前输入符号*,对终结符i进行归约。

6、栈顶符号“+”优先级小于当前输入符号*,移进。

7、栈顶符号“*”优先级小于当前输入符号i,移进。

8、栈顶符号“i”优先级大于当前输入符号#,对终结符i进行归约。

9、栈顶符号“*”优先级大于当前输入符号#,归约,E->E*E。

10、栈顶符号“+”优先级大于当前输入符号#,归约,E->E+E。

11、接受。

第4页共13页

华东交通大学课程设计报告

大多数对于算符优先分析方法都是设计两个栈,通过比较符号栈顶元素

和邻近的运算符之间的优先关系。

进行归约,移进的控制。

而我用的却是

另一种方法。

我将所输入的句型放在一个字符串Mystr中,然后对字符串进行扫描,

当扫描到的当前字符是“+,-,*,/,()”时分别调用与之对应的五种不同

的方法,当当前字符(token)是“+”调用方法evalExp2(),

因为*/法和()的有线级高于“+”法,所以在evalExp2()中要调用evalExp3()扫描后续的句子,后续的句子如果有“*,/”法,用evalExp3()完成对“*,/”法的归约。

同理括号中的算法的优先级别高于括号外的,所以evalExp3()的方法中要先调用evalExp4()对于括号的归约方法。

在完成后依次回溯到前一个方法,很明显我是通过递归的方法来实现算

符优先关系。

当然对于加减法evalExp2(),乘除法evalExp3(),括号evalExp4(),它们都可以单独调用,这由当前输入字符Taken确定。

归约的实现实际上是对字符串的处理,在下面的“模块设计”中将具体

解释。

第5页共13页

华东交通大学课程设计报告

1

privatecharevalExp2()throwsParserException

{

charresult;

charpartialResult;

result=evalExp3();//调用乘除法的归约方法

if(result!

='E'&&result!

='v'&&result!

='i')

return'Q';//非法字符的判断,退出。

else{

while(token=='+'||token=='-'){

charabc=token;

my[expIdx-1]="终结符";//读入当前运算符号

getToken();//读取下一个字符

if(token=='Q'){

error="语法错误";

handleErr(error);

return'Q';

}

else{//mystr用于保存输入的句子,mydel用于"动作"的输出

partialResult=evalExp3();

mystr[ind]=mystr[ind-1];mydel[ind]=mydel[ind-1];

ind++;

if("+-*/)".indexOf(token)==-1||!

mycmp)

{

mystr[ind-1]=mystr[ind-2].substring(0,mystr[ind-2].indexOf(abc,2))+mystr[ind-2

].substring(mystr[ind-2].indexOf(abc,2)+2);

mydel[ind-1]="归约"+"E?

E"+abc+"E";

}

else{

if(mystr[ind-3].indexOf(abc,mystr[ind-3].indexOf(abc)+1)!

=-1){

mystr[ind-2]=mystr[ind-3].substring(0,mystr[ind-3].indexOf(abc,mystr[ind-3].indexOf(abc)

+1))+mystr[ind-3].substring(mystr[ind-3].indexOf(abc,mystr[ind-3].indexOf(abc)+1)+2);

第6页共13页

华东交通大学课程设计报告mystr[ind-1]=mystr[ind-1].substring(0,mystr[ind-1].indexOf(abc,mystr[ind-1].indexOf(abc)

+1))+mystr[ind-1].substring(mystr[ind-3].indexOf(abc,mystr[ind-1].indexOf(abc)+1)+2);

}

else{//对于字符串的归约

mystr[ind-2]=mystr[ind-3].substring(0,mystr[ind-3].indexOf(abc,2))+mystr[ind-3].substring

(mystr[ind-3].indexOf(abc,2)+2);

mystr[ind-1]=mystr[ind-1].substring(0,mystr[ind-1].indexOf(abc,2))+mystr[ind-1].substring

(mystr[ind-1].indexOf(abc,2)+2);

}

mydel[ind-2]="归约"+"E?

E"+abc+"E";

}

if(partialResult!

='E'&&partialResult!

='v'&&partialResult!

='i')

return'Q';

}

}

return'E';

}

}

对于加减法归约的方法实际上是对存储句子的字符串mystr的操作,

给定一个句子,程序从逐个读入字符,当出现“+,-”号时调用evalExp2(),在一

系列的合法性判断之后,进行规约。

这里主要用到了(intstart,intend),方法,这是读取指定位置的字串。

例如,我们现在有一个句子v=E+E*E,要对加减法归约,先通过INDEX方

法读取到加号的位置,然后对字符串的前后求子串,

我们可以把所有的句子假设为„E+E„的形式,并假设当前算符位置为

taken通过读出前一个“„”,然后连接上规约的结果E(E->E+E),最后再连接上后面的子串直接用

输出后面的子串。

最终将„E+E„的形式规约为„E„的形式。

对于乘除法和括号的规约方法和加法的归约方法基本类似,也是对字符串的处理,

由此实现对运算符的归约。

第7页共13页

华东交通大学课程设计报告

2E->i

privatevoidgetToken()

{

if(expIdx==exp.length()){

mycmp=false;

token='Q';

return;

}

//

while(expIdx

Character.isWhitespace(exp.charAt(expIdx)))++expIdx;

if(expIdx==exp.length()){

mycmp=false;

token='Q';

return;

}

//

token=exp.charAt(expIdx);

mystr[ind]=mystr[ind-1]+token;

mydel[ind]="移进";

wyq=wyq+token+"";

ind++;

if(cmp){

if(("+-/*()Evi=".indexOf(token)!

=-1)){

expIdx++;

}

else{

cmp=false;

handleErr("非法字符");

return;

}

cmp=false;

}

//E->i

else{

if(("+-/*()Evi".indexOf(token)!

=-1)){

第8页共13页

华东交通大学课程设计报告

expIdx++;

if(("vi".indexOf(token)!

=-1)&&ind!

=2){

mystr[ind]=mystr[ind-2]+"E";

mydel[ind]="归约"+"E?

"+token;

ind++;

}

}

else{

handleErr("非法字符");

return;

}

}

return;

}

由算符优先分析表我们知道终结符i的优先级别是最高的,也就是说当读入到i时立即进行归约,于是我在读取到下一个字符的时候先进行判断,当这

个字符是i时,立即归约。

第9页共13页

华东交通大学课程设计报告

第10页共13页

华东交通大学课程设计报告

第11页共13页

华东交通大学课程设计报告

一个星期的课程设计结束了,但真正的学习才刚刚开始。

就像古语说的一样,事情都是看起来容易做起来难,说实话算符优

先在我看来,是编译原理中比较简单的一个算法,但也就是这样一个简单

的算法摧残了我近一个星期,不停的有新的问题,不停的需要修改,不断

的翻书,很可惜还是没能用书上的方法实现。

虽然最后用递归的方法模拟

了这个算法,却觉得还是不那么舒服,写报告的这两天我又去看了些别人

写的代码,算是加深了对栈的理解吧。

其实,出现了问题并不可怕,可怕的是你逃避已经出现了的问题,

或许我们在大学学到的就是解决问题的方法。

谢谢黄老师一个学期以来对我的帮助和指导,黄老师将会是给我影

像较深的一个老师,我依然记得您在上课时,当听到学生不认真听讲或者

睡觉时,那种恨铁不成钢的焦急心态,不知道我为什么始终记得这样的一

件事,或许是能这样做的人太少了吧,呵呵。

最后祝您在以后的日子里,一切顺心。

第12页共13页

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

当前位置:首页 > PPT模板 > 图表模板

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

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