From 61ed3bc01940995031d64768d5ee0b8ef037750c Mon Sep 17 00:00:00 2001 From: Terence Parr Date: Sun, 4 Nov 2012 17:02:41 -0800 Subject: [PATCH] Revert "Simplify Parser.getExpectedTokens and DefaultErrorStrategy.getErrorRecoverySet" This reverts commit d33172dce5cf7f41c00f7c3ed772ce2b927f0a60. --- .../v4/runtime/DefaultErrorStrategy.java | 16 ++++++++++++++-- .../Java/src/org/antlr/v4/runtime/Parser.java | 19 ++++++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java b/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java index 82592ad4d..838fed58f 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java +++ b/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java @@ -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 */ diff --git a/runtime/Java/src/org/antlr/v4/runtime/Parser.java b/runtime/Java/src/org/antlr/v4/runtime/Parser.java index 0e5059cee..3d5622e1c 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Parser.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Parser.java @@ -547,7 +547,24 @@ public abstract class Parser extends Recognizer { 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() {