/** * This code is factored out from mismatched token and mismatched set recovery. It handles "single * token insertion" error recovery for both. No tokens are consumed to recover from insertions. * Return true if recovery was possible else return false. */ protected boolean recoverFromMismatchedElement( IntStream input, RecognitionException e, BitSet follow) { if (follow == null) { // we have no information about the follow; we can only consume // a single token and hope for the best return false; } // System.out.println("recoverFromMismatchedElement"); // compute what can follow this grammar element reference if (follow.member(Token.EOR_TOKEN_TYPE)) { BitSet viableTokensFollowingThisRule = computeContextSensitiveRuleFOLLOW(); follow = follow.or(viableTokensFollowingThisRule); follow.remove(Token.EOR_TOKEN_TYPE); } // if current token is consistent with what could come after set // then it is ok to "insert" the missing token, else throw exception // System.out.println("viable tokens="+follow.toString(getTokenNames())+")"); if (follow.member(input.LA(1))) { // System.out.println("LT(1)=="+input.LT(1)+" is consistent with what follows; inserting..."); reportError(e); return true; } // System.err.println("nothing to do; throw exception"); return false; }
// what is exact? it seems to only add sets from above on stack // if EOR is in set i. When it sees a set w/o EOR, it stops adding. // Why would we ever want them all? Maybe no viable alt instead of // mismatched token? protected BitSet combineFollows(boolean exact) { int top = state._fsp; BitSet followSet = new BitSet(); for (int i = top; i >= 0; i--) { BitSet localFollowSet = state.following[i]; /* System.out.println("local follow depth "+i+"="+ localFollowSet.toString(getTokenNames())+")"); */ followSet.orInPlace(localFollowSet); if (exact) { // can we see end of rule? if (localFollowSet.member(Token.EOR_TOKEN_TYPE)) { // Only leave EOR in set if at top (start rule); this lets // us know if have to include follow(start rule); i.e., EOF if (i > 0) { followSet.remove(Token.EOR_TOKEN_TYPE); } } else { // can't see end of rule, quit break; } } } return followSet; }
public boolean mismatchIsMissingToken(IntStream input, BitSet follow) { if (follow == null) { // we have no information about the follow; we can only consume // a single token and hope for the best return false; } // compute what can follow this grammar element reference if (follow.member(Token.EOR_TOKEN_TYPE)) { BitSet viableTokensFollowingThisRule = computeContextSensitiveRuleFOLLOW(); follow = follow.or(viableTokensFollowingThisRule); if (state._fsp >= 0) { // remove EOR if we're not the start symbol follow.remove(Token.EOR_TOKEN_TYPE); } } // if current token is consistent with what could come after set // then we know we're missing a token; error recovery is free to // "insert" the missing token // System.out.println("viable tokens="+follow.toString(getTokenNames())); // System.out.println("LT(1)="+((TokenStream)input).LT(1)); // BitSet cannot handle negative numbers like -1 (EOF) so I leave EOR // in follow set to indicate that the fall of the start symbol is // in the set (EOF can follow). if (follow.member(input.LA(1)) || follow.member(Token.EOR_TOKEN_TYPE)) { // System.out.println("LT(1)=="+((TokenStream)input).LT(1)+" is consistent with what follows; // inserting..."); return true; } return false; }
protected BitSet combineFollows(boolean exact) { int top = _fsp; BitSet followSet = new BitSet(); for (int i = top; i >= 0; i--) { BitSet localFollowSet = following[i]; /* * System.out.println("local follow depth "+i+"="+ * localFollowSet.toString(getTokenNames())+")"); */ followSet.orInPlace(localFollowSet); if (exact && !localFollowSet.member(Token.EOR_TOKEN_TYPE)) { break; } } followSet.remove(Token.EOR_TOKEN_TYPE); return followSet; }