Wysłałem to pytanie do anltr-interest, a Andrew Haritonkin odpowiedział. Bart K ma połowę rację; musisz zastąpić metodę recoverFromMismatchedSet(), ale także recoverFromMismatchedToken().
Jeśli też chcesz lexer, aby wyjść na pierwszym błędem, istnieje strona wiki, który wyjaśnia, co należy zrobić:
http://www.antlr.org/wiki/pages/viewpage.action?pageId=5341217
Pokrótce, stwierdza, że:
- Jeśli chcesz rzucić RecognitionException (lub coś dziedziczącego z Exception), musisz zrobić podstępne sztuczki Java, ponieważ odpowiednie metody nie zadeklarują żadnych wyjątków
- Jeśli jest to w porządku, aby rzucić RuntimeEx ception lub Error, możesz albo nadpisać nextToken(), aby rzucić wyjątek, zamiast wywoływać metodę recoverError(), albo możesz zastąpić metodę recoverError(). rzucić wyjątek.
Oto przykład gramatyki że wychodzi po pierwszym Lexer lub parsera błędu: wyjście
grammar Test;
@parser::members {
public static void main(String[] args) throws Exception {
String text = args[0];
ANTLRStringStream in = new ANTLRStringStream(text);
TestLexer lexer = new TestLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
System.out.println(new TestParser(tokens).mainRule());
}
@Override
protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException {
throw new MismatchedTokenException(ttype, input);
}
@Override
public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException {
throw e;
}
}
@rulecatch {
catch (RecognitionException e) {
throw e;
}
}
@lexer::members {
@Override
public void reportError(RecognitionException e) {
throw new RuntimeException(e);
}
}
mainRule returns [List<String> words]
@init{$words = new ArrayList<String>();}
: w=Atom {$words.add($w.text);} (',' w=Atom {$words.add($w.text);})* EOF
;
Atom: '0' | '1';
WS : ('\t' | ' ' | '\r' | '\n'| '\u000C')+ { $channel = HIDDEN; } ;
Próbka:
C:\Users\dan\workspace\antlrtest>java -cp .;antlr-3.2.jar TestParser "1,0"
[1, 0]
C:\Users\dan\workspace\antlrtest>java -cp .;antlr-3.2.jar TestParser "1,,0"
Exception in thread "main" MismatchedTokenException(6!=4)
at TestParser.recoverFromMismatchedToken(TestParser.java:45)
at org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:115)
at TestParser.mainRule(TestParser.java:86)
at TestParser.main(TestParser.java:40)
C:\Users\dan\workspace\antlrtest>java -cp .;antlr-3.2.jar TestParser "1,+0"
Exception in thread "main" java.lang.RuntimeException: NoViableAltException('[email protected][])
at TestLexer.reportError(TestLexer.java:16)
at org.antlr.runtime.Lexer.nextToken(Lexer.java:94)
at org.antlr.runtime.CommonTokenStream.fillBuffer(CommonTokenStream.java:119) at org.antlr.runtime.CommonTokenStream.LT(CommonTokenStream.java:238)
at org.antlr.runtime.Parser.getCurrentInputSymbol(Parser.java:54)
at org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:104)
at TestParser.mainRule(TestParser.java:68)
at TestParser.main(TestParser.java:40)
Caused by: NoViableAltException('+'@[])
at TestLexer.mTokens(TestLexer.java:165)
at org.antlr.runtime.Lexer.nextToken(Lexer.java:84)
... 6 more
Dzięki za follow up Dan! –