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 ParseCancellationException
bez 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.