完整word版编译原理实验LL1文法的判断及转换word文档良心出品.docx

上传人:b****5 文档编号:29630478 上传时间:2023-07-25 格式:DOCX 页数:15 大小:66.39KB
下载 相关 举报
完整word版编译原理实验LL1文法的判断及转换word文档良心出品.docx_第1页
第1页 / 共15页
完整word版编译原理实验LL1文法的判断及转换word文档良心出品.docx_第2页
第2页 / 共15页
完整word版编译原理实验LL1文法的判断及转换word文档良心出品.docx_第3页
第3页 / 共15页
完整word版编译原理实验LL1文法的判断及转换word文档良心出品.docx_第4页
第4页 / 共15页
完整word版编译原理实验LL1文法的判断及转换word文档良心出品.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

完整word版编译原理实验LL1文法的判断及转换word文档良心出品.docx

《完整word版编译原理实验LL1文法的判断及转换word文档良心出品.docx》由会员分享,可在线阅读,更多相关《完整word版编译原理实验LL1文法的判断及转换word文档良心出品.docx(15页珍藏版)》请在冰豆网上搜索。

完整word版编译原理实验LL1文法的判断及转换word文档良心出品.docx

完整word版编译原理实验LL1文法的判断及转换word文档良心出品

2016.11.30

LL

(1)文法的判断及转换

一、实验名称

LL

(1)文法的判断及转换

二、实验目的

输入:

任意一个文法

输出:

(1)是否为LL

(1)文法

(2)若是,给出每条产生式的select集

(3)若不是,看看是否含有左公共因子或者含有左递归,并用相应的方法将非LL

(1)文法变成LL

(1)文法,并输出新文法中每条产生式的select集。

三、实验原理

1、First集定义

令X为一个文法符号(终止符或非终止符)或ε,则集合First(X)有终止符组成,此外可能还有ε,它的定义如下:

1. 若X是终止符或ε,则First(X)= {X}。

2. 若X是非终结符,则对于每个产生式X—>X1X2…Xn,First(X)包含了First(X1)-{ε}。

若对于某个i < n,所有的集合First(X1),... ,First(Xi)都包含了ε,则First(X)也包 括了First(Xi+1)- {ε}。

若所有集合First(X1),...,First(Xn)都包括了ε,则First(X)也包括了ε。

2、Follow集定义

给出一个非终结符A,那么集合Follow(A)则是由终结符组成,此外可能还含有#(#是题目约定的字符串结束符)。

集合Follow(A)的定义如下:

1.若A是开始符号,则#在Follow(A)中。

2.若存在产生式B—>αAγ,则First(γ)-{ε}在Follow(A)中。

3.若存在产生式B—>αAγ,且ε在First(γ)中,则Follow(A)包括Follow(B)。

3、Select集定义

对于产生式A—>α。

集合select(A—>α)定义如下:

1.若α不能推出ε,则select(A—>α)=first(α)。

2.若α能推出ε,则select(A—>α)=first(α)∪follow(A)。

4、含左递归文法

一个文法G,若存在P经过一次或多次推导得到Pa(即能推导出以P开头的式子),则称G是左递归的。

  

左递归分为直接左递归和间接左递归。

  

直接左递归经过一次推导就可以看出文法存在左递归,如P→Pa|b。

  

间接左递归侧需多次推导才可以看出文法存在左递归,如文法:

S→Qc|c,Q→Rb|b,R→Sa|a有S=>Qc=>Rbc=>Sabc

四、实验思路

本次实验采用python完成。

1、求非终结符是否能导出空

a.第一轮扫描。

当前的产生式还没被删除,非终结符lp可以导出空,将以该非终结符为左部的产生式标记为要删除的。

产生式右部分解,若该产生式右部包含终结符,删除该产生式因为由它不会导出空。

判断没有被删除的产生式中是否还有以该非终结符为左部的产生式。

b.第二轮扫描。

逐一扫描每一条产生右部的每一个符号,循化直至每个非终结符的状态都确定下来。

2、求First集算法

存储每一个非终结符对应的First集,扫描每一条产生式,记录每一轮扫描是每个非终结符First集是否增大过。

全部初始化为没有增大的状态,对于课本的五种类型依次求解,每次将结果加入对应的集合中,若一次扫描First集没有增大,则说明循环结束。

3、求Follow集算法

