pyparsing 在 emtpy delimitedList 上引发异常

pyparsing raise exception on emtpy delimitedList

我正在尝试解析列表,例如 [1.0, 3.9],我想在列表为空时引发自定义异常。我遵循了这个 但没有取得太大成功。 这是我目前所拥有的:

class EmptyListError(ParseFatalException):
    """Exception raised by the parser for empty lists."""

    def __init__(self, s, loc, msg):
        super().__init__(s, loc, 'Empty lists not allowed \'{}\''.format(msg))


def hell_raiser(s, loc, toks):
    raise EmptyListError(s, loc, toks[0])


START, END = map(Suppress, '[]')
list_t = START + delimitedList(pyparsing_common.sci_real).setParseAction(lambda s, loc, toks: hell_raiser(s, loc, toks) if not toks else toks) + END


tests = """
[1.0, 1.0, 1.0]
[]
[     ]
""".splitlines()

for test in tests:
    if not test.strip():
        continue
    try:
        print(test.strip())
        result = list_t.parseString(test)
    except ParseBaseException as pe:
        print(pe)
    else:
        print(result)

打印:

[1.0, 1.0, 1.0]
[1.0, 1.0, 1.0]
[]
Expected real number with scientific notation (at char 1), (line:1, col:2)
[     ]
Expected real number with scientific notation (at char 6), (line:1, col:7)

delimitedList 不会匹配空列表,因此您的解析操作永远不会 运行。我稍微更改了您的解析器,使 [] 中的列表可选,然后 运行 您的 hellRaiser 解析操作:

list_t = START + Optional(delimitedList(pyparsing_common.sci_real)) + END

list_t.setParseAction(lambda s, loc, toks: hell_raiser(s, loc, toks) if not toks else toks)

得到你想要的输出:

[1.0, 1.0, 1.0]
[1.0, 1.0, 1.0]
[]
Empty lists not allowed '[]' (at char 0), (line:1, col:1)
[     ]
Empty lists not allowed '[]' (at char 0), (line:1, col:1)

您还可以用布尔条件替换您的解析操作,在这种情况下,只需 bool - 内置方法将根据标记列表进行评估,如果为空,则条件失败。

list_t.addCondition(bool, message="Empty lists not allowed", fatal=True)

得到这个:

[1.0, 1.0, 1.0]
[1.0, 1.0, 1.0]
[]
Empty lists not allowed (at char 0), (line:1, col:1)
[     ]
Empty lists not allowed (at char 0), (line:1, col:1)

最后,查看 ParserElement 上的 runTests() 方法。我写了很多次 "test-the-string-and-dump-the-results-or-catch-the-exception" 循环,我决定只添加一个测试便利函数。