Use separate lists in the serialized ATN for non-greedy states (cleaner, allows ATNs with twice as many states), resolves antlr/antlr4#96
This commit is contained in:
parent
064501967e
commit
886baaf773
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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<nrules; r++) {
|
||||
|
@ -248,7 +254,6 @@ public class ATNSerializer {
|
|||
for (int i=1; i<=nstates; i++) {
|
||||
int stype = ATNSimulator.toInt(data[p++]);
|
||||
if ( stype==ATNState.INVALID_TYPE ) continue; // ignore bad type of states
|
||||
stype = stype & ATNSimulator.SERIALIZED_STATE_TYPE_MASK;
|
||||
int ruleIndex = ATNSimulator.toInt(data[p++]);
|
||||
String arg = "";
|
||||
if ( stype == ATNState.LOOP_END ) {
|
||||
|
@ -263,6 +268,10 @@ public class ATNSerializer {
|
|||
.append(ATNState.serializationNames.get(stype)).append(" ")
|
||||
.append(ruleIndex).append(arg).append("\n");
|
||||
}
|
||||
int numNonGreedyStates = ATNSimulator.toInt(data[p++]);
|
||||
for (int i = 0; i < numNonGreedyStates; i++) {
|
||||
int stateNumber = ATNSimulator.toInt(data[p++]);
|
||||
}
|
||||
int nrules = ATNSimulator.toInt(data[p++]);
|
||||
for (int i=0; i<nrules; i++) {
|
||||
int s = ATNSimulator.toInt(data[p++]);
|
||||
|
|
Loading…
Reference in New Issue