Обработка ошибок в ANTLR4
Поведение по умолчанию, когда анализатор не делаетt знать, что нужно сделать, это напечатать сообщения в терминал, как:
в строке 1:23 отсутствует DECIMAL в '}'
Это хорошее сообщение, но не в том месте. Я'Я предпочел бы получить это как исключение.
мы пытались использоватьBailErrorStrategy
, но это бросаетParseCancellationException
без сообщения (вызваноInputMismatchException
также без сообщения).
Есть ли способ заставить его сообщать об ошибках через исключения, сохраняя полезную информацию в сообщении?
Вот'что яЯ действительно после - я обычно использую действия в правилах для создания объекта:
dataspec returns [DataExtractor extractor]
@init {
DataExtractorBuilder builder = new DataExtractorBuilder(layout);
}
@after {
$extractor = builder.create();
}
: first=expr { builder.addAll($first.values); } (COMMA next=expr { builder.addAll($next.values); })* EOF
;
expr returns [List values]
: a=atom { $values = Arrays.asList($a.val); }
| fields=fieldrange { $values = values($fields.fields); }
| '%' { $values = null; }
| ASTERISK { $values = values(layout); }
;
Затем, когда я вызываю парсер, я делаю что-то вроде этого:
public static DataExtractor create(String dataspec) {
CharStream stream = new ANTLRInputStream(dataspec);
DataSpecificationLexer lexer = new DataSpecificationLexer(stream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
DataSpecificationParser parser = new DataSpecificationParser(tokens);
return parser.dataspec().extractor;
}
Все, что я действительно хочу, это
дляdataspec()
вызов, чтобы вызвать исключение (в идеале проверенное), когда ввод можетбыть разобраннымчтобы это исключение имело полезное сообщение и предоставляло доступ к номеру строки и позиции, в которой была обнаружена проблемаЗатем я'Позвольте этому исключению пузыриться в стеке вызовов там, где это лучше всего подходит для представления полезного сообщения пользователю - так же, как яобрабатывать потерянное сетевое соединение, чтение поврежденного файла и т. д.
Я видел, что действия сейчас рассматриваютсяпродвинутый» в ANTLR4, так что, возможно, яЯ делаю вещи странным образом, но у меня нетт посмотрел в чем "не продвинутый» способ сделать это будет, так как этот путь хорошо работает для наших нужд.