def put_in():
global a,vn, vt,start
n = input("请输入上下文无关文法的行数:")
a = []
vn = []
vt = []
print("请输入上下文无关文法:")
for i in range(int(n)):
str = input()
a.append(list(str))
start = a[0][0]
for i in a:
if i[0] not in vn:
vn.append(i[0])
for j in range(3,len(i)):
if not i[j].isupper() and i[j] not in vt and i[j] != 'ε':
vt.append(i[j])
print()
print("非终结符为:")
print(vn)
print("终结符为:")
print(vt)
def first_all_not_terminal():
global f
f = []
for i in range(len(vn)):
f = f + [set()]
for num in range(len(a)):
for s in vn:
first_single_not_terminal(s)
print('非终结符的FIRST集依次为:')
print(f)
def first_single_not_terminal(x):
index_start = index(x)
for i in a:
if i[0] == x:
for j in range(3,len(i)):
if judge_terminal(i[j]):
f[index_start].add(i[j])
break
else:
index_next = index(i[j])
if 'ε' not in f[index_next]:
for e in f[index_next]:
f[index_start].add(e)
break
else:
if j == len(i) -1:
break
for e in f[index_next]:
if e != 'ε':
f[index_start].add(e)
index_next_next = index(i[j+1])
for x in f[index_next_next]:
f[index_start].add(x)
def index(x):
for n in range(len(vn)):
if x == vn[n]:
return n
def index_num(x):
for n in range(len(a)):
if x == a[n]:
return n
def judge_terminal(x):
if x in vn:
return False
else:
return True
def first_all_string():
global f1
f1 = []
for i in range(len(a)):
f1 = f1 + [set()]
for j in range(len(vn)):
for i in range(len(a)):
first_single_string(i)
print('文法的FIRST集依次为:')
print(f1)
def first_single_string(num):
string = a[num]
for i in range(3,len(string)):
if judge_terminal(string[i]):
f1[num].add(string[i])
break
else:
index_next = index(string[i])
if 'ε' not in f[index_next]:
for e in f[index_next]:
f1[num].add(e)
break
else:
for e in f[index_next]:
if e != 'ε':
f1[num].add(e)
if i == len(string) -1 :
break
index_next_next = index(string[i+1])
for e in f[index_next_next]:
f1[num].add(e)
def follow_all():
global follow
follow = []
for i in range(len(vn)):
follow = follow + [set()]
follow[i].add("#")
for num in range(len(a)):
for s in vn:
follow_single(s)
print('非终结符的follow集依次为:')
print(follow)
def follow_single(s):
index_vn = index(s)
for i in a:
index_vn_start = index(i[0])
for j in range(3,len(i)):
if s == i[j]:
if j == len(i) - 1:
for e in follow[index_vn_start]:
if e != 'ε':
follow[index_vn].add(e)
break
else:
if judge_terminal(i[j+1]):
follow[index_vn].add(i[j+1])
break
else:
index_vn_next = index(i[j+1])
if 'ε' not in f[index_vn_next]:
for e in f[index_vn_next]:
follow[index_vn].add(e)
else:
for e in f[index_vn_next]:
if e != 'ε':
follow[index_vn].add(e)
for e in follow[index_vn_start]:
if e != 'ε':
follow[index_vn].add(e)
def select_all():
global select
select = []
for i in range(len(a)):
select = select + [set()]
select_singe(i)
print('文法的select集依次为:')
print(select)
def select_singe(i):
str = a[i]
if 'ε' not in f1[i]:
for e in f1[i]:
select[i].add(e)
else:
for e in f1[i]:
if e != 'ε':
select[i].add(e)
index_start = index(str[0])
for e in follow[index_start]:
select[i].add(e)
def judge_LL1():
global temp_set,compare_set,flag
flag = True
for x in vn:
temp_set = set()
compare_set = set()
for i in a:
if x == i[0]:
num = index_num(i)
if len(temp_set) == 0:
temp_set = temp_set | select[num]
else:
compare_set = temp_set & select[num]
if len(compare_set) != 0:
print("不是LL(1)文法")
flag = False
break
if flag:
print("是LL(1)文法")
def forecast_analysis_table():
global table
table = [['' for i in range(len(vt))] for j in range(len(vn))]
for i in range(len(vn)):
for j in range(len(vt)):
for n in range(len(a)):
if vn[i] == a[n][0]:
if vt[j] in f1[n]:
table[i][j] = str_list(a[n][3:])
print("此文法的预测分析表为:")
print(table)
def str_list(x):
b = [str(j) for j in x]
str2 = ''.join(b)
return str2
def index_vt(x):
global flag1
flag1 = False
for i in range(len(vt)):
if x == vt[i]:
flag1 = True
return i
if not flag1:
return -1
def find_terminator(x,index_right):
left_last = x[-1]
if judge_terminal(left_last):
return x
else:
index_left = index(left_last)
x.pop()
for e in list(table[index_left][index_right][::-1]):
x.append(e)
find_terminator(x,index_right)
def match():
if flag:
global stack
print("请输入待匹配的字符串:")
string = list(input())
stack = ['#', start]
str_stack = str_list(stack)
str_string = str_list(string)
print(format("%-25s%5s" % (str_stack, str_string)))
while True:
left_last = stack[-1]
right_first = string[0]
index_right = index_vt(right_first)
if index_right == -1:
print("匹配错误")
break
if not judge_terminal(left_last):
find_terminator(stack,index_right)
str_stack = str_list(stack)
str_string = str_list(string)
print(format("%-25s%5s" % (str_stack,str_string)))
stack.pop()
string.pop(0)
if stack[-1] == '#' and string[0] == '#':
str_stack = str_list(stack)
str_string = str_list(string)
print(format("%-25s%5s" % (str_stack, str_string)))
print("匹配成功")
break
def run():
put_in()
print()
first_all_not_terminal()
first_all_string()
follow_all()
select_all()
print()
print("判断是否为LL(1)文法:")
judge_LL1()
print()
forecast_analysis_table()
print()
match()
run()
|