1 package ro.infoiasi.donald.compiler.lexer; 2 3 import ro.infoiasi.donald.compiler.lexer.exceptions.*; 4 import java.util.*; 5 6 7 public class DFA implements Cloneable { 8 9 private int stateNo; 10 11 private int startState; 12 13 private Alphabet alpha; 14 15 private int delta[][]; 16 17 private HashSet accept; 18 19 20 public DFA() { 21 stateNo = 0; 22 } 23 24 25 public DFA(DFA d) { 26 stateNo = d.stateNo; 27 if (!isEmpty()) { 28 startState = d.startState; 29 alpha = (Alphabet)d.alpha.clone(); 30 delta = (int[][])d.delta.clone(); 31 accept = (HashSet)d.accept.clone(); 32 } 33 } 34 35 36 public DFA(int stateNo, int startState, Alphabet alpha, int delta[][], int finalStates[]) 37 throws InvalidStateNo, InvalidState, InvalidDelta { 38 39 if (stateNo<=0) { 41 throw new InvalidStateNo(); 42 } 43 this.stateNo = stateNo; 44 45 if (startState<0 || startState>=stateNo) { 47 throw new InvalidState("startState: "+startState); 48 } 49 this.startState = startState; 50 51 this.alpha = (Alphabet)alpha.clone(); 53 54 if (delta.length != stateNo) { 56 throw new InvalidDelta("delta.length: "+delta.length); 57 } 58 for (int i = 0; i<stateNo; i++) { 59 if (delta[i].length != alpha.size()) { 60 throw new InvalidDelta("delta["+i+"].length: "+delta[i].length); 61 } 62 for (int j = 0; j<alpha.size(); j++) { 63 if (delta[i][j]<0 || delta[i][j]>=stateNo) { 64 throw new InvalidDelta("delta[i][j]: "+delta[i][j]); 65 } 66 } 67 } 68 this.delta = (int[][])delta.clone(); 69 70 accept = new HashSet(); 72 for (int i = 0; i<finalStates.length; i++) { 73 if (finalStates[i]<0 || finalStates[i]>=stateNo) { 74 throw new InvalidState("start: "+finalStates[i]); 75 } 76 accept.add(new Integer (finalStates[i])); 77 } 78 } 79 80 81 private class DFAstate { 82 private HashSet set; private int delta[]; public DFAstate(HashSet set) { 85 this.set = set; 86 delta = new int[alpha.size()]; 87 } 89 void setDelta(int i, int j) { delta[i] = j; } 90 public String toString() { 91 StringBuffer sb = new StringBuffer (); 92 sb.append("set: "+set+" "); 93 sb.append("delta: ["); 94 for (int i = 0; i<alpha.size(); i++) { 95 sb.append(delta[i]+","); 96 } 97 sb.append("]"); 98 return new String (sb); 99 } 100 } 101 102 103 private class States { 104 105 private ArrayList arrList; 106 107 private HashMap setMap; 108 public States() { 109 arrList = new ArrayList(); 110 setMap = new HashMap(); 111 } 113 public int add(HashSet set, boolean isFinal) { 114 if (!setMap.containsKey(set)) { 115 Integer size = new Integer (arrList.size()); 116 if (isFinal) { 117 accept.add(size); 118 } 119 DFAstate state = new DFAstate(set); 120 arrList.add(state); 121 setMap.put(set, size); 122 return size.intValue(); 124 } else { 125 return ((Integer )setMap.get(set)).intValue(); 126 } 127 } 128 public int size() { return arrList.size(); } 129 DFAstate getState(int i) { 130 return (DFAstate)arrList.get(i); 131 } 132 public String toString() { 133 return "arrList: "+arrList+" setMap: "+setMap; 134 } 135 } 136 137 138 public DFA(RTS r) { 139 if (r.isEmpty()) { 140 stateNo = 0; return; 142 } 143 try { 144 accept = new HashSet(); 145 alpha = r.getAlphabet(); 146 147 States s = new States(); 148 s.add(new HashSet(), false); boolean isFinal; 150 HashSet set = new HashSet(); 151 isFinal = r.lambda(r.getStartState(), set); 152 s.add(set, isFinal); 154 int i = 1; 155 while (i<s.size()) { 156 DFAstate q = s.getState(i); 157 for (int j = 0; j<alpha.size(); j++) { 158 char ch = alpha.getSymbol(j).charValue(); 159 set = new HashSet(); 160 Iterator itQ = q.set.iterator(); 161 while (itQ.hasNext()) { 162 int rState = ((Integer )itQ.next()).intValue(); 163 Character chObj = r.getStateSymbol(rState); 164 if (chObj != null && chObj.charValue() == ch) { 165 set.add(r.getNext1State(rState)); 166 } 167 } 168 if (!set.isEmpty()) { 169 HashSet newSet = new HashSet(); 170 isFinal = false; 171 Iterator itS = set.iterator(); 172 while (itS.hasNext()) { 173 int rState = ((Integer )itS.next()).intValue(); 174 HashSet auxSet = new HashSet(); 175 if (r.lambda(rState, auxSet)) { 176 isFinal = true; 177 } 178 Iterator itA = auxSet.iterator(); 179 while (itA.hasNext()) { 180 newSet.add(itA.next()); 181 } 182 } 183 int k = s.add(newSet, isFinal); 184 q.setDelta(j, k); 185 } 186 } 187 i++; 188 } 189 190 192 stateNo = s.size(); 193 startState = 1; 194 delta = new int[stateNo][]; 195 for (int k = 0; k<stateNo; k++) { 196 delta[k] = s.getState(k).delta; 197 } 198 } catch(Exception e) { 199 System.out.println("Exception: "+e); 200 System.out.println("Message: "+e.getMessage()); 201 e.printStackTrace(); 202 System.exit(-1); 203 } 204 } 205 206 207 public Object clone() { 208 return new DFA(this); 209 } 210 211 212 public boolean isEmpty() { 213 return (stateNo == 0); 214 } 215 216 217 public int getStateNo() { 218 return stateNo; 219 } 220 221 222 public Integer getStartState() { 223 if (!isEmpty()) { 224 return new Integer (startState); 225 } else { 226 return null; 227 } 228 } 229 230 231 public Alphabet getAlphabet() { 232 if (!isEmpty()) { 233 return (Alphabet)alpha.clone(); 234 } else { 235 return null; 236 } 237 } 238 239 240 public int[][] getDelta() { 241 if (!isEmpty()) { 242 return (int[][])delta.clone(); 243 } else { 244 return null; 245 } 246 } 247 248 249 public Set getFinalStates() { 250 if (!isEmpty()) { 251 return accept; 252 } else { 253 return null; 254 } 255 } 256 257 258 public boolean acceptsString(String str) throws SymbolNotInAlphabet { 259 if (isEmpty()) { 260 return false; 261 } 262 int state = startState; 263 for (int i = 0; i<str.length(); i++) { 264 char ch = str.charAt(i); 265 if (!alpha.containsSymbol(ch)) { 266 throw new SymbolNotInAlphabet("symbol: "+ch); 267 } 268 int idx = alpha.idxSymbol(ch); 269 state = delta[state][idx]; 270 } 271 return accept.contains(new Integer (state)); 272 } 273 274 275 public String toString() { 276 StringBuffer sb = new StringBuffer (); 277 if (!isEmpty()) { 278 sb.append("State Number: "+stateNo); 279 sb.append("\nStart State: "+startState); 280 sb.append("\nAlphabet: "+alpha); 281 sb.append("\nDelta: {"); 282 for (int i = 0; i<stateNo; i++) { 283 sb.append("{"); 284 for (int j = 0; j<alpha.size(); j++) { 285 sb.append(delta[i][j]+","); 286 } 287 sb.append("},"); 288 } 289 sb.append("}\nAccepting States: "+accept); 290 } else { 291 sb.append("Empty DFA"); 292 } 293 return new String (sb); 294 } 295 296 297 public void print() { 298 System.out.println(""+toString()); 299 } 300 } 301 | Popular Tags |