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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

实验3LL1文法构造.docx

1、实验3LL1文法构造实 验 报 告实验课程: 编译原理 学生姓名: 学 号: 专业班级: 计科 实验3 LL(1)文法构造一、实验目的熟悉LL(1)文法的分析条件,了解LL(1)文法的构造方法。二、实验内容1、编制一个能够将一个非LL(1)文法转换为LL(1)文法;2、消除左递归;3、消除回溯。三、实验要求1、 将一个可转换非LL(1)文法转换为LL(1)文法,要经过两个阶段,1)消除文法左递归,2)提取左因子,消除回溯。2、 提取文法左因子算法:1)对文法G的所有非终结符进行排序2)按上述顺序对每一个非终结符Pi依次执行:for( j=1; j Pi| ,其中不以Pi开头,则修改产生式为:P

2、i PiPi Pi|3)化简上述所得文法。3、 提取左因子的算法: A 1|2|n|1|2|m (其中,每个不以开头)那么,可以把这些产生式改写成 A A|1| 2|m A1|2|n4、 利用上述算法,实现构造一个LL(1)文法:1) 从文本文件g.txt中读入文法,利用实验1的结果,存入实验1设计的数据结构;2) 设计函数remove_left_recursion()和remove_left_gene()实现消除左递归和提取左因子算法,分别对文法进行操作,消除文法中的左递归和提出左因子;3) 整理得到的新文法;4) 在一个新的文本文件newg.txt输出文法,文法输出按照一个非终结符号一行,

3、开始符号引出的产生式写在第一行,同一个非终结符号的候选式用“|”分隔的方式输出。四、实验环境PC微机DOS操作系统或 Windows 操作系统Turbo C 程序集成环境或 Visual C+ 程序集成环境五、实验步骤 1、学习LL(1)文法的分析条件; 2、学习构造LL(1)文法的算法;3、结合实验1给出的数据结构,编程实现构造LL(1)文法的算法;4、结合实验1编程和调试实现对一个具体文法运用上述算法,构造它的LL(1)文法形式;5、 把实验结果写入一个新建立的文本文件。六、测试数据 输入数据:编辑一个文本文文件g.txt,在文件中输入如下内容:S-Qc|c|cab;Q-Rb|b;R-Sa

4、|a; 正确结果: 本实验的输出结果是不唯一的,根据消除左递归是选择非终结符号的顺序不同,或选择新的非终结符号的不同,可能会得到不同的结果,下面只是可能的一个结果:S-Qc|cT;T-|ab; /由于无法输出,用代替Q-Rb|b;R-bcaU|caU|cabaU|aU;U-bcaU|; 七、实验报告要求实验报告应包括以下几个部分:1、 满足LL(1)文法的分析条件;2、 构造LL(1)文法的算法;3、 消除左递归文法和提取左因子算法实现方法;4、 整个测试程序的流程;5、 程序的测试结果和问题;6、 实验总结。代码#include #include using namespace std; t

5、ypedef struct Chomsky /定义一个产生式结构体 string left; /定义产生式的左部 string right; /定义产生式的右部 Chomsky; int n;/产生式总数 string strings;/存储产生式 char q20; void apart(Chomsky *p,int i) /分开产生式左右部i代表产生式的编号 int j; for(j=0;jstrings.length();j+) if(stringsj=-) pi.left=strings.substr(0,j);/从0开始的j长度的子串即0j-1 pi.right=strings.su

6、bstr(j+1,strings.length()-j);/从j+1开始的后面子串 int zero(Chomsky *p)/0型文法 int flag(0),count(0); int i,j; for(i=0;in;i+) for(j=0;j=A&pi.leftj0)/说明某一个产生式左部有非终结符 flag=0;/下个产生式判断前清零 count+;/左部存在非终结符的产生式 个数加1 else break; /左部没有非终结符结束 if(count=n) return 1; /属于0型文法 else coutendl所输产生式不属于任何文法。endl; return 0; int on

7、e(Chomsky *p)/1型文法 int flag(0); int i; if(zero(p) for(i=0;in;i+) if(pi.right.length()0) coutendl此文法属于0型文法即短语文法。endl; return 0; /不属于1型文法 else if(flag=0) return 1; /属于1型文法 else return 0; int two(Chomsky *p)/2型文法 int flag(0); int i; if(one(p) for(i=0;i=A&pi.left00) coutendl此文法属于1型文法即上下文有关文法。endl; retur

8、n 0; /不属于2型文法 else if(flag=0) return 1; /属于2型文法 else return 0; int remove(Chomsky *p,int n)/消除左递归 /把文法的所有非终结符按某一顺序排序 int i,j,count=1,count1=n,flag=0,m,x; q0=p0.left0; for(i=1;in;i+) for(j=0;ji;j+) if(pi.left=pj.left)break; if(j=i)qcount+=pi.left0; count-; for(i=0;in;i+)/判断第一个非终结符是否存在直接左递归 if(pi.left

9、0=q0&pi.left0=pi.right0) flag+; if(flag!=0)/消除第一个非终结符的直接左递归 for(i=0;in;i+) if(pi.left0=q0) if(pi.left0=pi.right0) pi.left=pi.left+; pi.right=pi.right.substr(1,pi.right.length()+pi.left; else pi.right=pi.right+pi.left+; pcount1.left=p0.left; pcount1+.right=#;/用#代替空产生式 /消一切左递归 for(m=0;m=count;m+) for(

10、i=0;in;i+) if(pi.left0=qm) for(j=0;jcount1;j+) for(x=m+1;x=count;x+) if(pj.left0=qx&pj.right0=qm) pcount1.left=pj.left; pcount1.right=pi.right+pj.right.substr(1,pj.right.length(); count1=count1+1; for(j=0;jcount1;j+) for(x=m+1;x=count;x+) if(pj.right0=qm&pj.left0=qx) pj.right=; pj.left=; for(x=0,fla

11、g=0;xcount1;x+)/判断第m个非终结符是否存在直接左递归 if(px.left0=qm&px.left0=px.right0) flag+; /消直接左递归 if(flag!=0) for(i=0;icount1;i+) if(pi.left0=qm) if(pi.left0=pi.right0) pi.left=pi.left+; pi.right=pi.right.substr(1,pi.right.length()+pi.left; pcount1.left=pi.left; pcount1.right=#;/用#代替空产生式 else pi.right=pi.right+p

12、i.left+; count1=count1+1; count1-; return count1; void main( ) int i,j,count1; cout.编译原理实验非LL(1)文法到LL(1)文法的转换.endl; cout请输入产生式总数及各产生式endl其中左右部之间用-表示空用#表示n; Chomsky *p=new Chomsky50; / 初始化产生式数组 for(i=0;istrings; apart(p,i); if(two(p) cout该文法属于二型文法实验继续.endl; count1=remove(p,n); cout转换后的文法输出如下endl; for(i=0;i=count1;i+) if(pi.left0!=NULL) coutpi.leftpi.rightendl; else cout该文法不是2型文法无需进行LL(1)的转换实验结束endl; system(pause); 八、思考题1、 是不是所有的文法都可以通过上述程序构造LL(1)文法? 2、 LL(1)文法在整个语法分析中的作用? 3、 实验1中设计的文法数据结构对本实验的影响?4、 如何更好地组合实验1和实验3,使之具有更高的效率?

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

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