Merge branch 'recognizer-local-state'

This commit is contained in:
Sam Harwell 2012-11-14 14:40:56 -06:00
commit 92ae0f0fa6
7 changed files with 39 additions and 44 deletions

View File

@ -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);

View File

@ -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;

View File

@ -419,7 +419,8 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator> {
* 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<Token, ParserATNSimulator> {
_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<Token, ParserATNSimulator> {
// 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<Token, ParserATNSimulator> {
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<Token, ParserATNSimulator> {
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<Token, ParserATNSimulator> {
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.
*/

View File

@ -93,13 +93,6 @@ public class ParserRuleContext extends RuleContext {
*/
// public List<Integer> 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

View File

@ -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?

View File

@ -48,6 +48,8 @@ public abstract class Recognizer<Symbol, ATNInterpreter extends ATNSimulator> {
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<Symbol, ATNInterpreter extends ATNSimulator> {
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);

View File

@ -208,8 +208,8 @@ RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAc
<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n">
<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public final <endif><currentRule.ctxType> <currentRule.name>(<currentRule.args; separator=",">) throws RecognitionException {
<currentRule.ctxType> _localctx = new <currentRule.ctxType>(_ctx, <currentRule.startState><currentRule.args:{a | , <a.name>}>);
enterRule(_localctx, RULE_<currentRule.name>);
<currentRule.ctxType> _localctx = new <currentRule.ctxType>(_ctx, getState()<currentRule.args:{a | , <a.name>}>);
enterRule(_localctx, <currentRule.startState>, RULE_<currentRule.name>);
<namedActions.init>
<locals; separator="\n">
try {
@ -246,7 +246,7 @@ LeftRecursiveRuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,
<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public final <endif><currentRule.ctxType> <currentRule.name>(<currentRule.args; separator=",">) throws RecognitionException {
ParserRuleContext _parentctx = _ctx;
int _parentState = _ctx.s;
int _parentState = getState();
<currentRule.ctxType> _localctx = new <currentRule.ctxType>(_ctx, _parentState<currentRule.args:{a | , <a.name>}>);
<currentRule.ctxType> _prevctx = _localctx;
int _startState = <currentRule.startState>;
@ -602,9 +602,9 @@ StructDecl(struct,attrs,getters,dispatchMethods,interfaces,extensionMembers,
public static class <struct.name> extends <superClass><if(interfaces)> implements <interfaces; separator=", "><endif> {
<attrs:{a | <a>}; separator="\n">
<getters:{g | <g>}; separator="\n">
<if(struct.ctorAttrs)>public <struct.name>(ParserRuleContext parent, int state) { super(parent, state); }<endif>
public <struct.name>(ParserRuleContext parent, int state<struct.ctorAttrs:{a | , <a>}>) {
super(parent, state);
<if(struct.ctorAttrs)>public <struct.name>(ParserRuleContext parent, int invokingState) { super(parent, invokingState); }<endif>
public <struct.name>(ParserRuleContext parent, int invokingState<struct.ctorAttrs:{a | , <a>}>) {
super(parent, invokingState);
<struct.ctorAttrs:{a | this.<a.name> = <a.name>;}; separator="\n">
}
@Override public int getRuleIndex() { return RULE_<struct.derivedFromName>; }