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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

LR0语法分析器.docx

1、LR0语法分析器 西 安 邮 电 大 学 (计算机学院)课内实验报告实验名称: LR(0)语法分析器 专业名称: 计算机科学与技术班 级: 计科1304 学生姓名: 裴世宇学号(8位): 04131132(12)指导教师: 陈燕实验日期: 2016年05月15日一、实验目的. 1.巩固对语法分析的基本功能和原理的认识。2.通过对语法分析表的自动生成加深语法分析表的认识。3.理解并处理语法分析中的异常和错误。二、实验环境VC+6.0Windows 7三、实验内容 大多数用上下文无关文法描述的程序语言都可用LR分析器予以识别。LR分析法比算符优先分析法或其他的“移进-规约”技术更加广泛,而且分析效

2、率并不比他们差。规范规约的关键问题是寻找句柄。一个LR分析器实质上是一个带先进后出的存储器(栈)点确定有限状态自动机。1.通过设计、编制、陶氏一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。2.选择对各种常见程序语言都用的语法结构,如赋值语句(尤其是表达式)作为分析对象,并且与所选语法分析方法要比较贴切。四、实验功能LR分析器实质上是一个带先进后出存储器(栈)的确定有限状态自动机。我们将把“历史”和“展望”材料综合地抽象成某些“状态”。我们把栈的结构看成是:LR分析器模型LR分析器的核心部分是一张分析表。这张分析表包括两部分,意识

3、“动作”(ACTION)表,另一个是“状态转换”(GOTO)表。他们都是二维数组。ACTION s , a 规定了当状态s面临符号a时应采取什么动作。GOTO s ,X 规定了状态。面对文法符号X(终结符或非终结符)时下一个状态是什么。显然,GOTOs,X定义了一个以文法符号为字母表的DFA。对于任一文法GS,若SA,若是的前缀,则称是G的一个活前缀。活前缀与句柄的关系: 活前缀已含有句柄的全部符号,表明产生式A的 右部已出现在栈顶。 活前缀只含句柄的一部分符号如1表明A12的右部子串1已出现在栈顶,当前期待从输入串中看到2推出的符号。 活前缀不含有句柄的任何符号,此时期望产生式A的右部所推出

4、的符号串。(1)ACTON表和GOTO表的构建每一项ACTION s , a 所规定的动作不外是下述四种可能之一: 移进 把Sj=GOTOSi,a移入到状态栈,把a移入到文法符号栈。其中i,j表示状态号。 归约 当在栈顶形成句柄为时,则用归约为相应的非终结符A,即文法中有A的产生式,若的长度为r(即|=r),则从状态栈和文法符号栈中自栈顶向下去掉r个符号,即栈指针SP减去r。并把A移入文法符号栈内,Sj=GOTOSi,A移进状态栈,其中Si为修改指针后的栈顶状态。 接受acc当归约到文法符号栈中只剩文法的开始符号S时,并且输入符号串已结束即当前输入符是#,则为分析成功。 报错 当遇到状态栈顶为

5、某一状态下出现不该遇到的文法符号时,则报错,说明输入串不是该文法能接受的句子。 若项目Aa属于Ik且转换函数GO(Ik,a)= Ij,当a为终结符时则置ACTIONk,a为Sj,其动作含意为将终结符a移进符号栈,状态j进入状态栈,(相当状态k时遇a转向状态j)。 若项目A 属于Ik,则对任何终结符a 和#号置ACTIONk,a和ACTIONk,#为rj,j为在文法G中某产生式A的序号。rj动作的含义是把当前文法符号栈顶的符号串归约为A,并状态栈指针从栈顶向下移动|的长度 , 文法符号栈从栈顶弹出|个符号,非终结符A变为当前面临的符号。 若GO(Ik,A)Ij,则置GOTOk,A为j,其中A为非

6、终结符,表示当前状态为k时,遇文法符号A时状态应转向j,因此A移入文法符号栈,j移入状态栈。 若项目SS属于Ik,则置ACTIONk,#为acc,表示接受。 凡不能用上述方法填入的分析表的元素,均应填上报错标志。为了表的清晰我们仅用空白表示错误标志。(2)LR(0)项目在文法G中每个产生式的右部适当位置添加一个圆点构成LR(0)项目。我们也可以根据圆点所在的位置和圆点后是终结符还是非终结符把LR(0)项目分为以下几种: 移进项目形如Aa,其中,V*,a VT,即圆点后面为终结符的项目为移进项目,对应状态为移进状态。分析时把a移进符号栈。 待约项目形如AB,其中,V* ,BVN,即圆点后面为非终

7、结符的项目称待约项目,它表明所对应的状态等待着分析完非终结符B所能推出的串归约成B,才能继续分析A右部的B后面部分。 归约项目形如A其中V* ,即圆点在最右端的项目,称归约项目,它表明一个产生式的右部已分析完,句柄已形成可以归约。 接受项目形如SS,其中SVN ,SS为拓广文法的产生式,S为左部的产生式只有一个,因而它是归约项目的特殊情况,对应状态称为接受状态,表明已分析成功。我们规定SS 为初态。(3)LR(0)项目集规范族的构造对于构成识别一个文法活前缀的DFA项目集(状态)的全体我们称之为这个文法的LR(0)项目集规范族。为此,在这里须引入LR(0)项目集的闭包函数CLOSURE和状态转

