我正在编写一个程序,将中缀转换为后缀表示法,并将其编译为不确定的有限自动机。我收到一条错误消息,提示我正在尝试从一个空堆栈中弹出,但是我不知道为什么未正确填充它。抱歉,如果这是一个愚蠢的问题,我是Python的新手,但任何帮助将不胜感激。谢谢!
class state:
label, edge1, edge2 = None, None, None
class NFA:
initial, accept = None, None
def __init__(self, initial, accept):
self.initial, self.accept = initial, accept
# convert infix notation to postfix
def shunt(infix):
operators = {'*': 30, '+': 30, '?': 30, '.': 20, '|': 10}
postfix, stack = ' ', ' '
for c in infix:
# open brackets are pushed straight to stack
if c == '(':
stack += c
# discard closing bracket, print inside brackets
elif c == ')':
while stack[-1] != '(':
postfix += stack[-1]
stack = stack[:-1]
stack = stack[:-1]
# operators get pushed to stack
elif c in operators:
# pushes operator with higher precedence on the stack
while stack and operators.get(c, 0) <= operators.get(stack[-1], 0):
postfix += stack[-1]
stack = stack[:-1]
stack += c
else:
postfix += c
# copied from above to run if stack is not empty
while stack:
postfix += stack[-1]
stack = stack[:-1]
return postfix
# regular expression compiler
def compile(postfix):
nfaStack = []
for c in postfix:
# join the initial and accept states together to create a loop for your characters
if c == '*':
nfa = nfaStack.pop()
initial, accept = state(), state()
initial.edge1, nfa.accept.edge1 = nfa.initial, nfa.initial
initial.edge2, nfa.accept.edge2 = accept, accept
nfaStack.append(NFA(initial, accept))
# merge the two automata by linking 1's accept to 2's initial states
elif c == '.':
nfa2, nfa1 = nfaStack.pop(), nfaStack.pop()
nfa1.accept.edge1 = nfa2.initial
nfaStack.append(NFA(nfa1.initial, nfa2.accept))
# create new initial and accept states and use them to link nfa1 and nfa2
elif c == '|':
nfa2, nfa1 = nfaStack.pop(), nfaStack.pop()
initial, accept = state(), state()
initial.edge1, initial.edge2 = nfa1.initial, nfa2.initial
# both old accept states now point to our new accept state
nfa1.accept.edge1, nfa2.accept.edge1 = accept, accept
nfaStack.append(NFA(initial, accept))
# creates new states and edges; labels each edge with what the current non-special character is
else:
initial, accept = state(), state()
initial.label = c
initial.edge1 = accept
# create instance of class nfa()
nfaStack.append(NFA(initial, accept))
# should only ever have one nfa in the stack
return nfaStack.pop()
print(compile("a|b*"))
compile()应该返回新创建的nfa存储位置的内存地址,但它告诉我仅弹出一个字符后堆栈为空。