исключение pyparsing повысить в emtpy delimitedList - PullRequest
1 голос
/ 15 марта 2019

Я пытаюсь проанализировать списки, например [1.0, 3.9], и я хотел бы вызвать пользовательское исключение, когда список пуст.Я следовал за этим https://stackoverflow.com/a/13409786/2528668, но без особого успеха.Вот что у меня есть:

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)

1 Ответ

1 голос
/ 17 марта 2019

delimitedList не будет совпадать с пустым списком, поэтому ваше действие синтаксического анализа никогда не запустится. Я немного изменил ваш парсер, чтобы сделать список внутри [] необязательным, а затем запустил ваше действие hellRaiser parse:

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)

Наконец, проверьте метод runTests() на ParserElement. Я много раз писал этот цикл «тест-строка-и-дамп-результаты-или-поймать-исключение», поэтому я решил просто добавить удобную функцию тестирования.

...