使用递归语法进行pyparsing

时间:2016-02-18 17:31:41

标签: parsing recursion pyparsing

我无法使用pyparsing正确解析递归语法。尽管我认为它会将它识别为“param”解析器的三个匹配项(其中两个嵌套在一个“parent”下),但下面代码中的测试#5失败了:

import pyparsing as p

DOUBLE_QUOTE  = p.Word('"')
SINGLE_QUOTE  = p.Word("'")
COMMA         = p.Suppress(p.Word(","))
EQUALS        = p.Suppress(p.Word("="))
RIGHT_PAREN   = p.Suppress(p.Word(")"))
LEFT_PAREN    = p.Suppress(p.Word("("))
WORD          = p.Word(p.alphanums + '<' + '<' + '>' + '/' + '.' + ':' + \
        ';' + '-' + '_' + '$' + '+' + '*' + '&' + '!' + '%' + '?' + '@' + '\\')
QUOTED_STRING = p.QuotedString("'") | p.QuotedString('"')
value         = WORD | QUOTED_STRING
value_list    = value + p.ZeroOrMore(COMMA + value)
keyword       = WORD
pv1           = value
pv2           = (LEFT_PAREN + value_list + RIGHT_PAREN)
pv3           = p.Forward()
param         = keyword + EQUALS + p.Group(p.OneOrMore(pv3) | pv2 | pv1)
pv3 << (LEFT_PAREN + param + RIGHT_PAREN)

parser = p.OneOrMore(p.Group(param))

tests = []
tests.append("""l1=v1""")
tests.append("""l1=(v1,v2,v3)""")
tests.append("""l1=(v1,v2,v3) l1=(v4, v5, v6)""")
tests.append("""l1=(l2=v1)""")
tests.append("""l1=v1 l1=v2""")

# This test fails
tests.append("""l1=(l2=(l3=v1))""")

results = []
for (i, test_string) in enumerate(tests):
    try:
        results.append(parser.parseString(test_string))
    except Exception as e:
        print("Failed test #{}".format(i))
        print(e)

我在哪里出错?

1 个答案:

答案 0 :(得分:2)

当我检查你的递归​​是否正确时,我花了一些时间来计算这个。但事实证明,您的代码在代码顶部有两行代码(我认为已经更正),这很好。

错误是由于您使用p.Word而不是p.Literal设置括号。因此,通过将代码更改为此代码,它应该可以工作:

RIGHT_PAREN   = p.Suppress(p.Literal(")"))
LEFT_PAREN    = p.Suppress(p.Literal("("))

来自PyParsing wiki的提醒:

  

Literal - 构造一个完全匹配的字符串

     

Word - 一个或多个连续字符;使用包含允许的初始字符集的字符串构造,以及可选的第二个允许的正文字符串;

相关问题