生成器"/>
LL1语法生成器
LL1语法生成器-python+界面
- 构建first集
- 构建follow集
- 构建分析表
之前因为题主时间能力有限,没有格外写一个控制页面,只能完成最基础的语法生成。效果如下:
另外,可能是代码本身问题,有时会跑不出来,多跑几次就好了。如果有大佬知道原因也欢迎留下评论!
但是题主为了内卷积极配置了pyqt5,并借鉴(照搬)了其他大佬的界面,如下图:
复制粘贴了别的大佬的界面,代码如下:
class GuiWidget(QWidget): # gui程序内容,相应按键,显示输出def __init__(self, name):super().__init__()#调用父类self.qle = QLineEdit(self)self.qle.setText('')self.qle.move(100, 20)self.qbt = QPushButton(self)self.qbt.setText('确认')self.qbt.move(250, 20)self.qtw_result = QTableWidget(20, 4, self)header = ['分析栈', '剩余输入串', '所用产生式', '动作']self.qtw_result.setHorizontalHeaderLabels(header)self.qtw_result.setEditTriggers(QTableWidget.NoEditTriggers)self.qtw_result.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)self.qtw_result.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)self.qtw_result.resize(600, 600)self.qtw_result.move(0, 50)self.qbt.clicked.connect(self.onInputChanged)self.setWindowTitle(name)self.show()def onInputChanged(self):text = self.qle.text()if text == '':returngetGram()getVT()getVN()initail()getFirst()getFollow()creat_Select()analyse(text)row = -1for num in massage:row += 1col = -1for item in num:col += 1self.qtw_result.setItem(row, col, QTableWidgetItem(item))
构建first集
# 获取first集
def getFirst():while (1):test = FIRST.copy()for i in sentences:temp0 = i.split("->")[0]temp1 = i.split("->")[1]if (temp0 in VT) or (temp1[0] in VT) or (temp1[0] == 'ε'):if (temp0 in VT):FIRST[temp0] = FIRST.get(temp0)else:FIRST[temp0] = FIRST.get(temp0) + temp1[0]else: # 首字符为非终结符flag = 1for j in temp1:FIRST[temp0] = FIRST.get(temp0) + str(FIRST[j]).replace('ε', '')if 'ε' not in FIRST[j]: # 若不含空集则breakflag = 0breakif flag == 1:FIRST[temp0] = FIRST.get(temp0) + 'ε'for i, j in FIRST.items():temp = ""for word in list(set(j)):temp += wordFIRST[i] = tempif test == FIRST:breakprint(FIRST)
构建follow集
def getFollow():while (1):test = FOLLOW.copy()for i in sentences:temp0 = i.split("->")[0]temp1 = i.split("->")[1]for p in temp1:if p in VT or p == 'ε':continuelocal = temp1.find(p)flag0 = 0 # 判断是否为终结符flag1 = 0for j in temp1[local + 1:]:FOLLOW[p] = FOLLOW.get(p) + str(FIRST[j]).replace('ε', '')if 'ε' not in FIRST[j] or j in VT:if j in VT:flag0 = 1else:flag1 = 1breakif (flag1 == 0) and (flag0 == 0):FOLLOW[p] = FOLLOW.get(p) + FOLLOW.get(temp0)for i, j in FOLLOW.items():temp = ""for word in list(set(j)):temp += wordFOLLOW[i] = tempif test == FOLLOW:breakprint(FOLLOW)
构建分析表
# 像二维字典插入数据
def addDict(dict, a, b, val):if a in dict:dict[a].update({b: val})else:dict.update({a: {b: val}})# 构建预测分析表
def creat_Select():print(sentences)for sentence in sentences:a=sentence.split("->")[0]str=sentence.split("->")[1]temp=str[0]for i in VT:if i in FIRST[temp]:addDict(SELECT, a, i, str)if 'ε' in FIRST[temp]:for j in FOLLOW[a]:addDict(SELECT, a, j, 'ε')print(SELECT)
以下为全部代码
import sys
from inspect import stack
from PyQt5.QtWidgets import (QWidget, QLineEdit, QApplication, QTableWidget, QTableWidgetItem, QPushButton,QHeaderView)
VT = [] # 终结符
VN = [] #
sentences = [] # 语法
file = "text.txt"
Start = 'E'
FIRST = {} # first集
FOLLOW = {} # follow 集
SELECT = {"": {"": ""}} # 分析表
STACK = ["#"] # 输入栈
STACK_INPUT = [] # 剩余输入串
massage = []def getGram():with open(file, encoding='UTF-8') as f:text = f.read().splitlines()print(text)for sentence in text:Start = sentence[0]if len(sentence.split('|')) < 2:sentences.append(sentence)else:part_head = sentence.split('|')[0]sentences.append(part_head)for i in sentence.split('|')[1:]:sentences.append(part_head[0] + "->" + i)print(sentences)# 获取VN
def getVN():for i in sentences:if i[0] not in VN:VN.append(i[0])VN.sort()print(VN)# 获取VT
def getVT():for i in sentences:for j in i:if not j.isupper():if not j in VT:VT.append(j)VT.remove('ε')VT.sort()print(VT)def initail():for str in sentences:part_begin = str.split("->")[0]part_end = str.split("->")[1]FIRST[part_begin] = ""FOLLOW[part_begin] = ""for i in VT:FIRST[i] = iFOLLOW[i] = iFIRST['ε'] = 'ε'FOLLOW['ε'] = 'ε'FOLLOW[Start] = '#'# 获取first集
def getFirst():while (1):test = FIRST.copy()for i in sentences:temp0 = i.split("->")[0]temp1 = i.split("->")[1]if (temp0 in VT) or (temp1[0] in VT) or (temp1[0] == 'ε'):if (temp0 in VT):FIRST[temp0] = FIRST.get(temp0)else:FIRST[temp0] = FIRST.get(temp0) + temp1[0]else: # 首字符为非终结符flag = 1for j in temp1:FIRST[temp0] = FIRST.get(temp0) + str(FIRST[j]).replace('ε', '')if 'ε' not in FIRST[j]: # 若不含空集则breakflag = 0breakif flag == 1:FIRST[temp0] = FIRST.get(temp0) + 'ε'for i, j in FIRST.items():temp = ""for word in list(set(j)):temp += wordFIRST[i] = tempif test == FIRST:breakprint(FIRST)# 获取follow集
def getFollow():while (1):test = FOLLOW.copy()for i in sentences:temp0 = i.split("->")[0]temp1 = i.split("->")[1]for p in temp1:if p in VT or p == 'ε':continuelocal = temp1.find(p)flag0 = 0 # 判断是否为终结符flag1 = 0for j in temp1[local + 1:]:FOLLOW[p] = FOLLOW.get(p) + str(FIRST[j]).replace('ε', '')if 'ε' not in FIRST[j] or j in VT:if j in VT:flag0 = 1else:flag1 = 1breakif (flag1 == 0) and (flag0 == 0):FOLLOW[p] = FOLLOW.get(p) + FOLLOW.get(temp0)for i, j in FOLLOW.items():temp = ""for word in list(set(j)):temp += wordFOLLOW[i] = tempif test == FOLLOW:breakprint(FOLLOW)# 像二维字典插入数据
def addDict(dict, a, b, val):if a in dict:dict[a].update({b: val})else:dict.update({a: {b: val}})# 构建预测分析表
def creat_Select():print(sentences)for sentence in sentences:a=sentence.split("->")[0]str=sentence.split("->")[1]temp=str[0]for i in VT:if i in FIRST[temp]:addDict(SELECT, a, i, str)if 'ε' in FIRST[temp]:for j in FOLLOW[a]:addDict(SELECT, a, j, 'ε')print(SELECT)def record(left1, key='', string=''):msg = ""for s in STACK:msg += sif key == '':b = ''c = 'GETNEXT'else:b = '{}->{}'.format(key, string)c = 'POP,PUSH({})'.format(string)massage.append([msg,left1, b, c])def analyse(text):#STACK_INPUT = input(print("Please input: "))+"#"STACK_INPUT=text+"#"STACK.append(Start)index = 0a = STACK_INPUT[index]x = STACK.pop()while not a == x == '#':if x in VN:fm = SELECT[x][a]for c in reversed(fm):if c != 'ε':STACK.append(c)record(STACK_INPUT[index:], x, fm)else:if a in VT:if x != a: # 出错STACK.append(x)print("111")# error(STACK[index:], a, index + 1)breakindex += 1a = STACK_INPUT[index]record(STACK_INPUT[index:])x = STACK.pop()print("步骤 分析栈 剩余输入串 所用产生式 动作")count=1for i in massage:print('{:<5}'.format(count),'{:<8}'.format(i[0]),'{:>7}'.format(i[1]),'{:^13}'.format(i[2]),'{:<13}'.format(i[3]))count+=1'''
class GuiWidget(QWidget): # gui程序内容,相应按键,显示输出def __init__(self, name):super().__init__()#调用父类self.qle = QLineEdit(self)self.qle.setText('')self.qle.move(100, 20)self.qbt = QPushButton(self)self.qbt.setText('确认')self.qbt.move(250, 20)self.qtw_result = QTableWidget(20, 4, self)header = ['分析栈', '剩余输入串', '所用产生式', '动作']self.qtw_result.setHorizontalHeaderLabels(header)self.qtw_result.setEditTriggers(QTableWidget.NoEditTriggers)self.qtw_result.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)self.qtw_result.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)self.qtw_result.resize(600, 600)self.qtw_result.move(0, 50)self.qbt.clicked.connect(self.onInputChanged)self.setWindowTitle(name)self.show()def onInputChanged(self):text = self.qle.text()if text == '':returngetGram()getVT()getVN()initail()getFirst()getFollow()creat_Select()analyse(text)row = -1for num in massage:row += 1col = -1for item in num:col += 1self.qtw_result.setItem(row, col, QTableWidgetItem(item))def main():name = 'LL1'app = QApplication(sys.argv)ex = GuiWidget(name)sys.exit(app.exec_())#sys.exit(0)if __name__ == '__main__':sys.exit(main())
'''if __name__ == '__main__':getGram()getVT()getVN()initail()getFirst()getFollow()creat_Select()analyse()
更多推荐
LL1语法生成器
发布评论