8、换函数GO两个概念。 闭包函数CLOSURE(I)的定义如下: a)I的项目均在CLOSURE(I)中。b)若AB属于CLOSURE(I),则每一形如B的项目也属于CLOSURE(I)。c)重复b)直到不出现新的项目为止。即CLOSURE(I)不再扩大。 转换函数GO(I,X)的定义: GO(I,X)CLOSURE(J)其中:I为包含某一项目集的状态,X为一文法符号,X(VNVT),J任何形如AX的项目| AX属于I。 这样就可以使用闭包函数和转换函数构造文法G的LR(0)项目集规范族,其步骤如下: a)置项目SS为初态集的核,然后对核求闭包,CLOSURE(SS)得到初态的项目集。 b)对初

9、态集或其它所构造的项目集应用转换函数GO(I,X)=CLOSURE(J),求出新状态J的项目集。c)重复b)直到不出现新的项目为止。五、算法描述核心算法为构建ACTION表和GOTO表,构造文法的所有项目。全局变量的定义以及注释char AnalyzedArrayMAXSIZE; /字符串char VtArrayMAXSIZE; /终结符号数组int NumVt; /终结符号个数char VnArrayMAXSIZE; /非终结符号数组int NumVn; /非终结符号个数char GrammarMAXARRAYMAXARRAY; /文法 数组int NumGrammar; /文法 条数cha

10、r GeneralizationMAXARRAYMAXARRAY;/拓广所有文法,eg E-.aA E-a.A E-aA.int NumGeneralization; /拓广文法 条数int ACTIONMAXSIZEMAXSIZE; /ACTION表 正数=移进 负数=规约 100=接受 0 = 报错int GOTOMAXSIZEMAXSIZE; /GOTO表 存放规约后的状态int INum; /项目集规范族 个数利用二维数组Grammar来存储所有的文法,利用 二维数组Generalization来存储拓广之后的所有文法 。void getDFAGeneralization() /获得文

11、法的所有拓展 即.在文法在文法终点所有位置利用这个函数可以获得所有文法的拓广文法。在实现这个函数的同时需要调用另一个函数:void Insert_ponitosP(int num , char *s , char *G) , 将.插入到制定字符串的指定位置i 并存储到 扩展文法n位置这样只需要进行下标的定位就可以实现.的加入。之后,要进行项目规范族的划分,同一族的项目可以通过到达,所以利用递归算法可以很快实现项目集的划分,在同一族中被选中的项目原本的下标会出现靠后的情况,这时需要引入另一数组Used记录使用情况,如果被选中过,则不可以被再次选中,反之可以进入新的族。void CLOSURE_D

12、FA(DFA *I , int num , char c , int n ,int *U) ,这个函数就是用来实现识别活前缀的DFA 项目集规范族的构建。并且它是递归的函数。获得了每个独立的识别活前缀的DFA 项目集规范族后,下一步,就是要将他们连接起来,连接的弧我们通过终结符号或非终结符号来实现。通过函数void Line_DFA(DFA *I)我们实现了连接项目集规范族。在实现过程中我们调用了int ArcX(char *pro1 , char *pro2) 函数,获得该字符串的弧c后的结果 , 比较pro1和pro2是否只是.的位置不同来确定两个字符串是否只是.的位置不同,因为每个项目都

13、是不同的,当只有.的位置不同时可以确定他们是可以通过某个字符弧连接到的,也可以延伸到规范族可以连接到。前期工作完成后接下来就是置表了。首先完成ACTION表。函数void Action(DFA *I)置Action表 纵坐标是 规范族个数=INum,横坐标是 终结符号 = VtNum。实现过程也如图上述实验功能所述,在此不再赘述。值得一提的是,按实验功能所述,移进时应移进“si”表示状态i进栈,规约“rj”表示按照第j个文法进行规约,我在这里小小的动一下脑筋,因为存入“si”相当于字符串,存储和读取都非常的麻烦,所以我利用数字的“+”“-”区分存储和读取,“+”为移进,“-”为规约。当然第一步

14、是要初始化ACTION表全部赋值为“错误”的值,之后进行表的构建会将“错误”值替换。GOTO表的构建如同ACTION表的过程,细心就好。万事俱备,只欠分析。最后一步也是最重要的一步就是分析函数void Analysis(seq *L , char *S , DFA *I),这是用来传入待分析串并且返回结果是否符合LR0文法。函数的实现方法也如同实验功能所述,但是在结构体的创建时要想好需要什么标识符来标识需要用到的信息,比如该规范族通过某字符连接到下一规范族的下标需要存储等等。六、运行结果第一组正常数据第二组正常数据不正常数据七、调试情况初期设计思想比较迷茫,不知道LR0语法分析器的编写从何开始

15、,无从下手。所以只能从书上找到切入点。按照书上的要求和提示,我进行了一步步的编写,偶尔出现要寻找下标的困难就要从存储方式上找捷径,就这样程序逐渐丰满起来。我为了保证每一个模块的完整性,每次写完一个函数就要测试一下测试用例,对比着正确过程修改代码实现功能。在写完所有功能,测试完功能过后就要进行优化。优化包括界面的优化和算法优化。八、实验总结及体会开始对这次试验比较有兴趣,得知同学们都在写算符优先文法和LL1语法分析器后,我并没有后悔,只有LR0才能有挑战的快感,正因为如此我也找到了乐趣。编写代码过程中确实有困扰的地方,包括为了实现一种功能想出了一条最容易想到的算法,但是时间复杂度很高,我会再想更先进的文法。因为这样我编写的速度比较慢。但是在程序全部完成的那一刻,我体会到了成就感。九、源程序清单(电子版)(另附文件。)

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

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