I try to use pyparsing to parse logical expressions such as these
x
FALSE
NOT x
(x + y <= 5) AND (y >= 10) OR NOT (z < 100 OR w)
(A=True OR NOT (
I had the same problem. Found a solution here (parserElement.enablePackrat()
): https://github.com/pyparsing/pyparsing
The following code is now parsed instantly (vs 60 sec before)
ParserElement.enablePackrat()
integer = Word(nums).setParseAction(lambda t:int(t[0]))('int')
operand = integer | variable('var')
# Left precedence
eq = Literal("==")('eq')
gt = Literal(">")('gt')
gtEq = Literal(">=")('gtEq')
lt = Literal("<")('lt')
ltEq = Literal("<=")('ltEq')
notEq = Literal("!=")('notEq')
mult = oneOf('* /')('mult')
plus = oneOf('+ -')('plus')
_and = oneOf('&& and')('and')
_or = oneOf('|| or')('or')
# Right precedence
sign = oneOf('+ -')('sign')
negation = Literal('!')('negation')
# Operator groups per presedence
right_op = negation | sign
# Highest precedence
left_op_1 = mult
left_op_2 = plus
left_op_3 = gtEq | ltEq | lt | gt
left_op_4 = eq | notEq
left_op_5 = _and
left_op_6 = _or
# Lowest precedence
condition = operatorPrecedence( operand, [
(right_op, 1, opAssoc.RIGHT),
(left_op_1, 2, opAssoc.LEFT),
(left_op_2, 2, opAssoc.LEFT),
(left_op_3, 2, opAssoc.LEFT),
(left_op_4, 2, opAssoc.LEFT),
(left_op_5, 2, opAssoc.LEFT),
(left_op_6, 2, opAssoc.LEFT)
]
)('computation')