| 1 package ro.infoiasi.donald.compiler.lexer; 2 3 import ro.infoiasi.donald.compiler.lexer.exceptions.*; 4 import ro.infoiasi.donald.compiler.simple.*; 5 import java.util.*; 6 7 16 public class RTS 17 implements Cloneable { 18 private class RTSstate { 19 21 private Integer idxSymbol; 22 23 private Integer next1; 24 25 private Integer next2; 26 public String toString() { 27 return "("+idxSymbol+","+next1+","+next2+")"; 28 } 29 } 30 31 private int stateNo; 32 33 private int startState; 34 35 private int finalState; 36 37 private Alphabet alpha; 38 39 private RTSstate states[]; 40 41 42 public RTS() { 43 stateNo = 0; 44 } 45 46 47 public RTS(RTS r) { 48 stateNo = r.stateNo; 49 if (!isEmpty()) { 50 startState = r.startState; 51 finalState = r.finalState; 52 alpha = (Alphabet)r.alpha.clone(); 53 states = (RTSstate[])r.states.clone(); 54 } 55 } 56 57 58 public RTS(int stateNo, int startState, int finalState, String strAlpha, 59 Character symbol[], Integer next1[], Integer next2[]) 60 throws InvalidStateNo, InvalidState, SymbolNotInAlphabet { 61 62 if (stateNo<=0) { 64 throw new InvalidStateNo("stateNo: "+stateNo); 65 } 66 this.stateNo = stateNo; 67 68 if (startState<0 || startState>=stateNo) { 70 throw new InvalidState("startState: "+startState); 71 } 72 this.startState = startState; 73 74 if (finalState<0 || finalState>=stateNo) { 76 throw new InvalidState("finalState: "+finalState); 77 } 78 this.finalState = finalState; 79 80 this.alpha = new Alphabet(strAlpha); 82 83 states = new RTSstate[stateNo]; 85 for (int i = 0; i<stateNo; i++) { 86 states[i] = new RTSstate(); 87 if (symbol[i] == null) { 88 states[i].idxSymbol = null; 89 if (next1[i] == null) { 90 if (next2[i] != null || finalState != i) { 91 throw new InvalidState("state: "+i); 92 } 93 states[i].next1 = states[i].next2 = null; 95 } else { 96 if (next2[i] == null) { 97 if (next1[i].intValue()<0 || 98 next1[i].intValue()>=stateNo) { 99 throw new InvalidState("state: "+i); 100 } 101 states[i].next1 = next1[i]; 103 states[i].next2 = null; 104 } else { 105 if (next1[i].intValue()<0 || 106 next1[i].intValue()>=stateNo || 107 next2[i].intValue()<0 || 108 next2[i].intValue()>=stateNo ) { 109 throw new InvalidState("state: "+i); 110 } 111 states[i].next1 = next1[i]; 113 states[i].next2 = next2[i]; 114 } 115 } 116 } else { 117 if (!alpha.containsSymbol(symbol[i].charValue())) { 118 throw new SymbolNotInAlphabet("symbol: "+symbol[i]); 119 } 120 if (next1[i] == null || 121 next1[i].intValue()<0 || 122 next1[i].intValue()>=stateNo || 123 next2[i] != null) { 124 throw new InvalidState("state: "+i); 125 } 126 char ch = symbol[i].charValue(); 128 if (!alpha.containsSymbol(ch)) { 129 throw new SymbolNotInAlphabet("symbol: "+symbol[i]); 130 } 131 states[i].idxSymbol = new Integer (alpha.idxSymbol(ch)); 132 states[i].next1 = next1[i]; 133 states[i].next2 = null; 134 } 135 } 136 } 137 138 139 140 public RTS(ExpTree et) throws SymbolNotInAlphabet { 141 alpha = et.getAlphabet(); 142 143 class Label { 145 int start; 146 int end; 147 Label(int start, int end) { this.start = start; this.end = end; } 148 } 149 HashMap map = new HashMap(); 150 int labelNo = 0; 151 Iterator it = et.postIterator(); 152 while (it.hasNext()) { 153 BinTreeNode node = (BinTreeNode)(it.next()); 154 boolean concat = false; 155 if (node.get().getClass() == OperatorToken.class) { 156 Operator op = ((OperatorToken)(node.get())).operator(); 157 if (op == Operator.CONCAT) { 158 Label leftLabel = (Label)map.get(node.left()); 159 Label rightLabel = (Label)map.get(node.right()); 160 map.put(node, new Label(leftLabel.start, rightLabel.end)); 161 concat = true; 162 } 163 } 164 if (!concat) { 165 map.put(node, new Label(labelNo, labelNo+1)); 166 labelNo += 2; 167 } 168 } 169 170 stateNo = labelNo; 171 states = new RTSstate[stateNo]; 172 for (int i = 0; i<stateNo; i++) { 173 states[i] = new RTSstate(); 174 } 175 Label rootLabel = (Label)map.get(et.root()); 176 startState = rootLabel.start; 177 finalState = rootLabel.end; 178 179 180 it = et.preIterator(); 181 while (it.hasNext()) { 182 BinTreeNode node = (BinTreeNode)(it.next()); 183 Label nodeLabel = (Label)(map.remove(node)); 184 ExpToken token = (ExpToken)node.get(); 185 if (token.getClass() == OperatorToken.class) { 186 Operator op = ((OperatorToken)token).operator(); 187 if (op.isBinary()) { 188 Label leftLabel = (Label)map.get(node.left()); 189 Label rightLabel = (Label)map.get(node.right()); 190 if (op == Operator.CONCAT) { 191 states[leftLabel.end].next1 = new Integer (rightLabel.start); 192 } else if (op == Operator.UNION) { 193 states[nodeLabel.start].next1 = new Integer (leftLabel.start); 194 states[nodeLabel.start].next2 = new Integer (rightLabel.start); 195 states[leftLabel.end].next1 = states[rightLabel.end].next1 196 = new Integer (nodeLabel.end); 197 } else { 198 System.err.println("ExpTree contains unknown binary operator\n"); } 200 } else { Label leftLabel = (Label)map.get(node.left()); 202 if (op == Operator.ITARAT) { 203 states[nodeLabel.start].next1 = states[leftLabel.end].next1 204 = new Integer (leftLabel.start); 205 states[nodeLabel.start].next2 = states[leftLabel.end].next2 206 = new Integer (nodeLabel.end); 207 } else { 208 System.err.println("ExpTree contains unknown unary operator\n"); } 210 } 211 } else if (token.getClass() == SymbolToken.class) { 212 states[nodeLabel.start].next1 = new Integer (nodeLabel.end); 213 states[nodeLabel.start].idxSymbol = 214 new Integer (alpha.idxSymbol(((SymbolToken)token).getChar())); 215 } else { 216 System.err.println("ExpTree contains unknown entity\n"); } 218 } 219 } 220 221 222 public Object clone() { 223 return new RTS(this); 224 } 225 226 227 public boolean isEmpty() { 228 return (stateNo == 0); 229 } 230 231 232 public int getStateNo() { 233 return stateNo; 234 } 235 236 237 public int getStartState() throws EmptyRTS { 238 if (!isEmpty()) { 239 return startState; 240 } else { 241 throw new EmptyRTS(); 242 } 243 } 244 245 246 public Integer getFinalState() throws EmptyRTS { 247 if (!isEmpty()) { 248 return new Integer (finalState); 249 } else { 250 throw new EmptyRTS(); 251 } 252 } 253 254 255 public Alphabet getAlphabet() throws EmptyRTS { 256 if (!isEmpty()) { 257 return (Alphabet)alpha.clone(); 258 } else { 259 throw new EmptyRTS(); 260 } 261 } 262 263 264 public Character getStateSymbol(int state) throws EmptyRTS { 265 if (!isEmpty()) { 266 Integer idx = states[state].idxSymbol; 267 if (idx == null) { 268 return null; 269 } else { 270 return alpha.getSymbol(idx.intValue()); 271 } 272 } else { 273 throw new EmptyRTS(); 274 } 275 } 276 277 278 public Integer getNext1State(int state) throws InvalidState, EmptyRTS { 279 if (!isEmpty()) { 280 if (state<0 || state>stateNo) { 281 throw new InvalidState("state:"+state); 282 } 283 return states[state].next1; 284 } else { 285 throw new EmptyRTS(); 286 } 287 } 288 289 291 public Integer getNext2State(int state) throws InvalidState, EmptyRTS { 292 if (!isEmpty()) { 293 if (state<0 || state>stateNo) { 294 throw new InvalidState("state:"+state); 295 } 296 return states[state].next2; 297 } else { 298 throw new EmptyRTS(); 299 } 300 } 301 302 308 public boolean lambda(int state, Set set) throws InvalidState, EmptyRTS { 309 if (!isEmpty()) { 310 if (state<0 || state>stateNo) { 311 throw new InvalidState("state:"+state); 312 } 313 boolean hasFinal = false; 314 if (state == finalState) { 315 hasFinal = true; 316 } 317 set.clear(); 318 ArrayList a = new ArrayList(); 319 Integer ss = new Integer (state); 320 a.add(ss); 321 set.add(ss); 322 int i = 0; 323 while (i<a.size()) { 324 int sc = ((Integer )a.get(i)).intValue(); 326 if (sc == finalState) { 327 hasFinal = true; 328 } 329 if (getStateSymbol(sc) == null) { 330 Integer s1 = getNext1State(sc); 331 if (s1 != null && !set.contains(s1)) { 332 a.add(s1); 334 set.add(s1); 335 Integer s2 = getNext2State(sc); 336 if (s2 != null && !set.contains(s2)) { 337 a.add(s2); 339 set.add(s2); 340 } 341 } 342 } 343 i++; 344 } 345 return hasFinal; 346 } else { 347 throw new EmptyRTS(); 348 } 349 } 350 351 352 public String toString() { 353 StringBuffer sb = new StringBuffer (); 354 if (!isEmpty()) { 355 sb.append("State Number: "+stateNo); 356 sb.append("\nStart State: "+startState); 357 sb.append("\nFinal State: "+finalState); 358 sb.append("\nAlphabet: "+alpha); 359 sb.append("\nState transitions:"); 360 for (int i = 0; i<stateNo; i++) { 361 sb.append("\n"+i+":"+states[i]); 362 } 363 } else { 364 sb.append("Empty RTS"); 365 } 366 return new String (sb); 367 } 368 369 370 public void print() { 371 System.out.println(""+this); 372 } 373 } 374 | Popular Tags |