存储每一个非终结符对应的Follow集,将'#'加入文法的开始符号的Follow集合中,记录每一轮扫描是每个非终结符Follow集合是否增大过,全部初始化为没有增大的状态,扫描每一条产生式的右部,扫描到非终结符,判断在该非终结符之后的子串能否推导空,若该符号串可以推导出空,还要将Follow(lp)加入到里面。

4、求Select集算法

初始化每条产生式对应的Select集合为空,若产生式右部不能推导出空,则将右部的First集加入Select集,如果可以推出空,则需要同时将左部的Follow集合右部的First集去掉空的部分加入Select集。

五、实验小结

通过本次实验,知道了如何判断一个文法是不是LL

(1)文法,同时对于First、Follow以及Select集的求解原理变得更加熟悉,并且知道了如何用计算机语言求解First,Follow以及Select集。

不足之处是,没有完成判断文法是否为左递归文法以及左递归文法的转换部分。

六、附件

1、源代码

classGw:

def__init__(self):

withopen('Gw.txt')asf:

content=f.readlines()

content=[line.strip()forlineincontent]

self.Vn=content[0].split('')

self.Vt=content[1].split('')

self.start=content[2]

self.produce=[]

self.left=[]

self.right=[]

foriinrange(3,len(content)):

self.produce.append(content[i])

self.left.append(content[i].split('->')[0])

self.right.append(content[i].split('->')[1])

defshowGw(self):

