我正在尝试在python中实现一个简单的表达式求值程序,但我陷入了解析器方法.Below是我的代码片段。
class Number:
def __init__(self,value):
self.value=value
def execute(self):
return self.value
class Plus:
def __init__(self,left,right):
self.left=left
self.right=right
def execute(self):
return self.left+self.right
class Minus:
def __init__(self,left,right):
self.left=left
self.right=right
def execute(self):
return self.left-self.right
class Multiply:
def __init__(self,left,right):
self.left=left
self.right=right
def execute(self):
return self.left*self.right
import re
def parser(input):
stack=[]
token_pat = re.compile("\s*(?:(\d+)|(.))")
for number, operator in token_pat.findall(input):
if number:
stack.append(Number(int(number)))
else:
first,second=stack.pop(),stack.pop()
if operator=="+":
stack.append(Plus(first,second))
elif operator=="-":
stack.append(Minus(first,second))
elif operator=="*":
stack.append(Multiply(first,second))
else:
raise SyntaxError("unknown operator")
print stack[0].execute()
if __name__=="__main__":
parser('1 2 +')
当我运行上面的代码时,我收到了以下错误。任何人都可以查看我的代码。
Traceback (most recent call last):
File "Interpreter.py", line 52, in <module>
parser('1 2 +')
File "Interpreter.py", line 48, in parser
print stack[0].execute()
File "Interpreter.py", line 12, in execute
return self.left+self.right
TypeError: unsupported operand type(s) for +: 'instance' and 'in
答案 0 :(得分:5)
错误消息令人困惑,因为您使用的是classic classes。使用新式类(即继承自object
),您会得到更合理的结果:
TypeError: unsupported operand type(s) for +: 'Number' and 'Number'
使用int
代替Number对象,或通过实施__add__
and friends实现添加逻辑,或在Plus.execute
中添加评估逻辑。
另请注意,您正在重新实现Python的内置插件。此外,使用execute
方法几乎是一种反模式。更短的实施将是
import functools,operator,re
def parser(inp):
stack=[]
token_pat = re.compile("\s*(?:(\d+)|(.))")
for number, op in token_pat.findall(inp):
if number:
stack.append(functools.partial(lambda i:i, int(number)))
else:
first,second=stack.pop(),stack.pop()
try:
op = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul
}[op]
except KeyError:
raise SyntaxError("unknown operator")
stack.append(functools.partial(lambda op,first,second:
op(first(), second()), op, first, second))
print(stack[0]())
if __name__=="__main__":
parser('1 2 + 3 *')
答案 1 :(得分:1)
由于您对自己进行基本调试不感兴趣:
sucmac: $ python out.py
> /Users/xxxx/out.py(13)execute()
-> return self.left+self.right
(Pdb) self.left
<__main__.Number instance at 0x10043f3f8>
(Pdb) self.right
<__main__.Number instance at 0x10042f248>
(Pdb) right
*** NameError: name 'right' is not defined
(Pdb) self.right.__dict__
{'value': 1}
你显然想要
return self.right.value + self.left.value