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 31 public final class MinimalDfaState<T extends Comparable <? super T>> 32 implements Comparable <MinimalDfaState<T>> { 33 34 35 private final MinimalDfa<T> minimalDfa; 36 37 38 private final int id; 39 40 44 private SortedMap <Symbol<T>, MinimalDfaState<T>> transitions; 45 46 47 private boolean isStable; 48 49 53 private String toString; 54 55 64 MinimalDfaState( 65 MinimalDfa<T> minimalDfa) { 66 67 if (minimalDfa == null) { 68 throw new InternalException("minimalDfa may not be null"); 69 } 70 71 this.minimalDfa = minimalDfa; 72 73 this.id = minimalDfa.getNextStateId(); 74 minimalDfa.addState(this); 75 76 this.transitions = new TreeMap <Symbol<T>, MinimalDfaState<T>>(); 77 78 this.isStable = false; 79 } 80 81 86 public MinimalDfa<T> getMinimalDfa() { 87 88 return this.minimalDfa; 89 } 90 91 96 public int getId() { 97 98 return this.id; 99 } 100 101 108 public SortedMap <Symbol<T>, MinimalDfaState<T>> getTransitions() { 109 110 if (!this.isStable) { 111 throw new InternalException("the state is not stable yet"); 112 } 113 114 return this.transitions; 115 } 116 117 128 public MinimalDfaState<T> getTarget( 129 Symbol<T> symbol) { 130 131 if (!this.isStable) { 132 throw new InternalException("the state is not stable yet"); 133 } 134 135 if (symbol == null) { 136 throw new InternalException("symbol may not be null"); 137 } 138 139 if (!this.minimalDfa.getAlphabet().getSymbols().contains(symbol)) { 140 throw new InternalException("invalid symbol"); 141 } 142 143 MinimalDfaState<T> target = this.transitions.get(symbol); 144 145 if (target == null) { 146 target = this.minimalDfa.getDeadEndState(); 147 } 148 149 return target; 150 } 151 152 162 @Override 163 public boolean equals( 164 Object obj) { 165 166 if (this == obj) { 167 return true; 168 } 169 170 if (obj == null) { 171 return false; 172 } 173 174 if (getClass() != obj.getClass()) { 175 return false; 176 } 177 178 MinimalDfaState nfaState = (MinimalDfaState) obj; 179 180 return this.id == nfaState.id; 181 } 182 183 188 @Override 189 public int hashCode() { 190 191 return this.id; 192 } 193 194 199 @Override 200 public String toString() { 201 202 if (this.toString == null) { 203 this.toString = "dfaState" + this.id; 204 } 205 206 return this.toString; 207 } 208 209 222 public int compareTo( 223 MinimalDfaState<T> minimalDfaState) { 224 225 if (this.minimalDfa != minimalDfaState.minimalDfa) { 226 throw new InternalException( 227 "cannot compare states from distinct MinimalDFAs"); 228 } 229 230 return this.id - minimalDfaState.id; 231 } 232 233 247 void addTransition( 248 Symbol<T> symbol, 249 MinimalDfaState<T> minimalDfaState) { 250 251 if (this.isStable) { 252 throw new InternalException("a stable state may not be modified"); 253 } 254 255 if (symbol == null) { 256 throw new InternalException("symbol may not be null"); 257 } 258 259 if (minimalDfaState == null) { 260 throw new InternalException("minimalDfaState may not be null"); 261 } 262 263 if (!this.minimalDfa.getAlphabet().getSymbols().contains(symbol)) { 264 throw new InternalException("invalid symbol"); 265 } 266 267 if (this.minimalDfa != minimalDfaState.minimalDfa) { 268 throw new InternalException("invalid dfaState"); 269 } 270 271 if (minimalDfaState == this.minimalDfa.getUnstableDeadEndState()) { 272 if (this.transitions.get(symbol) != null) { 274 throw new InternalException("target was already set"); 275 } 276 } 277 else if (this.transitions.put(symbol, minimalDfaState) != null) { 278 throw new InternalException("target was already set"); 279 } 280 } 281 282 288 void stabilize() { 289 290 if (this.isStable) { 291 throw new InternalException("state is already stable"); 292 } 293 294 this.transitions = Collections.unmodifiableSortedMap(this.transitions); 295 296 this.isStable = true; 297 } 298 } 299 | Popular Tags |