我有一个错误,声明:
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
File "derpAgain.py", line 14, in parse
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
File "derpAgain.py", line 13, in parse
if tokens[0] == "+":
RuntimeError: maximum recursion depth exceeded in comparison
我不知道为什么会出现这个错误。我仔细检查,看到它没有错。
from derp_node import *
def parse(tokens, i = 0):
"""parse: tuple(String) * int -> (Node, int)
From an infix stream of tokens, and the current index into the
token stream, construct and return the tree, as a collection of Nodes,
that represent the expression.
NOTE: YOU ARE NOT ALLOWED TO MUTATE 'tokens' (e.g. pop())!!! YOU
MUST USE 'i' TO GET THE CURRENT TOKEN OUT OF 'tokens'
"""
#t = tokens.pop(0)
if tokens[0] == "+":
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif tokens[0] == "-":
return mkSubstractNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif tokens[0] == "*":
return mkMultiplyNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif tokens[0] == "//":
return mkDivideNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif (tokens.pop(0).isdigit()):
return mkLiteralNode(int(tokens.pop(0)))
else:
return mkVariableNode(tokens.pop(0))
def infix(node):
"""infix: Node -> String | TypeError
Perform an inorder traversal of the node and return a string that
represents the infix expression."""
if isinstance(node, MultiplyNode):
return "(" + infix(node.left) + " * " + infix(node.right) + ")"
elif isinstance(node, DivideNode):
return "(" + infix(node.left) + " // " + infix(node.right) + ")"
elif isinstance(node, AddNode):
return "(" + infix(node.left) + " + " + infix(node.right) + ")"
elif isinstance(node, SubtractNode):
return "(" + infix(node.left) + " - " + infix(node.right) + ")"
elif isinstance(node, LiteralNode):
return str(node.val)
else:
return node.name
def evaluate(node, symTbl):
"""evaluate: Node * dict(key=String, value=int) -> int | TypeError
Given the expression at the node, return the integer result of evaluating
the node.
Precondition: all variable names must exist in symTbl"""
if isinstance(node, MultiplyNode):
return evaluate(node.left, symTbl) * evaluate(node.right, symTbl)
elif isinstance(node, DivideNode):
return evaluate(node.left, symTbl) // evaluate(node.right, symTbl)
elif isinstance(node, AddNode):
return evaluate(node.left, symTbl) + evaluate(node.right, symTbl)
elif isinstance(node, SubtractNode):
return evaluate(node.left, symTbl) - evaluate(node.right, symTbl)
elif isinstance(node, VariableNode):
for var in symTbl:
if var == node.name:
return symTbl[var]
else:
return node.val
def main():
"""main: None -> None
The main program prompts for the symbol table file, and a prefix
expression. It produces the infix expression, and the integer result of
evaluating the expression"""
print("Hello Herp, welcome to Derp v1.0 :)")
inFile = input("Herp, enter symbol table file: ")
# STUDENT: CONSTRUCT AND DISPLAY THE SYMBOL TABLE HERE
fileOpen = open(inFile)
symTbl = {}
for line in fileOpen:
lineStrip = line.split()
symTbl[lineStrip[0]] = int(lineStrip[1])
for var in sorted(symTbl):
print("Name: " + var + " => " + str(symTbl[var]))
print("Herp, enter prefix expressions, e.g.: + 10 20 (RETURN to quit)...")
# input loop prompts for prefix expressions and produces infix version
# along with its evaluation
while True:
prefixExp = input("derp> ")
if prefixExp == "":
break
prefix = prefixExp.split()
root = parse(prefix)
print("Derping the infix expression: " + infix(root))
print("Derping the evaluation: " + str(evaluate(root, symTbl)))
print("Goodbye Herp :(")
if __name__ == "__main__":
main()
当我打开程序时。它将显示此输出:
Hello Herp, welcome to Derp v1.0 :)
Herp, enter symbol table file: vars.txt
Name: x => 10
Name: y => 20
Name: z => 30
Herp, enter prefix expressions, e.g.: + 10 20 (RETURN to quit)...
derp> - 10 20
Derping the infix expression: 10
Derping the evaluation: None
derp> + 10 * x y
Then the error has started...
Vars.txt:
x 10
y 20
z 30
旁注:如果你们好奇derp_node.py中的内容,我不会在这里发布,但是,我把它发布在pastebin上,所以这个页面看起来并不大。 http://pastebin.com/MXuc8Shc任何帮助都会很棒!谢谢。希望我提供了足够的信息,所以你们有一个想法,我在做什么。
答案 0 :(得分:1)
您继续将相同的引用传递给令牌。
如果你不增加你所指的那个字符,那么tokens [0]总是'+',这意味着对parse()的递归调用将永远继续。
另外,为什么你有4个if / elif分支都检查/调用完全相同的东西?
此外,.pop()方法实际上更改了基础列表,因此if tokens.pop()。isdigit()实际上是删除标记中的最后一个元素。这可能是你想要在第一个中做的。
答案 1 :(得分:0)
你仍然有一些关于弹出的调用,并且在条件中调用pop特别糟糕,因为当你甚至不确定条件是否适用时你会改变列表:
elif (tokens.pop(0).isdigit()):
return mkLiteralNode(int(tokens.pop(0)))
应该是:
elif (tokens[0].isdigit()):
return mkLiteralNode(int(tokens.pop(0)))
答案 2 :(得分:0)
让我们来看看您致电parse(tokens, i)
和tokens[0] == '+'
时会发生什么。 parse
的正文将尝试执行:
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
执行此声明需要评估parse(tokens, i+1)
,并且在递归调用中tokens[0]
仍然是'+'
,您将再次呼叫parse
,另一个呼叫, 这将永远不会结束。我认为您要做的是测试tokens[i] == '+'
,而不是tokens[0]
,或者可能将parse(tokens, i+1)
更改为parse(tokens[1:], i+1)
(为什么当您'{0}时为i
不使用它?)
答案 3 :(得分:0)
如果你得到一个标记'+',它会启动一个无限循环:
if tokens[0] == "+":
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif tokens[0] == "+":
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif tokens[0] == "+":
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif tokens[0] == "+":
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif (tokens.pop(0).isdigit()):
return mkLiteralNode(int(tokens.pop(0)))
else:
return mkVariableNode(tokens.pop(0))
你只检查'+'标记,只有当标记不是'+'时才弹出。我希望有帮助
我会用:
aux = tokens.pop(0)
if aux == "+":
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif aux == "-":
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif aux == "*":
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif aux == "/":
return mkAddNode(parse(tokens, i + 1), parse(tokens, i + 1))
elif (aux.isdigit()):
return mkLiteralNode(int(aux))
else:
return mkVariableNode(aux)