diff --git a/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java b/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java index 838fed58f..98796df9a 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java +++ b/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java @@ -127,7 +127,7 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy { // ", states="+lastErrorStates); if ( lastErrorIndex==recognizer.getInputStream().index() && lastErrorStates != null && - lastErrorStates.contains(recognizer._ctx.s) ) { + lastErrorStates.contains(recognizer.getState()) ) { // uh oh, another error at same token index and previously-visited // state in ATN; must be a case where LT(1) is in the recovery // token set so nothing got consumed. Consume a single token @@ -139,7 +139,7 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy { } lastErrorIndex = recognizer.getInputStream().index(); if ( lastErrorStates==null ) lastErrorStates = new IntervalSet(); - lastErrorStates.add(recognizer._ctx.s); + lastErrorStates.add(recognizer.getState()); IntervalSet followSet = getErrorRecoverySet(recognizer); consumeUntil(recognizer, followSet); } @@ -161,7 +161,7 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy { */ @Override public void sync(Parser recognizer) { - ATNState s = recognizer.getInterpreter().atn.states.get(recognizer._ctx.s); + ATNState s = recognizer.getInterpreter().atn.states.get(recognizer.getState()); // System.err.println("sync @ "+s.stateNumber+"="+s.getClass().getSimpleName()); // If already recovering, don't try to sync if ( errorRecoveryMode ) return; @@ -316,7 +316,7 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy { // if current token is consistent with what could come after current // ATN state, then we know we're missing a token; error recovery // is free to conjure up and insert the missing token - ATNState currentState = recognizer.getInterpreter().atn.states.get(recognizer._ctx.s); + ATNState currentState = recognizer.getInterpreter().atn.states.get(recognizer.getState()); ATNState next = currentState.transition(0).target; ATN atn = recognizer.getInterpreter().atn; IntervalSet expectingAtLL2 = atn.nextTokens(next, recognizer._ctx); diff --git a/runtime/Java/src/org/antlr/v4/runtime/FailedPredicateException.java b/runtime/Java/src/org/antlr/v4/runtime/FailedPredicateException.java index ece08cc97..6291258f4 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/FailedPredicateException.java +++ b/runtime/Java/src/org/antlr/v4/runtime/FailedPredicateException.java @@ -56,7 +56,7 @@ public class FailedPredicateException extends RecognitionException { @Nullable String message) { super(formatMessage(predicate, message), recognizer, recognizer.getInputStream(), recognizer._ctx); - ATNState s = recognizer.getInterpreter().atn.states.get(recognizer._ctx.s); + ATNState s = recognizer.getInterpreter().atn.states.get(recognizer.getState()); PredicateTransition trans = (PredicateTransition)s.transition(0); this.ruleIndex = trans.ruleIndex; this.predicateIndex = trans.predIndex; diff --git a/runtime/Java/src/org/antlr/v4/runtime/Parser.java b/runtime/Java/src/org/antlr/v4/runtime/Parser.java index 3d5622e1c..4c4a601f5 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Parser.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Parser.java @@ -419,7 +419,8 @@ public abstract class Parser extends Recognizer { * This is flexible because users do not have to regenerate parsers * to get trace facilities. */ - public void enterRule(ParserRuleContext localctx, int ruleIndex) { + public void enterRule(ParserRuleContext localctx, int state, int ruleIndex) { + setState(state); _ctx = localctx; _ctx.start = _input.LT(1); if (_buildParseTrees) addContextToParseTree(); @@ -430,6 +431,7 @@ public abstract class Parser extends Recognizer { _ctx.stop = _input.LT(-1); // trigger event on _ctx, before it reverts to parent if ( _parseListeners != null) triggerExitRuleEvent(); + setState(_ctx.invokingState); _ctx = (ParserRuleContext)_ctx.parent; } @@ -514,7 +516,7 @@ public abstract class Parser extends Recognizer { // return getInterpreter().atn.nextTokens(_ctx); ATN atn = getInterpreter().atn; ParserRuleContext ctx = _ctx; - ATNState s = atn.states.get(ctx.s); + ATNState s = atn.states.get(getState()); IntervalSet following = atn.nextTokens(s); if (following.contains(symbol)) { return true; @@ -546,7 +548,7 @@ public abstract class Parser extends Recognizer { public IntervalSet getExpectedTokens() { ATN atn = getInterpreter().atn; ParserRuleContext ctx = _ctx; - ATNState s = atn.states.get(ctx.s); + ATNState s = atn.states.get(getState()); IntervalSet following = atn.nextTokens(s); // System.out.println("following "+s+"="+following); if ( !following.contains(Token.EPSILON) ) return following; @@ -569,7 +571,7 @@ public abstract class Parser extends Recognizer { public IntervalSet getExpectedTokensWithinCurrentRule() { ATN atn = getInterpreter().atn; - ATNState s = atn.states.get(_ctx.s); + ATNState s = atn.states.get(getState()); return atn.nextTokens(s); } @@ -653,19 +655,6 @@ public abstract class Parser extends Recognizer { return strings; } - /** Indicate that the recognizer has changed internal state that is - * consistent with the ATN state passed in. This way we always know - * where we are in the ATN as the parser goes along. The rule - * context objects form a stack that lets us see the stack of - * invoking rules. Combine this and we have complete ATN - * configuration information. - */ - public void setState(int atnState) { -// System.err.println("setState "+atnState); - _ctx.s = atnState; -// if ( traceATNStates ) _ctx.trace(atnState); - } - /** During a parse is sometimes useful to listen in on the rule entry and exit * events as well as token matches. This is for quick and dirty debugging. */ diff --git a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java index 2664b7cbb..5d4827083 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java @@ -93,13 +93,6 @@ public class ParserRuleContext extends RuleContext { */ // public List states; - /** Current ATN state number we are executing. - * - * Not used during ATN simulation/prediction; only used during parse that updates - * current location in ATN. - */ - public int s = -1; - public Token start, stop; /** Set during parsing to identify which alt of rule parser is in. */ @@ -117,20 +110,14 @@ public class ParserRuleContext extends RuleContext { public void copyFrom(ParserRuleContext ctx) { // from RuleContext this.parent = ctx.parent; - this.s = ctx.s; this.invokingState = ctx.invokingState; this.start = ctx.start; this.stop = ctx.stop; } - public ParserRuleContext(@Nullable ParserRuleContext parent, int invokingStateNumber, int stateNumber) { + public ParserRuleContext(@Nullable ParserRuleContext parent, int invokingStateNumber) { super(parent, invokingStateNumber); - this.s = stateNumber; - } - - public ParserRuleContext(@Nullable ParserRuleContext parent, int stateNumber) { - this(parent, parent!=null ? parent.s : -1 /* invoking state */, stateNumber); } // Double dispatch methods for listeners diff --git a/runtime/Java/src/org/antlr/v4/runtime/RecognitionException.java b/runtime/Java/src/org/antlr/v4/runtime/RecognitionException.java index 3b3bedc3a..d800e4269 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/RecognitionException.java +++ b/runtime/Java/src/org/antlr/v4/runtime/RecognitionException.java @@ -63,7 +63,7 @@ public class RecognitionException extends RuntimeException { this.recognizer = recognizer; this.input = input; this.ctx = ctx; - if ( ctx!=null ) this.offendingState = ctx.s; + if ( recognizer!=null ) this.offendingState = recognizer.getState(); } public RecognitionException(String message, @Nullable Recognizer recognizer, IntStream input, @@ -73,7 +73,7 @@ public class RecognitionException extends RuntimeException { this.recognizer = recognizer; this.input = input; this.ctx = ctx; - if ( ctx!=null ) this.offendingState = ctx.s; + if ( recognizer!=null ) this.offendingState = recognizer.getState(); } /** Where was the parser in the ATN when the error occurred? diff --git a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java index 719434f8f..1d4936153 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java @@ -48,6 +48,8 @@ public abstract class Recognizer { protected ATNInterpreter _interp; + private int _stateNumber = -1; + /** Used to print out token names like ID during debugging and * error reporting. The generated parsers implement a method * that overrides this to point to their String[] tokenNames. @@ -134,6 +136,23 @@ public abstract class Recognizer { public void action(@Nullable RuleContext _localctx, int ruleIndex, int actionIndex) { } + public final int getState() { + return _stateNumber; + } + + /** Indicate that the recognizer has changed internal state that is + * consistent with the ATN state passed in. This way we always know + * where we are in the ATN as the parser goes along. The rule + * context objects form a stack that lets us see the stack of + * invoking rules. Combine this and we have complete ATN + * configuration information. + */ + public final void setState(int atnState) { +// System.err.println("setState "+atnState); + _stateNumber = atnState; +// if ( traceATNStates ) _ctx.trace(atnState); + } + public abstract IntStream getInputStream(); public abstract void setInputStream(IntStream input); diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg index 151e3e242..07a1c953b 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg @@ -208,8 +208,8 @@ RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAc }; separator="\n"> }>public final () throws RecognitionException { - _localctx = new (_ctx, }>); - enterRule(_localctx, RULE_); + _localctx = new (_ctx, getState()}>); + enterRule(_localctx, , RULE_); try { @@ -246,7 +246,7 @@ LeftRecursiveRuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs, }>public final () throws RecognitionException { ParserRuleContext _parentctx = _ctx; - int _parentState = _ctx.s; + int _parentState = getState(); _localctx = new (_ctx, _parentState}>); _prevctx = _localctx; int _startState = ; @@ -602,9 +602,9 @@ StructDecl(struct,attrs,getters,dispatchMethods,interfaces,extensionMembers, public static class extends implements { }; separator="\n"> }; separator="\n"> - public (ParserRuleContext parent, int state) { super(parent, state); } - public (ParserRuleContext parent, int state}>) { - super(parent, state); + public (ParserRuleContext parent, int invokingState) { super(parent, invokingState); } + public (ParserRuleContext parent, int invokingState}>) { + super(parent, invokingState); = ;}; separator="\n"> } @Override public int getRuleIndex() { return RULE_; }