1 18 19 package org.sablecc.sablecc.automaton; 20 21 import java.util.Collections ; 22 import java.util.LinkedHashMap ; 23 import java.util.LinkedHashSet ; 24 import java.util.Map ; 25 import java.util.Set ; 26 import java.util.SortedMap ; 27 import java.util.TreeMap ; 28 29 import org.sablecc.sablecc.alphabet.Symbol; 30 import org.sablecc.sablecc.exception.InternalException; 31 32 36 class Group<T extends Comparable <? super T>> { 37 38 39 private final Partition<T> partition; 40 41 42 private final Set <Element<T>> elements = new LinkedHashSet <Element<T>>(); 43 44 45 private MinimalDfaState<T> state; 46 47 48 private final SortedMap <Symbol<T>, Group<T>> transitions = new TreeMap <Symbol<T>, Group<T>>(); 49 50 59 Group( 60 final Partition<T> partition) { 61 62 if (partition == null) { 63 throw new InternalException("partition may not be null"); 64 } 65 66 this.partition = partition; 67 68 this.partition.addGroup(this); 69 } 70 71 76 Partition<T> getPartition() { 77 78 return this.partition; 79 } 80 81 86 Set <Element<T>> getElements() { 87 88 return Collections.unmodifiableSet(this.elements); 89 } 90 91 96 MinimalDfaState<T> getState() { 97 98 return this.state; 99 } 100 101 106 SortedMap <Symbol<T>, Group<T>> getTransitions() { 107 108 return Collections.unmodifiableSortedMap(this.transitions); 109 } 110 111 116 @Override 117 public String toString() { 118 119 StringBuilder sb = new StringBuilder (); 120 sb.append("Group: {"); 121 for (Element<T> element : this.elements) { 122 sb.append(element.getState()); 123 sb.append(","); 124 } 125 sb.append("}"); 126 127 return sb.toString(); 128 } 129 130 136 void setState( 137 MinimalDfaState<T> state) { 138 139 this.state = state; 140 } 141 142 152 void addElement( 153 Element<T> element) { 154 155 if (element == null) { 156 throw new InternalException("element may not be null"); 157 } 158 159 if (element.getGroup() != this) { 160 throw new InternalException("invalid element"); 161 } 162 163 if (!this.elements.add(element)) { 164 throw new InternalException("element is already in this group"); 165 } 166 } 167 168 178 void removeElement( 179 Element<T> element) { 180 181 if (element == null) { 182 throw new InternalException("element may not be null"); 183 } 184 185 if (!this.elements.remove(element)) { 186 throw new InternalException("element is not in this group"); 187 } 188 } 189 190 203 void addTransition( 204 Symbol<T> symbol, 205 Group<T> group) { 206 207 if (symbol == null) { 208 throw new InternalException("symbol may not be null"); 209 } 210 211 if (group == null) { 212 throw new InternalException("group may not be null"); 213 } 214 215 if (this.transitions.containsKey(symbol) 216 && !this.transitions.get(symbol).equals(group)) { 217 throw new InternalException( 218 "distinct transitions on a single symbol are not allowed"); 219 } 220 221 this.transitions.put(symbol, group); 222 } 223 224 230 void refine() { 231 232 for (Symbol<T> symbol : this.partition.getDfa().getAlphabet() 233 .getSymbols()) { 234 235 Map <Group<T>, Element<T>> targetToRepresentative = new LinkedHashMap <Group<T>, Element<T>>(); 238 Map <Element<T>, Element<T>> elementToRepresentative = new LinkedHashMap <Element<T>, Element<T>>(); 239 240 for (Element<T> element : this.elements) { 241 Group<T> target = element.getTarget(symbol); 242 243 Element<T> representative = targetToRepresentative.get(target); 244 245 if (representative == null) { 246 representative = element; 247 targetToRepresentative.put(target, representative); 248 } 249 250 elementToRepresentative.put(element, representative); 251 } 252 253 if (targetToRepresentative.isEmpty()) { 254 throw new InternalException("corruption detected"); 255 } 256 257 if (targetToRepresentative.size() > 1) { 259 260 boolean first = true; 262 for (Map.Entry <Group<T>, Element<T>> entry : targetToRepresentative 263 .entrySet()) { 264 if (first) { 265 first = false; 267 } 268 else { 269 entry.getValue().setGroup(new Group<T>(this.partition)); 270 } 271 } 272 273 275 for (Element<T> element : new LinkedHashSet <Element<T>>( 278 this.elements)) { 279 element.setGroup(elementToRepresentative.get(element) 281 .getGroup()); 282 } 283 284 break; 285 } 286 } 287 } 288 } 289 | Popular Tags |