正确的方法SkipTo不是空的令牌与ZeroOrMore在pyparsing

时间:2014-06-11 06:49:06

标签: python pyparsing

我有一些伪代码txt_block-[seq_block]-txt-block[seq_block][seq-block]。我希望通过存储序列提取所有txtseq块。

ZeroOrMore(nestedExpr('[', ']') | SkipTo(Literal('[')) | StringEnd()))

但是解析转到无限循环因为SkipTo总是返回空字符串。简化示例:

ZeroOrMore(SkipTo('p')).parseString('p')

目前,我通过空检查继承了SkipTo和copypaste parseImpl方法:

if not skipText:
     raise ParseException(instring, loc, self.errmsg, self)

但它看起来很难看。用pyparsing处理这个伪代码的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

这是一个简单的演示,说明您的情况:

from pyparsing import *

parser = "A" + SkipTo("B") + "B"

for test in ("ABC", "AXBC"):
    try:
        print test
        print parser.parseString(test)
    except ParseException as pe:
        print "exception:", pe
    print

这打印:

ABC
['A', '', 'B']

AXBC
['A', 'X', 'B']

第一场比赛是你不想要的 - 如果它将是空的,你不希望SkipTo成功。

要在任何解析器元素上添加一些额外的验证,您可以定义一个解析操作,并且如果不满足验证规则,则该方法会引发ParseException。在您的情况下,SkipTo元素的匹配标记不能为空。这是一个解析此操作的解析操作:

def mustNotBeEmpty(tokens):
    if not tokens[0]:
        raise ParseException("match must not be empty")

parser = "A" + SkipTo("B").setParseAction(mustNotBeEmpty) + "B"

现在,运行与上面相同的测试代码可以得到:

ABC
exception: match must not be empty (at char 0), (line:1, col:1)

AXBC
['A', 'X', 'B']