Pyparsing:组合infixnotation和setResultsNam

2024-10-06 19:22:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用infixNotation(以前是operatorPrecedence)编写语法,但我不知道如何使用setResultsName。在

我尝试这样做的原因是,我在searchparser之上为布尔搜索查询构建了一个语法,但是它会在非常长的表达式中遇到RecursionError: maximum recursion depth exceeded in comparison。在

因此,通过使用infixNotation(searchparser没有),我似乎可以避免遇到这个错误。 因此,我试图使语法适应infixNotation,但我的评估很大程度上依赖于结构化解析结果中每个操作符的名称,特别是,能够轻松访问操作符的参数。在

我从pyparsing一书中给出的示例开始:

and_ = CaselessLiteral("and")
or_  = CaselessLiteral("or")
not_ = CaselessLiteral("not")
searchTerm = Word(alphanums) | quotedString.setParseAction( removeQuotes )
searchExpr = infixNotation( searchTerm,
      [
      (not_, 1, opAssoc.RIGHT),
      (and_, 2, opAssoc.LEFT),
      (or_, 2, opAssoc.LEFT),
      ])

那么,如何在这里设置ParseResultName?在

如果我试图将其设置为操作员:

^{pr2}$

此字符串('term1或term2或term3')的结果分析结果如下所示:

<ITEM>
  <word>
    <word>
      <ITEM>term1</ITEM>
    </word>
    <OR>or</OR>
    <word>
      <ITEM>term2</ITEM>
    </word>
    <OR>or</OR>
    <word>
      <ITEM>term3</ITEM>
    </word>
  </word>
</ITEM>

这意味着所有的术语和运算符都在同一个级别上,而我想要的是这样的,其中术语作为运算符的参数排列:

<OR>
  <OR>
    <word>
      <ITEM>term1</ITEM>
    </word>
    <OR>
      <word>
        <ITEM>term2</ITEM>
      </word>
      <word>
        <ITEM>term3</ITEM>
      </word>
    </OR>
  </OR>
</OR>

我以前的语法是这样实现的:

operatorOr << (Group(
            operatorAnd + Suppress(Keyword("OR", caseless=True)) + operatorOr
        ).setResultsName("OR") | operatorAnd)

但我不知道如何将结果名设置为由运算符及其两个参数组成的组?在


Tags: orandterm1参数语法not运算符item
1条回答
网友
1楼 · 发布于 2024-10-06 19:22:33

我鼓励您考虑使用类作为解析操作,以建立操作节点树,而不是使用结果名称。在

在下面的代码中,我将UnOp和BinOp类附加到每个infixNotation运算符级别,这将返回那些正确分配了operator和{}属性的类的实例:

class OpNode:
    def __repr__(self):
        return "{}({}):{!r}".format(self.__class__.__name__,
                                    self.operator, self.operands)
class UnOp(OpNode):
    def __init__(self, tokens):
        self.operator = tokens[0][0]
        self.operands = [tokens[0][1]]

class BinOp(OpNode):
    def __init__(self, tokens):
        self.operator = tokens[0][1]
        self.operands = tokens[0][::2]

and_ = CaselessLiteral("and")
or_  = CaselessLiteral("or")
not_ = CaselessLiteral("not")
searchTerm = Word(alphanums) | quotedString.setParseAction(removeQuotes)
searchExpr = infixNotation(searchTerm,
      [
      (not_, 1, opAssoc.RIGHT, UnOp),
      (and_, 2, opAssoc.LEFT, BinOp),
      (or_, 2, opAssoc.LEFT, BinOp),
      ])

下面是一个示例字符串,显示如何返回这些节点:

^{pr2}$

给出:

[BinOp(or):['term1', 'term2', BinOp(and):['term3', 'term4', UnOp(not):['term5']]]]

您可以浏览这个已解析的树,并根据节点类型和运算符计算不同的节点。在

另外,asXML()不是转储已解析数据的最佳工具,最好使用dump()方法。在

相关问题 更多 >