我正在使用pyparsing
,并且为了解析一些文本,我创建了一个语法,然而,它按预期工作,对于像这样的表达式:
OR(OR(in1, in2), in3)
我想将嵌套表达式替换为“别名”,然后为这个别名创建一个表达式,简单来说就是:
# 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"]]
这是一个最小的例子,但是我可以有任何嵌套的“表达式”(只有两个参数)。有没有办法做到这一点?
答案 0 :(得分:1)
这是一个解析器,可能与您编写的解析器类似:
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']]
变量名称周围没有引号。
为此,我们需要从解析操作返回一个对象,该操作将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
变量与已分析的输入区分开来。