Domyślnym zachowaniem, gdy parser nie wie, co zrobić, jest drukowanie wiadomości na terminalu, takich jak:
w wierszu 1:23 brakuje DECIMAL w „}”
To dobra wiadomość, ale w niewłaściwym miejscu. Wolałbym przyjąć to jako wyjątek.
Próbowałem użyć BailErrorStrategy, ale to rzuca ParseCancellationExceptionbez komunikatu (spowodowane przez InputMismatchException, również bez komunikatu).
Czy istnieje sposób, aby zgłosić błędy za pośrednictwem wyjątków, zachowując przydatne informacje w wiadomości?
Oto, czego naprawdę szukam - zwykle 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łuję 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;
}
Wszystko, czego naprawdę chcę, to
- aby
dataspec()wywołanie zgłosiło wyjątek (najlepiej zaznaczony), gdy nie można przeanalizować danych wejściowych - aby ten wyjątek miał użyteczną wiadomość i zapewniał dostęp do numeru linii i pozycji, w której znaleziono problem
Następnie pozwolę temu wyjątkowi wypłynąć w górę stosu wywołań, gdzie najlepiej nadaje się do przedstawienia użytkownikowi użytecznej wiadomości - w ten sam sposób, w jaki poradziłbym sobie z zerwaniem połączenia sieciowego, odczytaniem uszkodzonego pliku itp.
Widziałem, że akcje są teraz uważane za "zaawansowane" w ANTLR4, więc może zajmuję się rzeczami w dziwny sposób, ale nie sprawdziłem, jaki byłby "niezaawansowany" sposób, aby to zrobić od tego czasu działa dobrze na nasze potrzeby.