1 package com.tc.jrexx.set; 2 3 25 import java.io.*; 26 import java.util.*; 27 28 32 public class DFASet { 33 34 protected static class State { 35 protected static class Transition { 36 protected final CharSet charSet; 37 protected final int toState; 38 39 protected Transition(CharSet charSet,int toState) { 40 this.charSet = charSet; 41 this.toState = toState; 42 } 43 } 44 45 protected final boolean isFinal; 46 protected final Transition[] transitions; 47 48 protected State(boolean isFinal,Transition[] transitions) { 49 this.isFinal = isFinal; 50 this.transitions = transitions; 51 } 52 } 53 54 protected final State[] states; 55 protected final Integer startState; 56 57 protected DFASet(State[] states,Integer startState) { 58 this.states = states; 59 this.startState = startState; 60 } 61 62 public DFASet(FSAData automaton) { 63 if (automaton==null) throw new IllegalArgumentException ("automaton==null"); 64 65 HashMap map = new HashMap(); 66 67 State[] newStates = 68 new State[automaton.states==null ? 0 : automaton.states.length]; 69 70 for (int i=0; i<newStates.length; ++i) { 71 FSAData.State state = automaton.states[i]; 72 if (state==null) throw new IllegalArgumentException ((i+1)+". state of automaton is null"); 73 74 State.Transition[] newTransitions = 75 new State.Transition[state.transitions==null ? 0 : state.transitions.length]; 76 77 for (int t=0; t<newTransitions.length; ++t) { 78 FSAData.State.Transition trans = state.transitions[t]; 79 if (trans==null) throw new IllegalArgumentException ((t+1)+". transition of state "+state.number+" is null"); 80 if (trans.charSet==null) throw new IllegalArgumentException ("charSet of "+(t+1)+". transition of state "+state.number+" is null"); 81 82 CharSet newCharSet = (CharSet)map.get(trans.charSet); 83 if (newCharSet==null) { 84 newCharSet = new CharSet(trans.charSet); 85 map.put(trans.charSet,newCharSet); 86 } 87 88 int toStateNr = 0; 89 try { 90 while(automaton.states[toStateNr].number!=trans.toStateNumber) ++toStateNr; 91 } catch(ArrayIndexOutOfBoundsException e) { 92 throw new IllegalArgumentException ( 93 "toState "+trans.toStateNumber+" of "+(t+1)+". transition of state "+state.number+" does not exist" 94 ); 95 } 96 97 newTransitions[t] = new State.Transition(newCharSet,toStateNr); 98 } 99 100 newStates[i] = new State(state.isFinal,newTransitions); 101 } 102 103 this.states = newStates; 104 105 if (automaton.startStateNumber==null) this.startState = null; 106 else { 107 int automatonStartStateNr = automaton.startStateNumber.intValue(); 108 int startStateNr = 0; 109 try { 110 while(automaton.states[startStateNr].number!=automatonStartStateNr) ++startStateNr; 111 } catch(ArrayIndexOutOfBoundsException e) { 112 throw new IllegalArgumentException ( 113 "startState "+automaton.startStateNumber+" does not exist" 114 ); 115 } 116 this.startState = new Integer (startStateNr); 117 } 118 } 119 120 protected static FSAData toFSAData(Object obj) { 121 if (obj.getClass()!=FSAData.class) { 122 SAutomatonData data = (SAutomatonData)obj; 123 124 FSAData.State[] newStates = new FSAData.State[data.states==null ? 0 : data.states.length]; 125 for (int i=0; i<newStates.length; ++i) { 126 SAutomatonData.State state = data.states[i]; 127 if (state!=null) { 128 FSAData.State.Transition[] newTransitions = 129 new FSAData.State.Transition[state.transitions==null ? 0 : state.transitions.length]; 130 for (int t=0; t<newTransitions.length; ++t) { 131 SAutomatonData.State.Transition trans = state.transitions[t]; 132 newTransitions[t] = new FSAData.State.Transition(trans.properties,trans.charSet,trans.toStateNumber); 133 } 134 newStates[i] = new FSAData.State(state.number,state.isFinal,newTransitions,state.transitionsAreDeterministic); 135 } 136 } 137 return new FSAData(newStates,data.startStateNumber,data.isDeterministic); 138 139 } else { 140 FSAData data = (FSAData)obj; 141 switch(data.objectVersion) { 142 case FSAData.classVersion : return data; 143 default : return data; 144 } 145 } 146 } 147 148 149 public DFASet(InputStream dfaDataStream) throws IOException,ClassNotFoundException { 150 this(DFASet.toFSAData(new ObjectInputStream(dfaDataStream).readObject())); 151 } 152 153 public boolean contains(char[] chars) { 154 return this.contains(chars,0,chars.length); 155 } 156 157 public boolean contains(char[] chars,int offset) { 158 return this.contains(chars,offset,chars.length-offset); 159 } 160 161 public boolean contains(char[] chars,int offset,int length) { 162 if (this.startState==null) return false; 163 State state = this.states[this.startState.intValue()]; 164 165 loop: for (;length>0; ++offset, --length) { 166 for (int i=0; i<state.transitions.length; ++i) { 167 if (state.transitions[i].charSet.contains(chars[offset])) { 168 state = this.states[state.transitions[i].toState]; 169 continue loop; 170 } 171 } 172 return false; 173 } 174 175 return state.isFinal; 176 } 177 178 public boolean contains(String s) { 179 return this.contains(s,0,s.length()); 180 } 181 182 public boolean contains(String s,int offset) { 183 return this.contains(s,offset,s.length()-offset); 184 } 185 186 public boolean contains(String s,int offset,int length) { 187 if (this.startState==null) return false; 188 State state = this.states[this.startState.intValue()]; 189 190 loop: for (;length>0; ++offset, --length) { 191 for (int i=0; i<state.transitions.length; ++i) { 192 if (state.transitions[i].charSet.contains(s.charAt(offset))) { 193 state = this.states[state.transitions[i].toState]; 194 continue loop; 195 } 196 } 197 return false; 198 } 199 200 return state.isFinal; 201 } 202 203 204 public boolean contains(java.io.Reader in) throws java.io.IOException { 205 if (this.startState==null) return false; 206 State state = this.states[this.startState.intValue()]; 207 208 loop: for (int ch=in.read(); ch!=-1; ch=in.read()) { 209 for (int i=0; i<state.transitions.length; ++i) { 210 if (state.transitions[i].charSet.contains((char)ch)) { 211 state = this.states[state.transitions[i].toState]; 212 continue loop; 213 } 214 } 215 return false; 216 } 217 218 return state.isFinal; 219 } 220 221 } | Popular Tags |