package org.simantics.scl.compiler.parser.regexp.automata; import gnu.trove.impl.Constants; import gnu.trove.list.array.TByteArrayList; import gnu.trove.list.array.TIntArrayList; import gnu.trove.map.hash.TIntIntHashMap; import gnu.trove.procedure.TIntIntProcedure; import gnu.trove.procedure.TIntProcedure; import gnu.trove.set.hash.TIntHashSet; import java.util.ArrayList; import org.simantics.scl.compiler.parser.regexp.RAtom; import org.simantics.scl.compiler.parser.regexp.Regexp; public class DFA implements Automata { private ArrayList transitions = new ArrayList(); private TByteArrayList accepts = new TByteArrayList(); private int initialState; public int newState() { int stateId = transitions.size(); transitions.add(new TIntIntHashMap( Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, 0, -1)); accepts.add((byte)0); return stateId; } public int size() { return transitions.size(); } public DFA copy() { DFA copy = new DFA(); for(TIntIntHashMap t : transitions) copy.transitions.add(new TIntIntHashMap(t)); copy.accepts = new TByteArrayList(accepts); copy.initialState = initialState; return copy; } public void addTransition(int sourceId, int symbol, int targetId) { transitions.get(sourceId).put(symbol, targetId); } public int getTransition(int sourceId, int symbol) { return transitions.get(sourceId).get(symbol); } public void forEachTransition(int source, final TIntIntProcedure proc) { transitions.get(source).forEachEntry(proc); } public int[] nextStates(int id) { return transitions.get(id).keys(); } public void setAccepts(int id, boolean accepts) { this.accepts.set(id, accepts ? (byte)1 : (byte)0); } public boolean getAccepts(int id) { return accepts.get(id)==1; } public void setInitialState(int initialState) { this.initialState = initialState; } public int getInitialState() { return initialState; } public DFA minimize() { // Compute relevant input characters for minimization final TIntIntHashMap symbolMap = new TIntIntHashMap(); final int[] symbolArray; { final TIntArrayList l = new TIntArrayList(); TIntProcedure proc = new TIntProcedure() { @Override public boolean execute(int value) { if(!symbolMap.containsKey(value)) { symbolMap.put(value, l.size()); l.add(value); } return true; } }; for(TIntIntHashMap tMap : transitions) tMap.forEachKey(proc); symbolArray = l.toArray(); } int symbolCount = symbolMap.size(); int stateCount = transitions.size(); // Inverse automata final TIntArrayList[][] inverse = new TIntArrayList[stateCount+1][]; for(int i=0;i " + inverse[i][j]); */ // int[] ids = new int[stateCount+1]; final int[] memPartion = new int[stateCount+1]; TIntArrayList partionBegin = new TIntArrayList(); TIntArrayList partionEnd = new TIntArrayList(); TIntArrayList stack = new TIntArrayList(); TIntArrayList scheduled = new TIntArrayList(); // Initial partition { int min = 0; int max = stateCount; ids[min++] = stateCount; memPartion[stateCount] = 0; for(int i=0;i=0;--n) { Regexp ss = Regexp.star(a[n][n]); b[n] = Regexp.seq(ss, b[n]); for(int j=0;j