node2id.put(id2node[i], i);
}
final State[] basis = new State[numStates];
for(int i = 0; i < numStates; ++i) {
WrappedBitSet terminatedPatterns = new WrappedBitSet(numPatterns);
for(int pat : id2node[i].patternIds) {
terminatedPatterns.set(pat);
}
basis[i] = new IntState(i, terminatedPatterns);
}
TransferTable<Character,PowerIntState> transfer = new TransferTable<Character, PowerIntState>() {
private TransferFunction[] transfer = new TransferFunction[Character.MAX_VALUE+1];
public TransferFunction<PowerIntState> forToken(Character token) {
char t = token;
TransferFunction<PowerIntState> f = transfer[t];
if(f == null) {
transfer[t] = f = computeTransferFor(t);
}
return f;
}
private TransferFunction<PowerIntState> computeTransferFor(char token) {
WrappedBitSet[] state2next = new WrappedBitSet[numStates];
for(int i = 0; i < numStates; ++i) {
WrappedBitSet res = new WrappedBitSet(numStates);
NFA.Node node = id2node[i];
for (Pair<CharacterClass, NFA.Node> out : node.out) {
if(out.first.acceptsChar(token)) {
res.set(node2id.get(out.second));
}
}
state2next[i] = res;
}
return new PowerIntTable(state2next);
}
};
final WrappedBitSet justInitial = new WrappedBitSet(numStates);
justInitial.set(node2id.get(newInitial));
PowerIntState initial = new PowerIntState(basis, justInitial);
// StringBuilder dot = new StringBuilder();
// dot.append("digraph g {\n");
// for(int i = 0; i < numStates; ++i) {
// WrappedBitSet justThis = new WrappedBitSet(numStates);
// justThis.set(i);
// PowerIntState state = new PowerIntState(basis, justThis);
// dot.append(i + " [shape=" + (state.getTerminatedPatterns().isEmpty() ? "circle" : "square") + "]\n");
// }
// for(int i = 0; i < numStates; ++i) {
// WrappedBitSet justThis = new WrappedBitSet(numStates);
// justThis.set(i);
// PowerIntState state = new PowerIntState(basis, justThis);
// PowerIntState nextState = transfer.forToken('t').next(state);
// WrappedBitSet next = nextState.getSubset();
// for(int bit = next.nextSetBit(0); bit != -1; bit = next.nextSetBit(bit+1)) {
// dot.append(i + " -> " + bit + "\n");
// }
// }
// dot.append("}\n");
// System.out.println(dot);
return new DFA<Character, PowerIntState>(transfer, initial, PowerIntTable.REDUCER) {
@Override
public PowerIntState resetTerminatedPattern(PowerIntState state, int pattern) {
WrappedBitSet reset = new WrappedBitSet(basis.length);
reset.or(state.getSubset());
for(int substate = reset.nextSetBit(0); substate != -1; substate = reset.nextSetBit(substate + 1)) {
if(basis[substate].getTerminatedPatterns().get(pattern)) {
reset.clear(substate);
}
}
reset.or(justInitial);
return new PowerIntState(basis, reset);
}
};
}