KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > jrexx > set > DFASet


1 package com.tc.jrexx.set;
2
3 /*
4 * 01/07/2003 - 15:19:32
5 *
6 * Automaton.java -
7 * Copyright (C) 2003 Buero fuer Softwarearchitektur GbR
8 InputStream* ralf.meyer@karneim.com
9 * http://jrexx.sf.net
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */

25 import java.io.*;
26 import java.util.*;
27
28 /**
29  * DFASet is an immutable Set of strings based on a minimized deterministic automaton (DFA).
30  * @author Ralf Meyer
31  */

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 JavaDoc startState;
56
57   protected DFASet(State[] states,Integer JavaDoc startState) {
58     this.states = states;
59     this.startState = startState;
60   }
61
62   public DFASet(FSAData automaton) {
63     if (automaton==null) throw new IllegalArgumentException JavaDoc("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 JavaDoc((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 JavaDoc((t+1)+". transition of state "+state.number+" is null");
80         if (trans.charSet==null) throw new IllegalArgumentException JavaDoc("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 JavaDoc e) {
92           throw new IllegalArgumentException JavaDoc(
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 JavaDoc e) {
112         throw new IllegalArgumentException JavaDoc(
113           "startState "+automaton.startStateNumber+" does not exist"
114         );
115       }
116       this.startState = new Integer JavaDoc(startStateNr);
117     }
118   }
119
120   protected static FSAData toFSAData(Object JavaDoc 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 JavaDoc {
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 JavaDoc s) {
179     return this.contains(s,0,s.length());
180   }
181
182   public boolean contains(String JavaDoc s,int offset) {
183     return this.contains(s,offset,s.length()-offset);
184   }
185
186   public boolean contains(String JavaDoc 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 JavaDoc in) throws java.io.IOException JavaDoc {
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