使用python完成LL(1)文法(带界面)

重新完善了一下相关设计

#用于完善编译原理实验二,加入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)

效果展示:

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是笨比wei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值