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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

编译原理实验自动生成LR0分析表.docx

1、编译原理实验自动生成LR0分析表2016.12.14自动生成LR(0)分析表 一、实验名称 自动生成LR(0)分析表二、实验目的1、实现计算闭包函数CLOSURE的算法。2、实现转向函数GO(I,X)的算法。 3、实现ACTION子表和GOTO子表的构造算法。4、输入任意的压缩了的上下文无关文法,输出相应的LR(0)分析表(以表格形式输出)。三、实验原理 1、闭包closure(I) 若文法G已拓广为G,而S为文法G的开始符号,拓广后增加产生式S-S。如果I是文法G的一个项目集,定义和构造I的闭包closure(I)如下: a.I的项目在closure(I)中。 b.若A-B属于closure

2、(I),则每一形如B-的项目也属于closure(I)。 c.重复b直到不出现新的项目为止。即closure(I)不再扩大。2、转换函数GO(I,X)GO(I,X)=closure(J)其中:I为包含某一项目集的状态。X为一文法符号,XVnVtJ=任何形如A-X的项目|A-X属于I3、ACTION子表和GOTO子表的构造a.若项目A.a属于Ik且GO (Ik, a)= Ij, a为终结符,则置ACTIONk, a为“把状态j和符号a移进栈”,简记为“sj”; b.若项目A属于Ik,那么,对任何终结符a,置ACTIONk,a为“用产生式A进行规约”,简记为“rj”;其中,假定A为文法G的第j个产

3、生式c.若项目SS属于Ik, 则置ACTIONk, #为“接受”,简记为“acc”; d.若GO (Ik, A)= Ij, A为非终结符,则置GOTOk, A=j; e.分析表中凡不能用上述1至4填入信息的空白格均置上“出错标志”。 按上述算法构造的含有ACTION和GOTO两部分的分析表,如果每个入口不含多重定义,则称它为文法G的一张LR(0)分析表。具有LR(0)表的文法G称为一个LR(0)文法,LR(0)文法是无二义的。四、实验思路 本次实验采用python完成。 1、输入 构造一个LR类,输入非终结符,终结符,开始符以及产生式分别存于LR类的成员:Vn,Vt,start,product

4、ion。 2、建立项目 构造函数Project,根据产生式建立项目,对每一条产生式的右部进行处理,依次在右部的每个终结符和非终结符前添加原点,并在最后添加原点。 3、closure算法 构造函数closure,求一个项目的闭包closure。分三种情况讨论,对于S-和E-a这两种情况,返回自身。对于E-bB这种情况,对项目的右部进行处理,继续求B-r闭包,因此这是一个递归函数。最终函数以列表的形式返回每个项目集。 4、转向函数GO(I,X)的算法 构造函数GO,求一个项目集的GO(I,X)。建立字典go存放最终结果,对不是S-a形式的项目进行讨论,对项目的右部进行处理,将原点后移一位,利用cl

5、osure函数得到圆点后移得到的项目的项目集,加入go中。直到处理完该项目集的所有项目。 5、建立状态及对应的项目集 构造函数createDFA,建立状态及对应的项目集。首先,从拓广文法的第一个项目开始,建立初态,定义number存放状态编号,初始值为0。设立字典status存放状态编号及对应的项目集。将初态加入一个队列qu中。每次从qu中取出一个状态,求该状态的项目集的Go(I,x),再对得到的项目集进行判断,若该项目集是已知的状态,则不做处理,若该项目集是新的状态,则将其加入队列qu中,number加1。每次从qu中取出一个状态重复上述操作,直到队列为空,说明已求得所有状态。6、ACTIO

6、N子表的构造 分两种情况讨论:项目集只有一个项目和项目集不止一个项目。对于第一种情况,再分两种情况,看该项目是否对应了初态,若是,则将#对应为acc,其余终结符对应为error,若不是,则求得该项目去掉圆点之后的产生式的编号i,终结符合#对应为ri。对于项目集不止一个项目的情况,依次对终结符和#寻找在该状态的的GO(I,X)下是否有所对应,有则求得编号对应为Si,没有则对于error。7、GOTO子表的构造 对于每个状态的GO(I,X)函数进行遍历,寻找是否有对应的终结符,若有则返回对应的项目集的编号,若没有则返回error。五、实验小结 通过本次实验,了解了LR(0)分析表的构造,对于构造过

7、程所需要的一些算法有了深入的了解,通过实际的编写程序代码完成LR(0)分析表的构造,对于程序的编写能力有了一定的提升。在实验过程中,主要对于closure闭包函数的构造以及状态的设置有问题。Closure闭包函数用了递归的结构,因此对于递归的结束条件需要标注清楚。对于状态的建立,需要注意每次通过GO(I,X)得到的新的项目集是否是已经存在的状态,若是则不做处理。对于状态的遍历使用队列来完成,每次新的状态都加入队列中,队列为空说明状态遍历完毕。有一点问题值得注意,由于状态编号的项目集的存储结构使用了字典,字典是无序的结构,因此每次遍历得到的状态编号都不同,程序的每次运行得到的最终LR(0)分析表

8、不唯一。六、附件1、源代码import copyimport queueclass LR: def _init_(self): self.Vn = self.Vt = self.start = None # 开始符号 self.production = # 产生式 self.project = # 项目 self.status = # 存放状态编号及对应的项目集 self.goto = # 存放goto表 0:E:1,A:error,B:error self.action = # 存放action表 0:a:S2,b:S3 def setVn(self): Vn = input(输入非终结符(

9、以空格区分, 回车结束):) self.Vn = Vn.split( ) def setVt(self): Vt = input(输入终结符(以空格区分, 回车结束):) self.Vt = Vt.split( ) def setS(self): S = input(输入开始符号(以回车结束):) self.start = S def setf(self): # 生成产生式 n = int(input(输入产生式数目:) print(输入产生式(以回车区分):) for i in range(n): f = input() self.production.append(f) def Proje

10、ct(self): # 建立项目 for f in self.production: temporary = copy.deepcopy(f) # temporary与f相同 temporary = temporary.split(-) l = temporary0 # 产生式左部 r = list(temporary1) # 产生式右部 for i in range(len(r)+1): # 对产生式右部处理 temporary1 = copy.deepcopy(r) temporary1.insert(i,) newf = l+-+.join(temporary1) self.projec

11、t.append(newf) def closure(self, pro): # 求一个项目pro的闭包 E- E-b E-bB 返回列表 temporary = # 最终返回的结果 temporary.append(pro) # 将pro自身加入 l1 = pro.split(-)0 # 左部 r1 = pro.split(-)1 # 右部 x = list(r1) # 存放右部的列表 index = x.index() # 得到圆点位置 if len(x) = 1: # S- return temporary else: if index = len(r1)-1 or xindex+1 i

12、n self.Vt: #E-a return temporary else: # E-bB for elem in range(len(self.project): l = self.projectelem.split(-)0 # 左部 r = self.projectelem.split(-)1 # 右部 if l = xindex+1 and r.startswith(): # 继续求B-r闭包 conlist = self.closure(self.projectelem) if len(conlist) = 0: pass else: temporary.extend(conlist)

13、 return temporary def GO(self, project): # 计算一个项目集的GO(I,x),返回字典形式 go = # 存放Go(I,x)结果,形式为a:,b: for elem in project: l = elem.split(-)0 # 项目左部 r = elem.split(-)1 # 项目右部 index = list(r).index() # 返回的位置 if not r.endswith(): # 不是S-a形式 if go.get(list(r)index+1) = None: # 说明x所对应的go中没有项目 temporary = list(r)

