Revert "Simplify Parser.getExpectedTokens and DefaultErrorStrategy.getErrorRecoverySet"

This reverts commit d33172dce5.
This commit is contained in:
Terence Parr 2012-11-04 17:02:41 -08:00
parent e5c2dfaac4
commit 61ed3bc019
2 changed files with 32 additions and 3 deletions

View File

@ -34,6 +34,7 @@ import org.antlr.v4.runtime.atn.ATNState;
import org.antlr.v4.runtime.atn.BlockStartState;
import org.antlr.v4.runtime.atn.PlusBlockStartState;
import org.antlr.v4.runtime.atn.PlusLoopbackState;
import org.antlr.v4.runtime.atn.RuleTransition;
import org.antlr.v4.runtime.atn.StarLoopEntryState;
import org.antlr.v4.runtime.atn.StarLoopbackState;
import org.antlr.v4.runtime.misc.IntervalSet;
@ -521,8 +522,19 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy {
*/
protected IntervalSet getErrorRecoverySet(Parser recognizer) {
ATN atn = recognizer.getInterpreter().atn;
ParserRuleContext ctx = recognizer._ctx;
return atn.nextTokens(atn.states.get(ctx.s), ctx);
RuleContext ctx = recognizer._ctx;
IntervalSet recoverSet = new IntervalSet();
while ( ctx!=null && ctx.invokingState>=0 ) {
// compute what follows who invoked us
ATNState invokingState = atn.states.get(ctx.invokingState);
RuleTransition rt = (RuleTransition)invokingState.transition(0);
IntervalSet follow = atn.nextTokens(rt.followState);
recoverSet.addAll(follow);
ctx = ctx.parent;
}
recoverSet.remove(Token.EPSILON);
// System.out.println("recover set "+recoverSet.toString(recognizer.getTokenNames()));
return recoverSet;
}
/** Consume tokens until one matches the given token set */

View File

@ -547,7 +547,24 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator> {
ATN atn = getInterpreter().atn;
ParserRuleContext ctx = _ctx;
ATNState s = atn.states.get(ctx.s);
return atn.nextTokens(s, ctx);
IntervalSet following = atn.nextTokens(s);
// System.out.println("following "+s+"="+following);
if ( !following.contains(Token.EPSILON) ) return following;
IntervalSet expected = new IntervalSet();
expected.addAll(following);
expected.remove(Token.EPSILON);
while ( ctx!=null && ctx.invokingState>=0 && following.contains(Token.EPSILON) ) {
ATNState invokingState = atn.states.get(ctx.invokingState);
RuleTransition rt = (RuleTransition)invokingState.transition(0);
following = atn.nextTokens(rt.followState);
expected.addAll(following);
expected.remove(Token.EPSILON);
ctx = (ParserRuleContext)ctx.parent;
}
if ( following.contains(Token.EPSILON) ) {
expected.add(Token.EOF);
}
return expected;
}
public IntervalSet getExpectedTokensWithinCurrentRule() {