...
When we see 'catch', we need to report an error and then blow all the way out back to the "ruleBlock" rule. That screams out for a specialized recognition an exception object. All we have to do is throw it
...
Code Block |
---|
ruleBlock
: altList
;
catch [ResyncToEndOfRuleBlock e] {}
|
Code Block |
---|
/** Used to throw us out of deeply nested element back to end of a rule's * alt list. Note it's not under RecognitionException. */ public class ResyncToEndOfRuleBlock extends RuntimeException { } |
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:
...