重新完善了一下相关设计
#用于完善编译原理实验二,加入first and follow集合
#main.py
from tkinter import *
from myfunction import *
class MY_GUI():
def __init__(self,init_window_name):
self.init_window_name = init_window_name
def set_init_window(self):
self.init_window_name.title("LL(1)文法")
self.init_window_name.geometry('1200x570+10+10')
self.input_label = Label(self.init_window_name, text="请输入句子串")
self.input_label.grid(row=0, column=0)
self.output_label = Label(self.init_window_name, text="输出结果")
self.output_label.grid(row=3, column=0)
self.init_data_Text = Text(self.init_window_name, width=35, height=1)
self.init_data_Text.grid(row=1, column=0, rowspan=1, columnspan=1)
self.result_data_Text = Text(self.init_window_name, width=150, height=35)
self.result_data_Text.grid(row=30, column=0, rowspan=1, columnspan=1)
self.button = Button(self.init_window_name, text="LL(1)", bg="lightblue", width=10,command=self.begin_with)
self.button.grid(row=1, column=10)
def use_function(self,src):
self.result_data_Text.insert('end', src)
self.result_data_Text.insert(INSERT, '\n')
def begin_with(self): # 进行输入,lol终于写完了
read_text()
pro_deal()
get_first()
get_follow()
get_analysis()
# print(FIRST) #first集合
# print(FOLLOW) #follow集合
# print(grammer) #语法
# print(vt) # 终结符号
# print(vn) # 非终结符号
# print(analysis) #转换表
sentence = src = self.init_data_Text.get(1.0, END).strip().replace("\n", "")
input_stack = Stack('#') # 存储输入串的栈
ana_stack = Stack('#') # 建立分析栈
product_stack = Stack() # 建立存储所用产生式的栈
ana_stack.push(vn[0])
act_stack = Stack() # 建立动作栈
for i in list(reversed(sentence)):
input_stack.push(i)
act_stack.push('初始化')
out_put = "{0:<10}\t{1:<25}\t{2:<30}\t{3:<40}\t{4:<20}"
self.use_function(out_put.format("步骤", "分析栈", "剩余输入串", "所用产生式", "行为", chr(12288)))
step = 0
try:
while (not ana_stack.isempty()):
self.use_function(
out_put.format(step, str(ana_stack.show()), str(input_stack.show()), str(product_stack.show()),
str(act_stack.show()), chr(12288)))
step = step + 1
product_stack.clear()
act_stack.clear()
if ana_stack.show_last_one() == input_stack.show_last_one():
ana_stack.pop()
input_stack.pop()
act_stack.push('POP')
elif ana_stack.show_last_one() == 'e':
ana_stack.pop()
act_stack.push('POP')
elif analysis[ana_stack.show_last_one()][input_stack.show_last_one()]:
med = ana_stack.pop()
act_stack.push('POP')
for i in list(reversed(list(analysis[med][input_stack.show_last_one()])[0])):
ana_stack.push(i)
product_stack.push("{0}->{1}".format(med, str(list(analysis[med][input_stack.show_last_one()])[0])))
act_stack.push('PUSH({0})'.format(str(list(analysis[med][input_stack.show_last_one()])[0])))
else:
self.use_function('ERROR')
break
except KeyError:
self.use_function('Error,你输入错误句子')
def gui_start():
init_window = Tk()
xu = MY_GUI(init_window)
xu.set_init_window()
init_window.mainloop()
if __name__=="__main__":
gui_start()
#用于完善编译原理实验二,加入first and follow集合
#myfunction.py
import string,copy,myfunction
from tkinter import *
class Stack:#构建栈
def __init__(self,initial=None):
self.st=[]
if initial != None:
self.st.append(initial)
def isempty(self):
return len(self.st)==0
def push(self,info):
self.st.append(info)
def pop(self):
return self.st.pop()
def size(self):
return len(self.st)
def show(self):
if len(self.st)==0 :
return ''
return self.st
def show_last_one(self):
if len(self.st)!=0:
return self.st[-1]
def clear(self):
self.st.clear()
grammer={}#使用字典来存放语法
vn=[]#非终结符号
vt=[]#终结符号
FIRST={}#使用字典来存储first集合
FOLLOW={}#使用字典来存储follow集合
analysis={}#使用字典中字典来存储转移表
def read_text():#从文档中读
r=open("text.txt",'r')
line=r.readline()
while(line):
if '\n' in line:
line=line[:-1]
med=line.index('->')
if line[0] not in grammer.keys():
grammer[line[0]]=[line[med+2:]]
else:
grammer[line[0]].append(line[med+2:])
med = [i.split('|') for i in grammer[line[0]]]
grammer[line[0]] = [i for item in med for i in item]
line=r.readline()
r.close()
def pro_deal():#预处理,构建vt和vn
for i in grammer.keys():
vn.append(i)
for values in grammer.values():
for value in values:
for i in value:
if i not in string.ascii_uppercase:
if i not in vt:
vt.append(i)
def filter_e(result,item):#对于1<=j<=i-1,e in first(xj)中,则此函数返回i的数值
for index,word in enumerate(item):
if 'e' not in result[word]:
return index
def get_first():
for x in vt+vn:
FIRST[x]=set()
if x in vt:#规则一
FIRST[x].update(x)
sum=0
med=1
while(sum!=med):
med=sum
sum=0
for x in vt + vn:
if x in vn: # 当为非终结符号的时候
for item in grammer[x]:
if item == 'e': # 规则2.2
FIRST[x].update('e')
elif item[0] in vt + vn: # 规则2.1
FIRST[x].update(FIRST[item[0]])
if filter_e(FIRST, item):
if filter_e(FIRST, item) == len(item):
FIRST.update('e')
else:
FIRST[x].update(FIRST[filter_e(FIRST, item) + 1])
for i in vt+vn:
sum=sum+len(FIRST[i])
def get_product(element):#通过单一元素,反向找到其的产生式
result={}
for i in vn:#初始化
result[i]=set()
for i in vn:#进行筛选
for item in grammer[i]:
if len(item)>=2 and item[1]==element:
result[i].add(item)
for i in vn:#删除空集合的键值对
if len(result[i])==0:
del result[i]
return result
def get_follow():
for x in vn:
FOLLOW[x] = set()
sum = 0
med = 1
while (sum != med):
med=sum
sum=0
for x in vn:
if x ==vn[0]:
FOLLOW[x].update('#')
tem=get_product(x)#存储函数返回来的字典
for key in tem.keys():
for value in tem[key]:
if len(value)==3:
FOLLOW[x].update(FIRST[value[2]]-{'e'})
if 'e' in FIRST[value[2]]:
FOLLOW[x].update(FOLLOW[key])
if len(value)==2:
FOLLOW[x].update(FOLLOW[key])
for i in vn:
sum=sum+len(FOLLOW[i])
def get_analysis():#获得分析表
vt_new=copy.deepcopy(vt)
vt_new.append('#')#vt_new来表示表格列名
vt_new.remove('e')
for i in vn:#vn为表格行名
analysis[i]={}#典中典
for j in vt_new:
analysis[i][j]=set()
for key in grammer.keys():#对语法的遍历
for value in grammer[key]:
for i_vt in analysis[key].keys():
if i_vt in FIRST[value[0]]:
analysis[key][i_vt].add(value)
if 'e' in FIRST[value[0]]:
for i_vt in analysis[key].keys():
if i_vt in FOLLOW[key]:
analysis[key][i_vt].add(value)
for key in list(analysis.keys()):
for value in list(analysis[key].keys()):
if len(analysis[key][value])==0:
analysis[key].pop(value)
效果展示: