in jflex/src/main/java/jflex/core/NFA.java [708:779]
private void removeDead(int start, int end) {
if (Build.DEBUG) {
Out.debug("removeDead (" + start + "," + end + ") " + Out.NL + this);
}
StateSet notvisited = tempStateSet;
StateSet reachable = new StateSet(numStates, start);
notvisited.clear();
notvisited.addState(start);
while (notvisited.containsElements()) {
int state = notvisited.getAndRemoveElement();
notvisited.add(reachable.complement(epsilon[state]));
reachable.add(epsilon[state]);
for (int i = 0; i < numInput; i++) {
notvisited.add(reachable.complement(table[state][i]));
reachable.add(table[state][i]);
}
}
if (Build.DEBUG) {
Out.debug("reachable states " + reachable);
}
StateSet live = new StateSet(numStates, end);
boolean changed = true;
// compute all live states
while (changed) {
changed = false;
Out.debug("live: " + live);
StateSet complement = live.complement(reachable);
if (complement == null) throw new GeneratorException(new NullPointerException(), true);
for (int s : complement) {
for (int i = 0; i < numInput; i++) {
if (table[s][i] != null) {
for (int state : table[s][i]) {
if (live.hasElement(state)) {
changed = true;
live.addState(s);
}
}
}
}
if (epsilon[s] != null) {
for (int state : epsilon[s]) {
if (live.hasElement(state)) {
changed = true;
live.addState(s);
}
}
}
}
}
if (Build.DEBUG) {
Out.debug("live states: " + live);
}
// now remove all transitions to non-live states (unless everything is live)
if (!reachable.equals(live)) {
for (int s : reachable) {
for (int i = 0; i < numInput; i++) if (table[s][i] != null) table[s][i].intersect(live);
if (epsilon[s] != null) epsilon[s].intersect(live);
}
}
if (Build.DEBUG) {
Out.debug("Removed dead states " + Out.NL + this);
}
}