ImageVerifierCode 换一换
格式:DOCX , 页数:10 ,大小:76.29KB ,
资源ID:6343189      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6343189.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(算符优先分析过程模拟.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

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

1、算符优先分析过程模拟目录一、需求分析算符优先分析是自底而上分析方法的一种,这种方法是对输入符号串自左向右进行扫描,并将输入符逐个移入一个后进先出栈中,边移入边分析,一旦栈顶符号串形成某个句型的句柄或可规约串时(该句柄或可归约串对应产生式的右部),就用该产生式的左部非终结符代替相应右部的文法符号串,重复这样的归约过程,一直到只剩文法的开始符号时则为分析成功,也就是确认输入串是该文法的句子。而算符优先分析的基本思想则是只规定算符之间的优先关系,也就是只考虑终结符之间的优先关系,由于算符优先分析不考虑非终结符之间的优先关系,在归约过程中只要找到可归约的串就归约,并不考虑归约到那个非终结符名。在定义具

2、体的由于算符优先关系之前,先说明由于算符优先关系符的定义,有三中由于算符优先关系符,分别是,=设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 因为算符优先关系运算的次序只与运算符有关,而与运算对象无关,明显,对于算符优先文法的设计成为了关键。二、概要设计(一)、文法设计 算符优先分析只考虑算符(终结符)之

3、间的优先关系,先设计文法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)+

4、,-的优先级别较低,遵循左结合相当于+, +-, -, -+。(3)对()规定括号的优先性大于括号外的运算符,小于括号内的运算符。(4)对于句子括号#号规定与它相邻的任何运算符号的优先性都比它高。、(5)运算对象的终结符i,它优先级别最高。算符优先关系表+-*/()i#+-*/(=I#i3#E+i*i#移进4#E+i*i#移进5#E+i*i#归约E-i6#E+E*i#移进7#E+E*i#移进8#E+E*i#归约E-i9#E+E*E#归约E-E*E10#E+E#归约E-E+E11#E#接受分析过程:1、S栈中的“#”优先级小于当前输入符号i,移进。2、栈顶符号“i”优先级大于当前输入符号+,对终

5、结符i进行归约。3、栈顶符号“#”优先级小于当前输入符号+,移进。4、栈顶符号“+”优先级小于当前输入符号i,移进。5、栈顶符号“i”优先级大于当前输入符号*,对终结符i进行归约。6、栈顶符号“+”优先级小于当前输入符号*,移进。7、栈顶符号“*”优先级小于当前输入符号i,移进。8、栈顶符号“i”优先级大于当前输入符号#,对终结符i进行归约。9、栈顶符号“*”优先级大于当前输入符号#,归约,E - E * E。10、栈顶符号“+”优先级大于当前输入符号#,归约,E - E + E。11、接受。三、详细设计(一)、设计思路 大多数对于算符优先分析方法都是设计两个栈,通过比较符号栈顶元素和邻近的运

6、算符之间的优先关系。进行归约,移进的控制。而我用的却是另一种方法。 我将所输入的句型放在一个字符串Mystr中,然后对字符串进行扫描,当扫描到的当前字符是“+,-,*,/,()”时分别调用与之对应的五种不同的方法,当当前字符(token)是“+”调用方法evalExp2(),因为*/法和()的有线级高于“+”法,所以在evalExp2()中要调用evalExp3()扫描后续的句子,后续的句子如果有“*,/”法,用evalExp3()完成对“*,/”法的归约。同理括号中的算法的优先级别高于括号外的,所以evalExp3()的方法中要先调用evalExp4()对于括号的归约方法。在完成后依次回溯到

7、前一个方法,很明显我是通过递归的方法来实现算符优先关系。当然对于加减法evalExp2(),乘除法evalExp3(),括号evalExp4(),它们都可以单独调用,这由当前输入字符Taken确定。归约的实现实际上是对字符串的处理,在下面的“模块设计”中将具体解释。(二)、模块设计1、对于加减法的归约。private char evalExp2() throws ParserException char result; char partialResult; result = evalExp3(); /调用乘除法的归约方法 if(result!=E&result!=v&result!=i) r