14、 temporary.insert(index+2, ) temporary.remove() # 将后移一位 x = l+-+.join(temporary) # 产生一个完整的项目 golist(r)index+1 = self.closure(x) # 将该项目对应的项目集加入x的go中 else: # 说明x所对应的go中已有项目 temporary = list(r) temporary.insert(index+2,) temporary.remove() # 将后移一位 x = l+-+.join(temporary) # 产生一个完整的项目 golist(r)index+1.e

15、xtend(self.closure(x) return go def createDFA(self): # 建立识别活前缀的DFA number = 0 # 初始状态编号为0 first = S-+self.start # 初态 x = self.closure(first) # 初态闭包 self.statusnumber = x qu = queue.Queue() # 构造队列,用于存放得到的状态 qu.put(number:self.statusnumber) # 把初始状态加入队列中 number = number+1 while not qu.empty(): # 队列不为空,说

16、明状态没有遍历完毕 temporary = qu.get() # 队列中取出一个状态 for k, v in temporary.items(): y = self.GO(v) # 求项目集的Go(I,x) for key, value in y.items(): flag = -1 # 标志位,判断value是否是新的状态 for ke, va in self.status.items(): if set(va) = set(value): flag = ke # 状态已存在,返回状态编号 break if flag = -1: # 新的状态,加入状态集中 self.statusnumber

17、 = value qu.put(number:self.statusnumber) else: # 已有状态 pass # 不作处理 def GOTO(self): # goto表 for i in range(len(self.status): self.gotoi = temp = self.GO(self.statusi) # 每个状态的GO for vn in self.Vn: # 对非终结符遍历 if vn in temp.keys(): # 非终结符存在于状态的Go中 for key, value in self.status.items(): if set(value) = se

18、t(tempvn): number = key # 记录编号 break self.gotoivn = number else: self.gotoivn = error def ACTION(self): vtx = copy.deepcopy(self.Vt) vtx.append(#) # 终结符加# for i in range(len(self.status): self.actioni = if len(self.statusi) = 1: # 项目集只有一个项目 if self.statusi0.startswith(S): # S-E for vt in self.Vt: se

19、lf.actionivt = error self.actioni# = acc else: # 填写rj的项目 E-aA temp = self.statusi0.rstrip() # 删去项目的 E-aA for n in range(len(self.production): if self.productionn = temp: m = n+1 # 产生式在G中下标从1开始 break for vt in vtx: self.actionivt = r+str(m) else: # 填写Sj的项目 temp = self.GO(self.statusi) # 字典形式a:,b: for

20、 vt in vtx: if vt in temp.keys(): for key, value in self.status.items(): # 确定到哪一个状态 if set(value) = set(tempvt): number = key # 返回状态编号 break self.actionivt = S+str(number) else: self.actionivt = error def output(self): # 输出LR(0)分析表 表格形式 print(LR(0)分析表.center(85) print(状态.center(5), ACTION.center(50)

21、, GOTO.center(30) print( .center(10),end=) for vt in self.Vt: # action print(vt.center(10),end=) print(#.center(10),end=) for vn in self.Vn: # goto print(vn.center(10),end=) print() # 换行 vtx = copy.deepcopy(self.Vt) vtx.append(#) for i in range(len(self.status): # 输出每一行 print(str(i).center(10),end=)

22、 for vt in vtx: for key in self.actioni: # 0:b:S1 if vt = key: print(self.actionikey.center(10),end=) break for vn in self.Vn: for key in self.gotoi: if vn = key: print(str(self.gotoikey).center(10),end=) break print() # 换行 def show(self): # 显示各个状态及对应的项目集 print(所有状态及对应的项目集:) for key, value in self.status.items(): print(key, value)if _name_ = _main_: print(E21414020 陈国柱) a = LR() a.setVn() a.setVt() a.setS() a.setf() a.Project() a.createDFA() a.ACTION() a.GOTO() a.show() a.output()2、运行结果截图

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

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