pyparsing infixNotation优化

pyparsing infixNotation optimization

即使在使用 enablePackrat 之后,我对 infixNotation 的实现比我希望的要慢 运行,这大大提高了性能。

解析需要识别并解析以下类型的字符串:

我使用的代码:

def parse_expression(expr_str):

    fraction = Combine("." + Word(nums))
    number = Combine(Word(nums) + Optional(fraction)).setParseAction(str_to_num)

    event_id_expr = Word(alphanums + "_") + "::"
    dotted_columns = Combine(Word(alphanums + "_") + Optional("."))

    column_expr = Combine(event_id_expr + OneOrMore(dotted_columns))

    arith_expr = infixNotation(column_expr | number, [
        (Word(alphanums + "_"), 1, opAssoc.RIGHT),
        ("-", 1, opAssoc.RIGHT),
        (oneOf("* /"), 2, opAssoc.LEFT),
        (oneOf("+ -"), 2, opAssoc.LEFT),
        (Literal(","), 2, opAssoc.LEFT)
    ])

    parsed_expr = arith_expr.parseString(expr_str).asList()[0]

    return parsed_expr

 def str_to_num(t):
      num_str = t[0]
      try:
          return int(num_str)
      except ValueError:
          return float(num_str)

我是否可以进行任何更改以显着提高性能?我正在解析的结构相当简单,但它们是分批处理的。平均每个字符串需要 ~5.3ms。

看起来你是 "fudging" 函数,就好像它们是运算符一样,我认为你最好将函数调用移动到 infixNotation:

的操作数表达式中
def parse_expression(expr_str):

    number = pyparsing_common.number()

    event_id_expr = Word(alphas+"_", alphanums + "_") + "::"
    dotted_columns = Combine(Word(alphas+"_", alphanums + "_") + Optional("."))

    column_expr = Combine(event_id_expr + OneOrMore(dotted_columns))

    func_name = Word(alphas+"_", alphanums+'_')
    LPAR, RPAR = map(Suppress, "()")
    arith_expr = Forward()
    func_call = Group(func_name('name') 
                      + LPAR 
                      + Group(Optional(delimitedList(arith_expr)))("args") 
                      + RPAR)

    arith_expr <<= infixNotation(number | func_call | column_expr, [
        ("-", 1, opAssoc.RIGHT),
        (oneOf("* /"), 2, opAssoc.LEFT),
        (oneOf("+ -"), 2, opAssoc.LEFT),
    ])

    parsed_expr = arith_expr.parseString(expr_str)[0]

    return parsed_expr

我还修改了您的大部分标识符以使用 Word 的双参数形式 - 仅使用 Word(alphanums+"_") 也将匹配普通整数,我不认为 是你的意图。如果我弄错了,就把它们放回原来的样子。