简约-简单的递归模式

时间:2019-07-12 10:50:00

标签: python parsimonious

我希望能够解析简单的规则表达式,可以使用parsimonious中的andor这样的连词将它们连接在一起。

我尝试了一个非常基本的语法,该语法分析了一个简单的表达式,但是一旦我开始引入连词,它就会失败。

import parsimonious

grammar = parsimonious.grammar.Grammar( """
    rule = (rule)+
    rule = (fieldname function parameters) / (rule conjunction rule)
    fieldname = space? ("field1" / "field2" / "field3") space?
    function = space? ("equal to" / "not equal to") space?
    parameters = space? "()" space?
    conjunction = space? ("and" / "or") space?
    space = ~r"\s+"
    """)

测试一个简单的案例:

grammar.parse("field1 equal to ()")

成功解析(至少看起来要构建一个节点树-我还没有深入研究它如何拆分内容-乍看起来还不错)

但是对于更复杂的情况:

grammar.parse("field1 equal to () and field2 not equal to ()")

它返回IncompleteParseError: Rule 'rule' matched in its entirety, but it didn't consume all the text. The non-matching portion of the text begins with 'and field2 not equal' (line 1, column 20).

我提出的语法试图允许任意组合的语句,但是我一定缺少一些东西。

我尝试调整语法以明确显示顶级类和低级类之间的区别:

grammar = parsimonious.grammar.Grammar( """
    rule = expr+
    expr = (fieldname function parameters) / (expr conjunction expr)
    fieldname = space? ("field1" / "field2" / "field3") space?
    function = space? ("equal to" / "not equal to") space?
    parameters = space? "()" space?
    conjunction = space? ("and" / "or") space?
    space = ~r"\s+"
    """)

现在,当运行由两部分组成的词组时:

grammar.parse("field1 equal to () and field2 not equal to ()")

我得到一个IncompleteParseError,而不是RecursionError: maximum recursion depth exceeded in comparison

1 个答案:

答案 0 :(得分:1)

(expr conjunction expr)的{​​{1}}部分中,您有一个左递归问题。因此,您需要将其分解为单独的规则,如下所示:

expr