...
how do we detect the missing ';'? It's not as simple as looking for a ':' in rule element. In our case here, element has to look beyond 'b' in rule 'a' to see if there is an argument following (a[34], for example). It sees "a catch" instead and throws NoViableAltException. The problem is that the current input symbol is "b", not "catch". What we actually need to know is how far ahead it looked before it decided to fail. That token is the problem token (catch). So, I've updated v3 ANTLR runtime so that TokenStream knows how to ask for the "high water mark" via range(). Here is my handler for element that checks for the unterminated rule case:
Code Block |
---|
element
: ...
;
catch [RecognitionException re] {
int ttype = input.get(input.range()).getType();
// look for anything that really belongs at the start of the rule minus the initial ID
if ( ttype==COLON || ttype==RETURNS || ttype==CATCH || ttype==FINALLY || ttype==AT ) {
RecognitionException missingSemi =
new v4ParserException("unterminated rule (missing ';') detected at '"+
input.LT(1).getText()+" "+input.LT(2).getText()+"'", input);
reportError(missingSemi);
throw new ResyncToEndOfRuleBlock();
}
reportError(re);
recover(input,re);
retval.tree = (GrammarAST)adaptor.errorNode(input, retval.start, input.LT(-1), re);
}
|
...