pyparsing优先级拆分
pyparsing precedence splitting
在我能找到的大多数示例中,优先级使用分组的 (oneOf) 文字来设置相同的级别。使用这种方法,我将不得不查找它是 2 个(或更多)中的哪一个,然后继续进行评估。我想做的是拆分运算符以直接知道它是哪一个并对其进行评估。
这就是我想要实现的,但是现在的优先级是错误的
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 进行了测试,但没有用。
您必须匹配您的解析中的运算符 action/class。请注意,您可能会获得多个操作,而不仅仅是一个具有两个操作数的操作。例如,解析“1 - 3 + 2”会给你 [1, '-', 3, '+', 2]
,所以你真的不能让它创建一个加法或减法 class。
也许将它们组合成 class 类,如 AddSub 和 MultDiv,它们将迭代 left-to-right 通过解析的值来计算值:
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),
]
或者扩展您的 "addition" 概念以包括“+”和“-”操作。 (就像在工程学院一样,我们必须概括 "acceleration" 的概念以包括速度的任何变化,无论是向上还是向下。)
无论如何,如果您使用 infixNotation
方法,则必须让每个优先级别都包含该级别的所有运算符。
在我能找到的大多数示例中,优先级使用分组的 (oneOf) 文字来设置相同的级别。使用这种方法,我将不得不查找它是 2 个(或更多)中的哪一个,然后继续进行评估。我想做的是拆分运算符以直接知道它是哪一个并对其进行评估。
这就是我想要实现的,但是现在的优先级是错误的
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 进行了测试,但没有用。
您必须匹配您的解析中的运算符 action/class。请注意,您可能会获得多个操作,而不仅仅是一个具有两个操作数的操作。例如,解析“1 - 3 + 2”会给你 [1, '-', 3, '+', 2]
,所以你真的不能让它创建一个加法或减法 class。
也许将它们组合成 class 类,如 AddSub 和 MultDiv,它们将迭代 left-to-right 通过解析的值来计算值:
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),
]
或者扩展您的 "addition" 概念以包括“+”和“-”操作。 (就像在工程学院一样,我们必须概括 "acceleration" 的概念以包括速度的任何变化,无论是向上还是向下。)
无论如何,如果您使用 infixNotation
方法,则必须让每个优先级别都包含该级别的所有运算符。