Obsługa błędów w ANTLR4

Domyślnym zachowaniem, gdy analizator składni nie wie, co zrobić, jest drukowanie wiadomości do terminala, takich jak:

linia 1:23 brak DECIMAL w '}'

To dobra wiadomość, ale w złym miejscu. Wolałbym otrzymać to jako wyjątek.

Próbowałem użyćBailErrorStrategy, ale to rzucaParseCancellationException bez wiadomości (spowodowane przez aInputMismatchException, także bez wiadomości).

Czy istnieje sposób na zgłoszenie błędów za pomocą wyjątków przy zachowaniu przydatnych informacji w wiadomości?

Oto, czego naprawdę oczekuję - zazwyczaj używam akcji w regułach, aby zbudować obiekt:

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); }
    ;

Następnie, kiedy wywołam parser, robię coś takiego:

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;
}

Chcę tylko

dladataspec() wywołać wyjątek (najlepiej sprawdzony), gdy wejście nie może zostać przeanalizowaneaby ten wyjątek miał użyteczny komunikat i zapewniał dostęp do numeru linii i pozycji, w której problem został znaleziony

Następnie pozwolę, aby ten wyjątek pojawił się w pakiecie callstack, gdzie najlepiej nadaje się do przedstawienia użytecznej wiadomości dla użytkownika - w ten sam sposób, w jaki radzę sobie z upuszczonym połączeniem sieciowym, odczytaniem uszkodzonego pliku itp.

Widziałem, że działania są teraz uważane za „zaawansowane” w ANTLR4, więc może zajmuję się sprawami w dziwny sposób, ale nie sprawdziłem, jak będzie wyglądał „nie-zaawansowany” sposób, aby to zrobić działa dobrze dla naszych potrzeb.

questionAnswers(3)

yourAnswerToTheQuestion