Рассмотрим, что мы пытаемся подавать некорректный вводный текст на некоторую грамматику (например, текст, содержащий неизвестный токен). В ANTLRWorks
при интерпретации мы увидим NoViableAltException
в графике.Ловля ANTLR's NoViableAltException в Java и ANTLRWorks Debugger
UPD: Есть два случая, когда появляется это исключение:
1) Неожиданный с использованием некоторых известных маркеров, в этом случае мы получим что-то вроде line 5:36 no viable alternative at input ','
2) Используя неизвестный тип маркеров. Например, грамматика ничего не знает о токенах, которые начинаются с символа @
. И мы пытаемся прокормить текст таким маркером нашей грамматики.
К сожалению, в случае (2) это исключение не выбрасывается ни в ANTLRWorks
отладчик, ни в сгенерированный код Java; но это видно только в графике результатов интерпретатора ANTLRWorks
.
Я попытался также добавить следующий стандартный код для моей грамматике:
@parser::members {
private IErrorReporter errorReporter = null;
public void setErrorReporter(IErrorReporter errorReporter) {
this.errorReporter = errorReporter;
}
public void emitErrorMessage(String msg) {
errorReporter.reportError(msg);
}
}
@lexer::members {
... the same code as above ...
}
Эта конструкция успешно ловит разборе ошибок типа (1) (например, сообщения об ошибках, неожиданное использование маркера: line 5:36 no viable alternative at input ','
). Но в случае не-жизнеспособного ввода с неизвестным парсером токенов генерирует только children == null
в верхнем CommonTree
объекте без сообщений об ошибках.
Я использую antlr 3.5
.
Вопрос: можно ли поймать NoViableAltException
в описанной ситуации в сгенерированном Java-коде и как?
Хорошая идея. ** Но это также не дает мне никакого результата **. Для неправильного текста ошибки нет. – Andremoniy
Вы уверены, что вход получает токенизован должным образом (является ли недопустимый символ '@' от вашего ввода, доводя его до парсера)? Вы не разместили грамматику, поэтому сложно проверить свою ситуацию. –
Я могу подтвердить, что добавление правила lexer 'ANYCHAR' не может решить проблему. Но ваш ответ на мой второй вопрос об «OutofmemoryError» хорошо решает эту проблему. Было ясно, что обе проблемы чередуются. – Andremoniy