Python Pyparsing:将infixnotation与setResultsName相结合
我试图使用Python Pyparsing:将infixnotation与setResultsName相结合,python,parsing,pyparsing,Python,Parsing,Pyparsing,我试图使用infixNotation(以前是operatorrecessence)编写语法,但我不知道如何使用setResultsName 我尝试这样做的原因是,我为布尔搜索查询构建了一个语法,但它遇到了一个递归错误:对于非常长的表达式,在比较中超过了最大递归深度 因此,似乎通过使用infixNotation(searchparser没有),我可以避免遇到这个错误。 因此,我试图使语法适应infixNotation,但我的计算很大程度上依赖于在结构化解析结果中拥有每个运算符的名称,特别是,能够轻
infixNotation
(以前是operatorrecessence
)编写语法,但我不知道如何使用setResultsName
我尝试这样做的原因是,我为布尔搜索查询构建了一个语法,但它遇到了一个递归错误:对于非常长的表达式,在比较中超过了最大递归深度
因此,似乎通过使用infixNotation(searchparser没有),我可以避免遇到这个错误。
因此,我试图使语法适应infixNotation,但我的计算很大程度上依赖于在结构化解析结果中拥有每个运算符的名称,特别是,能够轻松访问运算符的参数
我从书中给出的示例开始:
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
如果我尝试将其设置为操作员:
or_ = CaselessLiteral("or").setResultsName("OR")
<OR>
<OR>
<word>
<ITEM>term1</ITEM>
</word>
<OR>
<word>
<ITEM>term2</ITEM>
</word>
<word>
<ITEM>term3</ITEM>
</word>
</OR>
</OR>
</OR>
此字符串('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>
术语1
或
术语2
或
第三学期
这意味着所有的术语和操作符都在同一个层次上,而我想要这样的东西,其中术语被安排为操作符的参数:
or_ = CaselessLiteral("or").setResultsName("OR")
<OR>
<OR>
<word>
<ITEM>term1</ITEM>
</word>
<OR>
<word>
<ITEM>term2</ITEM>
</word>
<word>
<ITEM>term3</ITEM>
</word>
</OR>
</OR>
</OR>
术语1
术语2
第三学期
在我以前的语法中,我经常这样做:
operatorOr << (Group(
operatorAnd + Suppress(Keyword("OR", caseless=True)) + operatorOr
).setResultsName("OR") | operatorAnd)
<代码>操作程序> p>我鼓励您考虑使用类作为解析动作,以建立操作节点树,而不是使用结果名称。
在下面的代码中,我将UnOp和BinOp类附加到每个infixNotation运算符级别,这将返回那些已正确分配运算符
和操作数
属性的类的实例:
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),
])
以下是显示如何返回这些节点的示例字符串:
test = "term1 or term2 or term3 and term4 and not term5"
print(searchExpr.parseString(test))
给出:
[BinOp(or):['term1', 'term2', BinOp(and):['term3', 'term4', UnOp(not):['term5']]]]
您可以导航此解析树,并根据不同节点的节点类型和运算符对其求值
而且asXML()
不是转储解析数据的最佳工具,最好使用dump()
方法