在大多数可以找到优先级的示例中,使用分组(oneOf)文字来设置相同的级别。通过这种方法,我将不得不查找它中的哪一个(或更多),然后继续评估。我想做的是拆分操作员直接知道它是哪一个并进行评估。
这是我想要实现的,但优先级现在是错误的
arith_prec = [
(subtract_op, 2, opAssoc.LEFT, ast.Substraction),
(add_op, 2, opAssoc.LEFT, ast.Addition),
(divide_op, 2, opAssoc.LEFT, ast.Division),
(multiplication_op, 2, opAssoc.LEFT, ast.Multiplication),
]
这就是我以前所拥有的,但必须匹配它中的哪一个(或更多)
plusop = oneOf(['+', '-'])
multop = oneOf(['*', '/'])
arith_prec = [
(plusop, 2, opAssoc.LEFT,),
(multop, 2, opAssoc.LEFT,),
]
有没有办法做到这一点?我已经使用arith_prec中的oneOf和Or进行了测试,但没有用。
答案 0 :(得分:1)
您必须匹配解析操作/类中的运算符。请注意,您可能会获得多个操作,而不仅仅是具有两个操作数的操作。例如,解析“1 - 3 + 2”会给你[1, '-', 3, '+', 2]
,所以你真的不能创建一个加法或减法类。
也许将它们组合到AddSub和MultDiv这样的类中,它们将通过解析的值从左到右迭代以评估值:
class BinOp:
operator_map = {}
def __init__(self, tokens):
self.tokens = tokens
def eval(self):
seq = self.tokens
ret = seq[0]
for operator, operand in zip(seq[1::2], seq[2::2]):
ret = self.operator_map[operator](ret, operand)
return ret
class AddSub(BinOp):
operator_map = {'+': operator.add, '-': operator.sub}
class MultDiv(BinOp):
operator_map = {'*': operator.mul, '/': operator.truediv}
plusop = oneOf(AddSub.operator_map.keys())
multop = oneOf(MultDiv.operator_map.keys())
arith_prec = [
(multop, 2, opAssoc.LEFT, MultDiv),
(plusop, 2, opAssoc.LEFT, AddSub),
]
或者扩大“添加”的概念,包括“+”和“ - ”操作。 (正如在工程学院,我们不得不概括“加速”的概念,包括速度的任何变化,无论是向上还是向下。)
无论如何,如果您使用infixNotation
方法,则必须让每个级别的优先级都包含该级别的所有运算符。