diff --git a/runtime/Java/src/org/antlr/v4/runtime/Parser.java b/runtime/Java/src/org/antlr/v4/runtime/Parser.java index 49e513809..a1bf4732b 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Parser.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Parser.java @@ -377,7 +377,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); _ctx.ruleIndex = ruleIndex; @@ -388,6 +389,7 @@ public abstract class Parser extends Recognizer public void exitRule() { // trigger event on _ctx, before it reverts to parent if ( _parseListeners != null) triggerExitRuleEvent(); + setState(_ctx.invokingState); _ctx = (ParserRuleContext)_ctx.parent; } @@ -404,26 +406,30 @@ public abstract class Parser extends Recognizer } /* like enterRule but for recursive rules; no enter events for recursive rules. */ - public void pushNewRecursionContext(ParserRuleContext localctx, int ruleIndex) { + public void pushNewRecursionContext(ParserRuleContext localctx, int state, int ruleIndex) { + setState(state); _ctx = localctx; _ctx.start = _input.LT(1); _ctx.ruleIndex = ruleIndex; } - public void unrollRecursionContexts(ParserRuleContext _parentctx) { + public void unrollRecursionContexts(ParserRuleContext _parentctx, int _parentState) { ParserRuleContext retctx = _ctx; // save current ctx (return value) // unroll so _ctx is as it was before call to recursive method if ( _parseListeners != null ) { while ( _ctx != _parentctx ) { triggerExitRuleEvent(); + setState(_ctx.invokingState); _ctx = (ParserRuleContext)_ctx.parent; } } else { + setState(_parentState); _ctx = _parentctx; } // hook into tree + retctx.invokingState = _parentState; retctx.parent = _parentctx; if (_buildParseTrees) _parentctx.addChild(retctx); // add return ctx into invoking rule's tree } diff --git a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java index 8b14b05e7..d2e461cad 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java @@ -47,7 +47,7 @@ public abstract class Recognizer { protected ATNInterpreter _interp; - private int _stateNumber; + private int _stateNumber = -1; /** Used to print out token names like ID during debugging and * error reporting. The generated parsers implement a method 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 422e4ac3d..1d01a1564 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 @@ -220,8 +220,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 { @@ -254,10 +254,11 @@ LeftRecursiveRuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs, }>public final () throws RecognitionException { ParserRuleContext\ _parentctx = _ctx; - _localctx = new (_ctx, }>); + int _parentState = getState(); + _localctx = new (_ctx, _parentState}>); _prevctx = _localctx; int _startState = ; - pushNewRecursionContext(_localctx, RULE_); + pushNewRecursionContext(_localctx, , RULE_); try { @@ -275,7 +276,7 @@ LeftRecursiveRuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs, } finally { - unrollRecursionContexts(_parentctx); + unrollRecursionContexts(_parentctx, _parentState); } return _localctx; } @@ -603,9 +604,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"> } @@ -668,18 +669,18 @@ recRuleSetReturnAction(src,name) ::= "$=$.;" recRuleSetStopToken() ::= "_ctx.stop = _input.LT(-1);" recRuleAltStartAction(ruleName, ctxName, label) ::= << -_localctx = new Context(_parentctx, _startState, _p); +_localctx = new Context(_parentctx, _parentState, _p); _localctx.addChild(_prevctx); _localctx.