diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNSimulator.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNSimulator.java index 39a3c3833..205a0244b 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNSimulator.java @@ -41,8 +41,6 @@ import java.util.IdentityHashMap; import java.util.List; public abstract class ATNSimulator { - public static final int SERIALIZED_NON_GREEDY_MASK = 0x8000; - public static final int SERIALIZED_STATE_TYPE_MASK = 0x7FFF; /** Must distinguish between missing edge and edge we know leads nowhere */ @NotNull @@ -117,12 +115,7 @@ public abstract class ATNSimulator { continue; } - boolean nonGreedy = (stype & SERIALIZED_NON_GREEDY_MASK) != 0; - stype &= SERIALIZED_STATE_TYPE_MASK; ATNState s = stateFactory(stype, i); - if (s instanceof DecisionState) { - ((DecisionState)s).nonGreedy = nonGreedy; - } s.ruleIndex = toInt(data[p++]); if ( stype == ATNState.LOOP_END ) { // special case int loopBackStateNumber = toInt(data[p++]); @@ -144,6 +137,12 @@ public abstract class ATNSimulator { pair.a.endState = (BlockEndState)atn.states.get(pair.b); } + int numNonGreedyStates = toInt(data[p++]); + for (int i = 0; i < numNonGreedyStates; i++) { + int stateNumber = toInt(data[p++]); + ((DecisionState)atn.states.get(stateNumber)).nonGreedy = true; + } + // // RULES // diff --git a/tool/src/org/antlr/v4/automata/ATNSerializer.java b/tool/src/org/antlr/v4/automata/ATNSerializer.java index 80cbda454..4445d100c 100644 --- a/tool/src/org/antlr/v4/automata/ATNSerializer.java +++ b/tool/src/org/antlr/v4/automata/ATNSerializer.java @@ -95,6 +95,7 @@ public class ATNSerializer { int nedges = 0; // dump states, count edges and collect sets while doing so + IntegerList nonGreedyStates = new IntegerList(); data.add(atn.states.size()); for (ATNState s : atn.states) { if ( s==null ) { // might be optimized away @@ -102,12 +103,11 @@ public class ATNSerializer { continue; } - // encode the nongreedy bit with the state type int stateType = s.getStateType(); - assert stateType >= 0; if (s instanceof DecisionState && ((DecisionState)s).nonGreedy) { - stateType |= ATNSimulator.SERIALIZED_NON_GREEDY_MASK; + nonGreedyStates.add(s.stateNumber); } + data.add(stateType); data.add(s.ruleIndex); if ( s.getStateType() == ATNState.LOOP_END ) { @@ -132,6 +132,12 @@ public class ATNSerializer { } } + // non-greedy states + data.add(nonGreedyStates.size()); + for (int i = 0; i < nonGreedyStates.size(); i++) { + data.add(nonGreedyStates.get(i)); + } + int nrules = atn.ruleToStartState.length; data.add(nrules); for (int r=0; r