编译原理实验LL1文法的判断及转换Word文件下载.docx
《编译原理实验LL1文法的判断及转换Word文件下载.docx》由会员分享,可在线阅读,更多相关《编译原理实验LL1文法的判断及转换Word文件下载.docx(13页珍藏版)》请在冰豆网上搜索。
给出一个非终结符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)
终结符:
self.Vt)
开始符号:
self.start)
产生式如下:
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<
len(temp):
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():
ifinotindeleteIndex:
lp=temp[i].split('
rp=temp[i].split('
rlsit=list(rp)
forjinrange(len(rlsit)):
ifself.isEmpty[rlsit[j]]==1:
ifj==len(rlsit)-1:
self.isEmpty[lp]=1
elifself.isEmpty[rlsit[j]]==0:
continue
defshow(self):
非终结符能否推导出空的信息:
forvinself.Vn:
ifself.isEmpty[v]==1:
yon='
是'
否'
%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('
rp=self.produce[i].split('
rlist=list(rp)
ifrlist[0]=='
orrlist[0]inself.Vt:
ifrlist[0]notinself.First[lp]:
self.First[lp].append(rlist[0])
isChange[lp]=1
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:
ifjnotinself.First[lp]:
if1notinisChange.values():
First集合不在增大!
First集合有增大!
pass
defshowFirst(self):
First集合信息:
print(v,self.First[v])
defcanCauseEmpty(self,plist):
first=list()
iflen(plist)==0:
first.append('
foriinplist:
ifiinself.Vn:
ifself.isEmpty[i]==1:
t=self.First[i][:
int:
t.remove('
forkint:
ifknotinfirst:
first.append(k)
.join(plist).endswith(i)and'
notinfirst:
forkinself.First[i]:
ifinotinfirst:
first.append(i)
returnfirst
defgetFollow(self):
self.Follow=dict()
self.Follow[i]=list()
self.Follow[self.start].append('
forjinrange(len(rlist)):
ifrlist[j]inself.Vn:
reslist=self.canCauseEmpty(rlist[j+1:
])
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]])
isChange[rlist[j]]=1
forxinreslist:
ifx!
='
andxnotinself.Follow[rlist[j]]:
self.Follow[rlist[j]].append(x)
defshowFollow(self):
Follow集合信息:
forkeyinself.Vn:
print(key,self.Follow[key])
defgetSelect(self):
self.Select=dict()
foriinself.produce:
self.Select[i]=list()
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])
res=self.canCauseEmpty(rlist)
notinres:
forvinres:
ifvnotinself.Select[self.produce[i]]andv!
defshowSelect(self):
Select集合信息:
forkeyinself.produce:
print(key,self.Select[key])
defisLLone(self):
isright=[]
tset=set()
tset.add('
tset=tset|set(self.Vt)
ifk==l:
p=l+'
+r
tset=tset&
set(self.Select[p])
iflen(tset)==0:
isright.append
(1)
isright.append(0)
if0inisright:
不是LL
(1)文法!
self.isll1=False
是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、运行结果截图