8、eturn Q; /非法字符的判断,退出。 else while(token= + | token = -) char abc= token; myexpIdx-1=终结符; /读入当前运算符号 getToken(); /读取下一个字符 if(token=Q) error=语法错误; handleErr(error); return Q; else / mystr用于保存输入的句子,mydel用于动作的输出 partialResult = evalExp3(); mystrind=mystrind-1;mydelind=mydelind-1; ind+; if(+-*/).indexOf(to

9、ken) = -1|!mycmp)mystrind-1=mystrind-2.substring(0,mystrind-2.indexOf(abc,2)+mystrind-2.substring(mystrind-2.indexOf(abc,2)+2); mydelind-1=归约+EE+abc+E; else if(mystrind-3.indexOf(abc,mystrind-3.indexOf(abc)+1)!=-1) mystrind-2=mystrind-3.substring(0,mystrind-3.indexOf(abc,mystrind-3.indexOf(abc)+1)+m

10、ystrind-3.substring(mystrind-3.indexOf(abc,mystrind-3.indexOf(abc)+1)+2); mystrind-1=mystrind-1.substring(0,mystrind-1.indexOf(abc,mystrind-1.indexOf(abc)+1)+mystrind-1.substring(mystrind-3.indexOf(abc,mystrind-1.indexOf(abc)+1)+2); else /对于字符串的归约 mystrind-2=mystrind-3.substring(0,mystrind-3.indexOf

11、(abc,2)+mystrind-3.substring(mystrind-3.indexOf(abc,2)+2); mystrind-1=mystrind-1.substring(0,mystrind-1.indexOf(abc,2)+mystrind-1.substring(mystrind-1.indexOf(abc,2)+2); mydelind-2=归约+EE+abc+E; if(partialResult!=E&partialResult!=v&partialResult!=i) return Q; return E; 对于加减法归约的方法实际上是对存储句子的字符串mystr的操作

12、,给定一个句子,程序从逐个读入字符,当出现“+,-”号时调用evalExp2(),在一系列的合法性判断之后,进行规约。这里主要用到了substring(intstart, intend),方法,这是读取指定位置的字串。 例如,我们现在有一个句子v=E+E*E,要对加减法归约,先通过INDEX方法读取到加号的位置,然后对字符串的前后求子串, 我们可以把所有的句子假设为E+E的形式,并假设当前算符位置为taken通过substring(0,taken-1)读出前一个“”,然后连接上规约的结果E(E-E+E),最后再连接上后面的子串直接用substring(taken+1)输出后面的子串。最终将E+

13、E的形式规约为E的形式。 对于乘除法和括号的规约方法和加法的归约方法基本类似,也是对字符串的处理,由此实现对运算符的归约。2、读取下一个字符,对E-i的归约。 private void getToken() if(expIdx = exp.length() mycmp=false; token = Q; return; / 滤去空格 while(expIdx i的归约 else if( +-/*()Evi.indexOf(token) != -1) expIdx+; if(vi.indexOf(token) != -1)&ind!=2) mystrind=mystrind-2+E; mydel

14、ind=归约+E+token; ind+; else handleErr(非法字符); return; return; 由算符优先分析表我们知道终结符i的优先级别是最高的,也就是说当读入到i时立即进行归约,于是我在读取到下一个字符的时候先进行判断,当这个字符是i时,立即归约。四、测试结果(一)、规定测试用例 (二)、对于有括号句型的分析(三)、无法接受情况(四)、接受到非法字符五、总结 一个星期的课程设计结束了,但真正的学习才刚刚开始。 就像古语说的一样,事情都是看起来容易做起来难,说实话算符优先在我看来,是编译原理中比较简单的一个算法,但也就是这样一个简单的算法摧残了我近一个星期,不停的有新的问题,不停的需要修改,不断的翻书,很可惜还是没能用书上的方法实现。虽然最后用递归的方法模拟了这个算法,却觉得还是不那么舒服,写报告的这两天我又去看了些别人写的代码,算是加深了对栈的理解吧。 其实,出现了问题并不可怕,可怕的是你逃避已经出现了的问题,或许我们在大学学到的就是解决问题的方法。 谢谢黄老师一个学期以来对我的帮助和指导,黄老师将会是给我影像较深的一个老师,我依然记得您在上课时,当听到学生不认真听讲或者睡觉时,那种恨铁不成钢的焦急心态,不知道我为什么始终记得这样的一件事,或许是能这样做的人太少了吧,呵呵。最后祝您在以后的日子里,一切顺心。

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

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