LL1语法生成器

编程入门 行业动态 更新时间:2024-10-23 18:33:22

LL1语法<a href=https://www.elefans.com/category/jswz/34/1764786.html style=生成器"/>

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语法生成器

本文发布于:2024-03-10 18:02:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1728657.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:生成器   语法

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!