Как выполнить сбой и генерировать исключения, когда правило не может быть полностью сопоставлено в PetitParserDart?

Я определил некоторые правила с PetitParserDart:

def("start", ref("rule").separatedBy(char('\n'), includeSeparators: false);
def("rule", char('(').seq(word().plus()).seq(char(')')));

Таким образом, следующий текст будет соответствовать:

(aaa)
(bbbbbb)

Но если есть строки, которые не могут совпадать:

(aaaa)
bbbbb
(cccccccc

Как определить грамматику, чтобы она не работала, и генерировать исключения в строке (ccccccccc, но не в сети bbbbb?

Я имею в виду, что он генерирует исключения только тогда, когда правило не полностью соответствует. Если ничто не соответствует, это не бросит исключение.

1 ответ

Решение

В любой точке грамматики вы можете ввести неработающий парсер:

failure('This parser always fails at this point');

Обычно PetitParser не использует исключения во время синтаксического анализа, успех и неудача обозначены соответствующими Success а также Failure контексты ответа.

Тем не менее, можно генерировать исключения, но обычно не рекомендуется, если пользователь вашей грамматики не может справиться с этим. Например, вы можете определить фабрику синтаксического анализатора следующим образом:

Parser thrower(String message) {
  return epsilon().map((value) => throw new IllegalStateException(message));
}

Используя обычные композиторы, вы можете генерировать очень точные сообщения об ошибках:

char('(')
  .seq(word().plus())
  .seq(char(')')
    // causes the parser to continue trying to parse the input
    .or(failure('something bad happened')))

Или с помощником выше:

char('(')
  .seq(word().plus())
  .seq(char(')')
     // stops parsing altogether and throws an exception
    .or(thrower('something bad happened')))
Другие вопросы по тегам