代码
def inputGrammer():
grammer
=[]
print('箭头请用符号→')
print('空串请用符号ε')
print('____________________________')
while(True):
production
=input()
if(production
=='$'):
break;
elif (production
[-1:] == '$'):
grammer
.append
(production
[:-1])
break;
else:
grammer
.append
(production
)
return grammer
def cut(grammer
):
grammer1
= []
for i
in range(len(grammer
)):
s
=grammer
[i
]
if '|' in s
:
while True:
index
= s
.find
('|')
grammer1
.append
(s
[:index
])
index2
= s
.find
('→')
s1
=s
[:index2
+ 1] + s
[index
+ 1:]
if '|' not in s1
:
grammer1
.append
(s1
)
break
else:
s
=s1
else:
grammer1
.append
(grammer
[i
])
return grammer1
First
={}
Follow
={}
def initializeFirstAndFollow(grammer
):
VN
=[]
for i
in range(len(grammer
)):
s
=grammer
[i
]
for j
in range(len(s
)):
if(s
[j
]>='A' and s
[j
]<='Z'):
if(j
<len(s
)-1 and s
[j
+1]=='\''):
vn
=s
[j
]+'\''
if vn
not in VN
:
VN
.append
(vn
)
else:
vn
= s
[j
] + ''
if vn
not in VN
:
VN
.append
(vn
)
global First
global Follow
for i
in range(len(VN
)):
First
[VN
[i
]]=[]
Follow
[VN
[i
]]=[]
Follow
[VN
[0]].append
('$')
def findFirstVN(s
):
length
=len(s
)
for i
in range(length
):
if s
[i
]>='A' and s
[i
]<='Z':
if(i
<length
-1):
if(s
[i
+1]=='\''):
return s
[i
:i
+2]
else:
return s
[i
]
else:
return s
[i
]
return '$'
def findNextVN(s
):
length
=len(s
)
vn
=findFirstVN
(s
)
index
=s
.find
(vn
)
length1
=len(vn
)
return findFirstVN
(s
[index
+length1
:])
def findLastVN(s
):
length
=len(s
)
index
=0
if s
[length
-1:]<'A' or s
[length
-1:]>'Z':
if s
[length
-1:]!='\'':
return findFirstVN
(s
)
for i
in range(length
):
if s
[i
]>='A' and s
[i
]<='Z':
index
=i
if index
==length
-1:
return s
[index
]
else:
if s
[index
+1]=='\'':
return s
[index
:index
+2]
else:
return s
[index
]
def lookVT(grammer
):
global First
for i
in range(len(grammer
)):
s
= grammer
[i
]
index
= s
.find
('→')
left
= s
[:index
]
right
= s
[index
+ 1:]
if right
[0]<'A' or right
[0]>'Z':
if right
[0]=='i' and 'id' not in First
[left
]:
First
[left
].append
('id')
else:
if right
[0] not in First
[left
]:
First
[left
].append
(right
[0])
def FFirst(grammer
):
'''
扫描文法中的每一个产生式,对于产生式右边第一个符号不是非终结符的情况,
把右边非终结符First集中的元素加入到左边非终结符的First集中去
如果右边非终结符的First集中包含空串ε,则应找到该非终结符之后的一个非终结符
把这个非终结符First集中的元素加入到左边非终结符的First集中去,此次类推
'''
for i
in range(len(grammer
)):
s
= grammer
[i
]
index
= s
.find
('→')
right
= s
[index
+ 1:]
if right
[0]<'A' or right
[0]>'Z':
continue
vn1
= findFirstVN
(s
)
vn2
= findNextVN
(s
)
flag
=1
while flag
==1 and '$'!=vn2
:
for ss
in First
[vn2
]:
if ss
not in First
[vn1
]:
First
[vn1
].append
(ss
)
if 'ε' in First
[vn2
]:
flag
=1
index
=s
.find
(vn2
)
vn2
=findLastVN
(s
[index
:])
else:
flag
=0
def handleFirst(grammer
):
lookVT
(grammer
)
FFirst
(grammer
)
FFirst
(grammer
)
def scanVT(s
):
global Follow
s1
=s
index
=s1
.find
('→')
s1
=s1
[index
+1:]
for i
in range(len(s1
)):
if s1
[i
]<'A' or s1
[i
]>'Z':
if s1
[i
]!='\'':
if i
>0 and s1
[i
-1]=='\'':
vn
=s1
[i
-2:i
]
elif i
>0:
vn
=s1
[i
-1]
else:
vn
='$'
if len(s1
)==1 or s1
=='id':
vn
='$'
if vn
!='$':
if s1
[i
] =='i' or s1
[i
]=='d':
if 'id' not in Follow
[vn
]:
Follow
[vn
].append
('id')
else:
if s1
[i
] not in Follow
[vn
]:
Follow
[vn
].append
(s1
[i
])
vn1
=findFirstVN
(s1
)
vn2
=findNextVN
(s1
)
if vn1
!='$' and vn2
!='$' and vn1
+vn2
in s1
:
for si
in First
[vn2
]:
if si
not in Follow
[vn1
] and si
!='ε':
Follow
[vn1
].append
(si
)
def FFollow(grammer
):
'''
扫描文法的每一个产生式,把第一个非终结符的Follow集去除空串ε加入到最后一个非终结符的Follow集中去
如果最后一个非终结符的First集中有空串ε,
则把第一个非终结符的Follow集去除空串ε加入到倒数第二个非终结符的FOllow集中去,依次类推
'''
for i
in range(len(grammer
)):
s
= grammer
[i
]
vn1
= findFirstVN
(s
)
vn2
= findLastVN
(s
)
flag
=1
while flag
==1 and vn1
!=vn2
:
for ss
in Follow
[vn1
]:
if ss
not in Follow
[vn2
]:
Follow
[vn2
].append
(ss
)
if 'ε' in First
[vn2
]:
flag
=1
index
=s
.find
(vn2
)
vn2
=findLastVN
(s
[:index
])
else:
flag
=0
def handleFollow(grammer
):
global Follow
for i
in range(len(grammer
)):
s
=grammer
[i
]
scanVT
(s
)
FFollow
(grammer
)
def showFirst():
global First
for i
in First
.keys
():
print('First(',i
,')= ',end
="{ ")
for j
in First
[i
]:
if j
!=First
[i
][-1]:
print(j
,end
=", ")
else:
print(j
, end
="")
print("} ")
def showFollow():
for i
in Follow
.keys
():
print('Follow(',i
,')= ',end
="{ ")
for j
in Follow
[i
]:
if j
!=Follow
[i
][-1]:
print(j
,end
=", ")
else:
print(j
,end
="")
print("} ")
if __name__
== '__main__':
print('____________________________')
g
=inputGrammer
()
grammer
=cut
(g
)
initializeFirstAndFollow
(grammer
)
print('____________________________')
handleFirst
(grammer
)
showFirst
()
print('____________________________')
handleFollow
(grammer
)
showFollow
()
print('____________________________')
输入
输出
检查
和课本55、56页的结果对比,发现是一致的
转载请注明原文地址: https://www.6miu.com/read-5038962.html