Обработка ошибок в ANTLR4

Поведение по умолчанию, когда анализатор не знает, что делать, это печатать сообщения в терминал, например:

в строке 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<ValueExtractor> 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, поэтому, возможно, я странным образом разбираюсь в вещах, но я не рассматривал, каким образом «непродвинутый» способ сделать это будет с тех пор хорошо работает для наших нужд.

Ответы на вопрос(3)

Ваш ответ на вопрос