2017-02-21 2 views
1

В большинстве примеров, где я могу найти приоритет, используются сгруппированные (oneOf) литералы для установки того же уровня. При таком подходе мне нужно было бы посмотреть, какой из двух (или более) он есть, а затем продолжить оценку. То, что я хотел бы сделать, - это разделить операторов, чтобы напрямую узнать, какой из них и оценить.расщепление приоритетов pyparsing

Это то, что я хотел бы реализовать, но уровни приоритета теперь неправильно

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,), 
] 

Есть ли способ сделать это? Я тестировал с использованием oneOf и Or внутри arith_prec, но не использовал.

ответ

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, вам придется иметь каждый уровень приоритета включает всех операторов на этом уровне.

+0

Спасибо, так что мне просто нужно вернуться туда, где я начал, и продолжать оттуда. –

+0

Btw, ваш приоритет операций обратный - 'multop' должен идти первым. – PaulMcG