print('非终结符:

',self.Vn)

print('终结符:

',self.Vt)

print('开始符号:

',self.start)

print('产生式如下:

')

forl,rinzip(self.left,self.right):

print(l+'->'+r)

defcanEmpty(self):

self.isEmpty=dict()

foriinrange(len(self.Vn)):

self.isEmpty[self.Vn[i]]=-1

print(self.isEmpty)

temp=self.produce[:

:

]

deleteIndex=[]

pointer=0

whilepointer

ifpointernotindeleteIndex:

lp=temp[pointer].split('->')[0]

rp=temp[pointer].split('->')[1]

ifrp=='!

':

self.isEmpty[lp]=1

foriinrange(len(temp)):

iftemp[i].split('->')[0]==lpandinotindeleteIndex:

deleteIndex.append(i)

l=list(rp)

isContainVt=[iinself.Vtforiinl]

ifTrueinisContainVt:

deleteIndex.append(pointer)

forkinrange(len(temp)):

ifknotindeleteIndex:

iftemp[k].split('->')[0]==lp:

break

else:

self.isEmpty[lp]=0

pointer=pointer+1

while-1inself.isEmpty.values():

foriinrange(len(temp)):

ifinotindeleteIndex:

lp=temp[i].split('->')[0]

rp=temp[i].split('->')[1]

rlsit=list(rp)

forjinrange(len(rlsit)):

ifself.isEmpty[rlsit[j]]==1:

ifj==len(rlsit)-1:

self.isEmpty[lp]=1

elifself.isEmpty[rlsit[j]]==0:

deleteIndex.append(i)

forkinrange(len(temp)):

ifknotindeleteIndex:

iftemp[k].split('->')[0]==lp:

break

else:

self.isEmpty[lp]=0

else:

continue

defshow(self):

print('非终结符能否推导出空的信息:

')

forvinself.Vn:

ifself.isEmpty[v]==1:

yon='是'

else:

yon='否'

print('%s:

%s'%(v,yon))

defgetFirst(self):

self.First=dict()

foriinself.Vn:

self.First[i]=list()

isChange=dict()

whileTrue:

forkinself.Vn:

isChange[k]=0

foriinrange(len(self.produce)):

lp=self.produce[i].split('->')[0]

rp=self.produce[i].split('->')[1]

rlist=list(rp)

ifrlist[0]=='!

'orrlist[0]inself.Vt:

ifrlist[0]notinself.First[lp]:

self.First[lp].append(rlist[0])

isChange[lp]=1

else:

forjinrlist:

ifjinself.Vn:

ifself.isEmpty[j]==1:

oldsize=len(self.First[lp])

templist=self.First[j][:

:

]

if'!

'intemplist:

templist.remove('!

')

forxintemplist:

ifxnotinself.First[lp]:

self.First[lp].append(x)

ifrp.endswith(j)and'!

'notinself.First[lp]:

self.First[lp].append('!

')

newsize=len(self.First[lp])

ifoldsize!

=newsize:

isChange[lp]=1

else:

oldsize=len(self.First[lp])

ifjinself.Vn:

templist=self.First[j][:

:

]

forxintemplist:

ifxnotinself.First[lp]:

self.First[lp].append(x)

else:

ifjnotinself.First[lp]:

self.First[lp].append(x)

newsize=len(self.First[lp])

ifoldsize!

=newsize:

isChange[lp]=1

break

if1notinisChange.values():

print('First集合不在增大!

')

break

else:

print('First集合有增大!

')

pass

defshowFirst(self):

print('First集合信息:

')

forvinself.Vn:

print(v,self.First[v])

defcanCauseEmpty(self,plist):

first=list()

iflen(plist)==0:

first.append('!

')

else:

foriinplist:

ifiinself.Vn:

ifself.isEmpty[i]==1:

t=self.First[i][:

:

]

if'!

'int:

t.remove('!

')

forkint:

ifknotinfirst:

first.append(k)

if''.join(plist).endswith(i)and'!

'notinfirst:

first.append('!

')

else:

forkinself.First[i]:

ifknotinfirst:

first.append(k)

break

else:

ifinotinfirst:

first.append(i)

break

returnfirst

defgetFollow(self):

self.Follow=dict()

foriinself.Vn:

self.Follow[i]=list()

self.Follow[self.start].append('#')

isChange=dict()

whileTrue:

forkinself.Vn:

isChange[k]=0

foriinrange(len(self.produce)):

lp=self.produce[i].split('->')[0]

rp=self.produce[i].split('->')[1]

rlist=list(rp)

forjinrange(len(rlist)):

ifrlist[j]inself.Vn:

reslist=self.canCauseEmpty(rlist[j+1:

:

])

if'!

'inreslist:

oldsize=len(self.Follow[rlist[j]])

foryinself.Follow[lp]:

ifynotinself.Follow[rlist[j]]:

self.Follow[rlist[j]].append(y)

newsize=len(self.Follow[rlist[j]])

ifoldsize!

=newsize:

isChange[rlist[j]]=1

else:

pass

oldsize=len(self.Follow[rlist[j]])

forxinreslist:

ifx!

='!

'andxnotinself.Follow[rlist[j]]:

self.Follow[rlist[j]].append(x)

newsize=len(self.Follow[rlist[j]])

ifoldsize!

=newsize:

isChange[rlist[j]]=1

if1notinisChange.values():

break

defshowFollow(self):

print('Follow集合信息:

')

forkeyinself.Vn:

print(key,self.Follow[key])

defgetSelect(self):

self.Select=dict()

foriinself.produce:

self.Select[i]=list()

foriinrange(len(self.produce)):

lp=self.produce[i].split('->')[0]

rp=self.produce[i].split('->')[1]

rlist=list(rp)

ifrlist[0]=='!

':

forvinself.Follow[lp]:

ifvnotinself.Select[self.produce[i]]:

self.Select[self.produce[i]].append(v)

elifrlist[0]inself.Vt:

self.Select[self.produce[i]].append(rlist[0])

else:

res=self.canCauseEmpty(rlist)

if'!

'notinres:

forvinres:

ifvnotinself.Select[self.produce[i]]:

self.Select[self.produce[i]].append(v)

else:

forvinres:

ifvnotinself.Select[self.produce[i]]andv!

='!

':

self.Select[self.produce[i]].append(v)

forvinself.Follow[lp]:

ifvnotinself.Select[self.produce[i]]:

self.Select[self.produce[i]].append(v)

defshowSelect(self):

print('Select集合信息:

')

forkeyinself.produce:

print(key,self.Select[key])

defisLLone(self):

isright=[]

forkinself.Vn:

tset=set()

tset.add('#')

tset=tset|set(self.Vt)

forl,rinzip(self.left,self.right):

ifk==l:

p=l+'->'+r

tset=tset&set(self.Select[p])

iflen(tset)==0:

isright.append

(1)

else:

isright.append(0)

if0inisright:

print('不是LL

(1)文法!

')

self.isll1=False

else:

print('是LL

(1)文法!

')

self.isll1=True

print(isright)

if__name__=='__main__':

w=Gw()

w.showGw()

w.canEmpty()

w.show()

w.getFirst()

w.showFirst()

w.getFollow()

#res=w.canCauseEmpty(['A','D'])

#print('res=',res)

w.showFollow()

w.getSelect()

w.showSelect()

w.isLLone()

2、运行结果截图

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

当前位置:首页 > 医药卫生 > 基础医学

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

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