python(1) 用户任意输入文法,检查文法是否有左递归和回溯,输出结果; (2) 若有,则消除左递归和回溯。测试文法G[S]如下: S→(T)|a+S|a T→T,S|S (3)显示改造后的文法,最终结果需以GUI界面展示
时间: 2023-12-14 20:36:54 浏览: 126
python实现文法左递归的消除方法
下面是 Python 代码,可以实现输入文法并检查是否有左递归和回溯,并对其进行消除:
```python
import tkinter as tk
def is_left_recursive(grammar, symbol, visited):
if symbol in visited:
return True
visited.add(symbol)
for production in grammar[symbol]:
if production[0] == symbol:
return True
elif production[0] in grammar and is_left_recursive(grammar, production[0], visited):
return True
visited.remove(symbol)
return False
def has_left_recursion(grammar):
for symbol in grammar:
if is_left_recursive(grammar, symbol, set()):
return True
return False
def has_backtracking(grammar, visited):
for symbol in grammar:
if symbol in visited:
return True
visited.add(symbol)
for production in grammar[symbol]:
if len(production) > 1:
for i in range(1, len(production)):
if production[i] in grammar and has_backtracking(grammar, {production[i]} | visited):
return True
visited.remove(symbol)
return False
def eliminate_left_recursion(grammar):
new_grammar = {}
for A in grammar:
new_productions = []
old_productions = grammar[A]
alpha_productions = []
beta_productions = []
for production in old_productions:
if production[0] == A:
alpha_productions.append(production[1:])
else:
beta_productions.append(production)
if len(alpha_productions) > 0:
new_A = A + "'"
new_productions.extend([beta + new_A for beta in beta_productions])
new_productions.extend([beta + new_A for beta in alpha_productions if len(beta) > 0])
new_productions.append("")
new_productions.extend([alpha + new_A for alpha in alpha_productions if len(alpha) > 0])
new_grammar[new_A] = [alpha + new_A for alpha in alpha_productions if len(alpha) > 0] + [""]
new_grammar[A] = new_productions
else:
new_grammar[A] = old_productions
return new_grammar
def eliminate_backtracking(grammar, symbol, visited):
new_productions = []
for production in grammar[symbol]:
if len(production) == 1 or not(production[0] in grammar):
new_productions.append(production)
else:
new_symbol = production[0]
if new_symbol in visited:
new_symbol = new_symbol + "'"
visited.add(new_symbol)
grammar[new_symbol] = []
new_production = eliminate_backtracking(grammar, new_symbol, visited) + production[1:]
new_productions.append(new_production)
if new_symbol.endswith("'"):
grammar[new_symbol].append(new_production + new_symbol[:-1])
return new_productions
def eliminate_all_backtracking(grammar):
for symbol in grammar:
grammar[symbol] = eliminate_backtracking(grammar, symbol, {symbol})
return grammar
def parse_grammar(text):
grammar = {}
for line in text.split("\n"):
line = line.strip()
if len(line) == 0:
continue
parts = line.split("->")
A = parts[0].strip()
productions = [p.strip() for p in parts[1].split("|")]
grammar[A] = productions
return grammar
def format_grammar(grammar):
text = ""
for A in grammar:
text += A + " -> " + " | ".join(grammar[A]) + "\n"
return text
def check_grammar(text):
grammar = parse_grammar(text)
has_left = has_left_recursion(grammar)
has_back = has_backtracking(grammar, set())
if has_left:
grammar = eliminate_left_recursion(grammar)
if has_back:
grammar = eliminate_all_backtracking(grammar)
return format_grammar(grammar)
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.grid()
self.create_widgets()
def create_widgets(self):
self.input_label = tk.Label(self, text="Enter grammar:")
self.input_label.grid(row=0, column=0, padx=5, pady=5, sticky=tk.W)
self.input_text = tk.Text(self, height=10, width=50)
self.input_text.grid(row=1, column=0, padx=5, pady=5)
self.output_label = tk.Label(self, text="Transformed grammar:")
self.output_label.grid(row=2, column=0, padx=5, pady=5, sticky=tk.W)
self.output_text = tk.Text(self, height=10, width=50)
self.output_text.grid(row=3, column=0, padx=5, pady=5)
self.check_button = tk.Button(self, text="Check grammar", command=self.check_grammar)
self.check_button.grid(row=4, column=0, padx=5, pady=5)
self.quit_button = tk.Button(self, text="Quit", command=self.master.destroy)
self.quit_button.grid(row=5, column=0, padx=5, pady=5)
def check_grammar(self):
input_text = self.input_text.get("1.0", tk.END).strip()
output_text = check_grammar(input_text)
self.output_text.delete("1.0", tk.END)
self.output_text.insert("1.0", output_text)
root = tk.Tk()
app = Application(master=root)
app.mainloop()
```
这段代码使用了 Python 的 tkinter 库来创建一个基本的 GUI 界面,用户可以在其中输入文法,并点击按钮来检查文法是否有左递归和回溯,并对其进行消除。代码中的 `check_grammar` 函数接受一个字符串作为输入,解析成文法后调用 `has_left_recursion` 和 `has_backtracking` 函数来检查文法是否有左递归和回溯。如果有,则分别调用 `eliminate_left_recursion` 和 `eliminate_all_backtracking` 函数来消除左递归和回溯。最后,使用 `format_grammar` 函数将消除后的文法格式化成字符串,并返回给调用者。
阅读全文