Python 正在解析表达式并替换为另一个表达式

Python Parsing Expression and replacing with another expression

我正在使用 pyparsing,为了解析一些文本,我创建了一个语法,它按预期工作,但是,对于像这样的表达式:

OR(OR(in1, in2), in3)

我想将嵌套表达式替换为 "alias",然后为此别名创建一个表达式,简单来说:

# I have this expression ( OR(OR(in1, in2), in3) )
# Which I parsed to
parsed = ["OR", [["OR", ["in1", "in2"]], "in3"]]

# I want to have
exp1 = ["OR", ["in1", "in2"]]
exp2 = ["OR", ["exp1", "in3"]]

这是一个最小的例子,但是我可以有任何嵌套的 "expressions"(只有两个参数)。有办法吗?

这是一个可能与您编写的类似的解析器:

import pyparsing as pp

LPAR, RPAR = map(pp.Suppress, "()")
OR = pp.Keyword("OR")
term = pp.pyparsing_common.identifier

or_expr = pp.Forward()
or_expr <<= pp.Group(OR + pp.Group(LPAR + pp.delimitedList(or_expr | term)) + RPAR)

当它解析您提供的字符串时,它会提供相同的嵌套输出。

要创建 "expN" 表达式名称,您可以使用解析操作在全局列表 var:

中收集表达式和关联的表达式 ID
# add parse action to convert OR's to exprs
exprs = []
def generate_expr_definition(tokens):
    expr_name = "exp{}".format(len(exprs)+1)
    exprs.append((expr_name, tokens.asList()[0]))
    return expr_name
or_expr.addParseAction(generate_expr_definition)

当你运行这个解析器时,创建的结果并不是重要的部分。重要的是解析时构建的 exprs 列表:

or_expr.parseString(sample)

# generate assignments for each nested OR expr
for name, expr in exprs:
    print("{} = {}".format(name, expr))

这给出:

exp1 = ['OR', ['in1', 'in2']]
exp2 = ['OR', ['exp1', 'in3']]

现在我看着它,然后问,“我怎么知道从输入中解析的 'exp1' 与应该表示已解析表达式的 'exp1' 之间的区别。如果这将被解释为 Python 赋值,它实际上应该是:

exp2 = ['OR', [exp1, 'in3']]

变量名两边没有引号。

为此,我们需要 return 解析操作中的一个对象,该对象将 repr 作为不带引号的名称。像这样:

class ExprName:
    def __init__(self, name):
        self._name = name
    def __repr__(self):
        return self._name

将解析动作中的return语句改为:

return ExprName(expr_name)

结果输出现在看起来像:

exp1 = ['OR', ['in1', 'in2']]
exp2 = ['OR', [exp1, 'in3']]

现在您可以区分生成的 expN 变量和解析的输入。