1 18 19 package org.sablecc.sablecc.automaton; 20 21 import java.util.Collections ; 22 import java.util.SortedMap ; 23 import java.util.TreeMap ; 24 25 import org.sablecc.sablecc.alphabet.Symbol; 26 import org.sablecc.sablecc.exception.InternalException; 27 28 33 public final class DfaState<T extends Comparable <? super T>> 34 implements Comparable <DfaState<T>> { 35 36 37 private final Dfa<T> dfa; 38 39 40 private final int id; 41 42 43 private SortedMap <Symbol<T>, DfaState<T>> transitions; 44 45 46 private boolean isStable; 47 48 52 private String toString; 53 54 62 DfaState( 63 Dfa<T> dfa) { 64 65 if (dfa == null) { 66 throw new InternalException("dfa may not be null"); 67 } 68 69 this.dfa = dfa; 70 71 this.id = dfa.getNextStateId(); 72 dfa.addState(this); 73 74 this.transitions = new TreeMap <Symbol<T>, DfaState<T>>(); 75 76 this.isStable = false; 77 } 78 79 84 public Dfa<T> getDfa() { 85 86 return this.dfa; 87 } 88 89 94 public int getId() { 95 96 return this.id; 97 } 98 99 106 public SortedMap <Symbol<T>, DfaState<T>> getTransitions() { 107 108 if (!this.isStable) { 109 throw new InternalException("the state is not stable yet"); 110 } 111 112 return this.transitions; 113 } 114 115 120 SortedMap <Symbol<T>, DfaState<T>> getUnstableTransitions() { 121 122 return this.transitions; 123 } 124 125 139 public DfaState<T> getTarget( 140 Symbol<T> symbol) { 141 142 if (!this.isStable) { 143 throw new InternalException("the state is not stable yet"); 144 } 145 146 if (symbol == null) { 147 throw new InternalException("symbol may not be null"); 148 } 149 150 if (!this.dfa.getAlphabet().getSymbols().contains(symbol)) { 151 throw new InternalException("invalid symbol"); 152 } 153 154 DfaState<T> target = this.transitions.get(symbol); 155 156 if (target == null) { 157 target = this.dfa.getDeadEndState(); 158 } 159 160 return target; 161 } 162 163 172 @Override 173 public boolean equals( 174 Object obj) { 175 176 if (this == obj) { 177 return true; 178 } 179 180 if (obj == null) { 181 return false; 182 } 183 184 if (getClass() != obj.getClass()) { 185 return false; 186 } 187 188 DfaState nfaState = (DfaState) obj; 189 190 return this.id == nfaState.id; 191 } 192 193 199 @Override 200 public int hashCode() { 201 202 return this.id; 203 } 204 205 210 @Override 211 public String toString() { 212 213 if (this.toString == null) { 214 this.toString = "dfaState" + this.id; 215 } 216 217 return this.toString; 218 } 219 220 230 public int compareTo( 231 DfaState<T> dfaState) { 232 233 if (this.dfa != dfaState.dfa) { 234 throw new InternalException( 235 "cannot compare states from distinct DFAs"); 236 } 237 238 return this.id - dfaState.id; 239 } 240 241 256 void addTransition( 257 Symbol<T> symbol, 258 DfaState<T> dfaState) { 259 260 if (this.isStable) { 261 throw new InternalException("a stable state may not be modified"); 262 } 263 264 if (symbol == null) { 265 throw new InternalException("symbol may not be null"); 266 } 267 268 if (dfaState == null) { 269 throw new InternalException("dfaState may not be null"); 270 } 271 272 if (!this.dfa.getAlphabet().getSymbols().contains(symbol)) { 273 throw new InternalException("invalid symbol"); 274 } 275 276 if (this.dfa != dfaState.dfa) { 277 throw new InternalException("invalid dfaState"); 278 } 279 280 if (dfaState == this.dfa.getUnstableDeadEndState()) { 281 if (this.transitions.get(symbol) != null) { 283 throw new InternalException("target was already set"); 284 } 285 } 286 else if (this.transitions.put(symbol, dfaState) != null) { 287 throw new InternalException("target was already set"); 288 } 289 } 290 291 297 void removeTransitions() { 298 299 if (this.isStable) { 300 throw new InternalException("a stable state may not be modified"); 301 } 302 303 this.transitions.clear(); 304 } 305 306 312 void stabilize() { 313 314 if (this.isStable) { 315 throw new InternalException("state is already stable"); 316 } 317 318 this.transitions = Collections.unmodifiableSortedMap(this.transitions); 319 320 this.isStable = true; 321 } 322 } 323 | Popular Tags |