Parsing logical sentence very slow with pyparsing

前端 未结 2 1812
滥情空心
滥情空心 2021-01-04 09:25

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 (         


        
2条回答
  •  攒了一身酷
    2021-01-04 10:24

    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')
    

提交回复
热议问题