用 OneOrMore 匹配括号

Matching parenthesis with OneOrMore

在我正在处理的一个应用程序中,我们有一个 DSL 将一些字符组合在一起,它们可以分组也可以不分组。括号确定组。比如好的输入:

123
12(34)
1(234)

输入错误:

12(34

本质上,我希望任何不匹配的括号完全不被解析,因为就我正在做的事情而言,这应该是一个语法错误。我制作这个 MVCE 是为了显示我的 pyparsing 代码遇到的问题:

import pyparsing as pp

def Syntax():
    lpar = pp.Literal('(').suppress()
    rpar = pp.Literal(')').suppress()
    rank = pp.Word('12345678', exact=1) #card ranking
    ranks = pp.OneOrMore(rank)
    rank_grouping = pp.Group(lpar + ranks + rpar)
    atom = ranks | rank_grouping
    return pp.OneOrMore(atom)

mvce_parser = Syntax()
try:
    mvce_parser.parseString("(76)(54")
except pp.ParseException:
    print("Exception1 was thrown!")
else:
    print("Exception1 not thrown :(")

try:
    mvce_parser.parseString("(76(54)")
except pp.ParseException:
    print("Exception2 was thrown!")
else:
    print("Exception2 not thrown :(")

输出:

$ python test.py 
Exception1 not thrown :(
Exception2 was thrown!

我在这里遇到的问题是第一个示例字符串 (76)(54 在这里解析 returns [['7','6']] 但没有抛出我想要的 ParseException 。然而,第二个确实如预期的那样失败了。

我怀疑这是 OneOrMore 抑制了剩余部分的异常,然后返回它到目前为止的结果。

如何更改我的代码以避免这种不一致问题?即使 OneOrMore 很方便,还有其他方法可以不使用 OneOrMore 吗?

所以你想解析整个字符串。

要做到这一点,您需要在语法中显式添加 StringEnd()

return pp.OneOrMore(atom) + pp.FollowedBy(pp.StringEnd())

或使用 parseAll = True 参数

提供 parseString 调用
mvce_parser.parseString("(76)(54", parseAll=True)