1 20 21 package JFlex; 22 23 24 import java.io.*; 25 import java.util.*; 26 27 28 35 final public class DFA { 36 37 40 private static final int STATES = 500; 41 42 45 public static final int NO_TARGET = -1; 46 47 52 int [][] table; 53 54 55 59 boolean [] isFinal; 60 61 66 boolean [] isPushback; 67 68 69 73 boolean [] isLookEnd; 74 75 76 80 Action [] action; 81 82 85 int lexState []; 86 87 90 int numStates; 91 92 93 96 int numInput; 97 98 99 102 Hashtable usedActions = new Hashtable(); 103 104 public DFA(int numLexStates, int numInp) { 105 numInput = numInp; 106 107 int statesNeeded = Math.max(numLexStates, STATES); 108 109 table = new int [statesNeeded] [numInput]; 110 action = new Action [statesNeeded]; 111 isFinal = new boolean [statesNeeded]; 112 isPushback = new boolean [statesNeeded]; 113 isLookEnd = new boolean [statesNeeded]; 114 lexState = new int [numLexStates]; 115 numStates = 0; 116 117 for (int i = 0; i < statesNeeded; i++) { 118 for (char j = 0; j < numInput; j++) 119 table [i][j] = NO_TARGET; 120 } 121 } 122 123 124 public void setLexState(int lState, int trueState) { 125 lexState[lState] = trueState; 126 } 127 128 private void ensureStateCapacity(int newNumStates) { 129 int oldLength = isFinal.length; 130 131 if ( newNumStates < oldLength ) return; 132 133 int newLength = oldLength*2; 134 while ( newLength <= newNumStates ) newLength*= 2; 135 136 boolean [] newFinal = new boolean [newLength]; 137 boolean [] newPushback = new boolean [newLength]; 138 boolean [] newLookEnd = new boolean [newLength]; 139 Action [] newAction = new Action [newLength]; 140 int [] [] newTable = new int [newLength] [numInput]; 141 142 System.arraycopy(isFinal,0,newFinal,0,numStates); 143 System.arraycopy(isPushback,0,newPushback,0,numStates); 144 System.arraycopy(isLookEnd,0,newLookEnd,0,numStates); 145 System.arraycopy(action,0,newAction,0,numStates); 146 System.arraycopy(table,0,newTable,0,oldLength); 147 148 int i,j; 149 150 for (i = oldLength; i < newLength; i++) { 151 for (j = 0; j < numInput; j++) { 152 newTable[i][j] = NO_TARGET; 153 } 154 } 155 156 isFinal = newFinal; 157 isPushback = newPushback; 158 isLookEnd = newLookEnd; 159 action = newAction; 160 table = newTable; 161 } 162 163 164 public void setAction(int state, Action stateAction) { 165 action[state] = stateAction; 166 if (stateAction != null) { 167 isLookEnd[state] = stateAction.isLookAction(); 168 usedActions.put(stateAction,stateAction); 169 } 170 } 171 172 public void setFinal(int state, boolean isFinalState) { 173 isFinal[state] = isFinalState; 174 } 175 176 public void setPushback(int state, boolean isPushbackState) { 177 isPushback[state] = isPushbackState; 178 } 179 180 181 public void addTransition(int start, char input, int dest) { 182 int max = Math.max(start,dest)+1; 183 ensureStateCapacity(max); 184 if (max > numStates) numStates = max; 185 186 188 table[start][input] = dest; 189 } 190 191 192 193 public String toString() { 194 StringBuffer result = new StringBuffer (); 195 196 for (int i=0; i < numStates; i++) { 197 result.append("State "); 198 if ( isFinal[i] ) result.append("[FINAL] "); if ( isPushback[i] ) result.append("[PUSH] "); 200 result.append(i+":"+Out.NL); 201 202 for (char j=0; j < numInput; j++) { 203 if ( table[i][j] >= 0 ) 204 result.append(" with "+(int)j+" in "+table[i][j]+Out.NL); 205 } 206 } 207 208 return result.toString(); 209 } 210 211 212 public void writeDot(File file) { 213 try { 214 PrintWriter writer = new PrintWriter(new FileWriter(file)); 215 writer.println(dotFormat()); 216 writer.close(); 217 } 218 catch (IOException e) { 219 Out.error(ErrorMessages.FILE_WRITE, file); 220 throw new GeneratorException(); 221 } 222 } 223 224 225 public String dotFormat() { 226 StringBuffer result = new StringBuffer (); 227 228 result.append("digraph DFA {"+Out.NL); 229 result.append("rankdir = LR"+Out.NL); 230 231 for (int i=0; i < numStates; i++) { 232 if ( isFinal[i] || isPushback[i] ) result.append(i); 233 if ( isFinal[i] ) result.append(" [shape = doublecircle]"); 234 if ( isPushback[i] ) result.append(" [shape = box]"); 235 if ( isFinal[i] || isPushback[i] ) result.append(Out.NL); 236 } 237 238 for (int i=0; i < numStates; i++) { 239 for (int input = 0; input < numInput; input++) { 240 if ( table[i][input] >= 0 ) { 241 result.append(i+" -> "+table[i][input]); 242 result.append(" [label=\"["+input+"]\"]"+Out.NL); 243 } 245 } 246 } 247 248 result.append("}"+Out.NL); 249 250 return result.toString(); 251 } 252 253 254 public void checkActions(LexScan scanner, LexParse parser) { 256 EOFActions eofActions = parser.getEOFActions(); 257 Enumeration l = scanner.actions.elements(); 258 259 while (l.hasMoreElements()) { 260 Object next = l.nextElement(); 261 if ( !next.equals(usedActions.get(next)) && !eofActions.isEOFAction(next) ) 262 Out.warning(scanner.file, ErrorMessages.NEVER_MATCH, ((Action) next).priority-1, -1); 263 } 264 } 265 266 267 274 public void minimize() { 275 Out.print(numStates+" states before minimization, "); 276 277 if (numStates == 0) { 278 Out.error(ErrorMessages.ZERO_STATES); 279 throw new GeneratorException(); 280 } 281 282 if (Options.no_minimize) { 283 Out.println("minimization skipped."); 284 return; 285 } 286 287 final int n = numStates+1; 290 291 int [] block = new int[2*n]; 295 296 int [] b_forward = new int[2*n]; 298 int [] b_backward = new int[2*n]; 299 300 int lastBlock = n; final int b0 = n; 305 int [] l_forward = new int[n*numInput+1]; 308 int [] l_backward = new int[n*numInput+1]; 309 int anchorL = n*numInput; 311 int [] [] inv_delta = new int[n][numInput]; 315 int [] inv_delta_set = new int [2*n*numInput]; 316 317 int [] twin = new int[2*n]; 321 int numSplit; 322 323 int [] SD = new int[2*n]; 327 328 int [] D = new int[n]; 330 int numD; 331 332 333 int lastDelta = 0; 335 int [] inv_lists = new int[n]; int [] inv_list_last = new int[n]; for (int c = 0; c < numInput; c++) { 338 for (int s = 0; s < n; s++) { 340 inv_list_last[s] = -1; 341 inv_delta[s][c] = -1; 342 } 343 344 inv_delta[0][c] = 0; 346 inv_list_last[0] = 0; 347 348 for (int s = 1; s < n; s++) { 350 int t = table[s-1][c]+1; 351 352 if (inv_list_last[t] == -1) { inv_delta[t][c] = s; inv_list_last[t] = s; 355 } 356 else { 357 inv_lists[inv_list_last[t]] = s; inv_list_last[t] = s; } 360 } 361 362 for (int s = 0; s < n; s++) { 365 int i = inv_delta[s][c]; inv_delta[s][c] = lastDelta; 366 int j = inv_list_last[s]; 367 boolean go_on = (i != -1); 368 while (go_on) { 369 go_on = (i != j); 370 inv_delta_set[lastDelta++] = i; 371 i = inv_lists[i]; 372 } 373 inv_delta_set[lastDelta++] = -1; 374 } 375 } 377 379 381 b_forward[b0] = 0; 383 b_backward[b0] = 0; 384 b_forward[0] = b0; 385 b_backward[0] = b0; 386 block[0] = b0; 387 block[b0] = 1; 388 389 for (int s = 1; s < n; s++) { 390 int b = b0+1; boolean found = false; 395 while (!found && b <= lastBlock) { 396 int t = b_forward[b]; 398 400 found = (isPushback[s-1] == isPushback[t-1]) && (isLookEnd[s-1] == isLookEnd[t-1]); 402 if (found) { 403 if (isFinal[s-1]) { 404 found = isFinal[t-1] && action[s-1].isEquiv(action[t-1]); 405 } 406 else { 407 found = !isFinal[t-1]; 408 } 409 410 if (found) { block[s] = b; 414 block[b]++; 415 416 int last = b_backward[b]; 418 b_forward[last] = s; 419 b_forward[s] = b; 420 b_backward[b] = s; 421 b_backward[s] = last; 422 } 423 } 424 425 b++; 426 } 427 428 if (!found) { 431 block[s] = b; 433 block[b]++; 434 435 b_forward[b] = s; 437 b_forward[s] = b; 438 b_backward[b] = s; 439 b_backward[s] = b; 440 441 lastBlock++; 442 } 443 } 445 447 int B_max = b0; 450 int B_i; 451 for (B_i = b0+1; B_i <= lastBlock; B_i++) 452 if (block[B_max] < block[B_i]) B_max = B_i; 453 454 l_forward[anchorL] = anchorL; 456 l_backward[anchorL] = anchorL; 457 458 if (B_max == b0) B_i = b0+1; else B_i = b0; 461 int index = (B_i-b0)*numInput; while (index < (B_i+1-b0)*numInput) { 463 int last = l_backward[anchorL]; 464 l_forward[last] = index; 465 l_forward[index] = anchorL; 466 l_backward[index] = last; 467 l_backward[anchorL] = index; 468 index++; 469 } 470 471 while (B_i <= lastBlock) { 473 if (B_i != B_max) { 474 index = (B_i-b0)*numInput; 475 while (index < (B_i+1-b0)*numInput) { 476 int last = l_backward[anchorL]; 477 l_forward[last] = index; 478 l_forward[index] = anchorL; 479 l_backward[index] = last; 480 l_backward[anchorL] = index; 481 index++; 482 } 483 } 484 B_i++; 485 } 486 488 while (l_forward[anchorL] != anchorL) { 493 496 498 int B_j_a = l_forward[anchorL]; 500 l_forward[anchorL] = l_forward[B_j_a]; 502 l_backward[l_forward[anchorL]] = anchorL; 503 l_forward[B_j_a] = 0; 504 int B_j = b0 + B_j_a / numInput; 506 int a = B_j_a % numInput; 507 508 510 513 numD = 0; 516 int s = b_forward[B_j]; 517 while (s != B_j) { 518 int t = inv_delta[s][a]; 520 while (inv_delta_set[t] != -1) { 522 D[numD++] = inv_delta_set[t++]; 524 } 525 s = b_forward[s]; 526 } 527 528 numSplit = 0; 530 531 533 for (int indexD = 0; indexD < numD; indexD++) { s = D[indexD]; 536 B_i = block[s]; 537 SD[B_i] = -1; 538 twin[B_i] = 0; 539 } 540 541 for (int indexD = 0; indexD < numD; indexD++) { s = D[indexD]; 546 B_i = block[s]; 547 548 if (SD[B_i] < 0) { 550 SD[B_i] = 0; 551 int t = b_forward[B_i]; 552 while (t != B_i && (t != 0 || block[0] == B_j) && 553 (t == 0 || block[table[t-1][a]+1] == B_j)) { 554 SD[B_i]++; 555 t = b_forward[t]; 556 } 557 } 558 } 559 560 for (int indexD = 0; indexD < numD; indexD++) { s = D[indexD]; 563 B_i = block[s]; 564 565 567 if (SD[B_i] != block[B_i]) { 568 int B_k = twin[B_i]; 570 if (B_k == 0) { 571 B_k = ++lastBlock; 573 b_forward[B_k] = B_k; 576 b_backward[B_k] = B_k; 577 578 twin[B_i] = B_k; 579 580 twin[numSplit++] = B_i; 582 } 583 585 b_forward[b_backward[s]] = b_forward[s]; 587 b_backward[b_forward[s]] = b_backward[s]; 588 589 int last = b_backward[B_k]; 591 b_forward[last] = s; 592 b_forward[s] = B_k; 593 b_backward[s] = last; 594 b_backward[B_k] = s; 595 596 block[s] = B_k; 597 block[B_k]++; 598 block[B_i]--; 599 600 SD[B_i]--; } 604 } 606 608 610 for (int indexTwin = 0; indexTwin < numSplit; indexTwin++) { 612 B_i = twin[indexTwin]; 613 int B_k = twin[B_i]; 614 for (int c = 0; c < numInput; c++) { 615 int B_i_c = (B_i-b0)*numInput+c; 616 int B_k_c = (B_k-b0)*numInput+c; 617 if (l_forward[B_i_c] > 0) { 618 int last = l_backward[anchorL]; 620 l_backward[anchorL] = B_k_c; 621 l_forward[last] = B_k_c; 622 l_backward[B_k_c] = last; 623 l_forward[B_k_c] = anchorL; 624 } 625 else { 626 if (block[B_i] <= block[B_k]) { 628 int last = l_backward[anchorL]; 629 l_backward[anchorL] = B_i_c; 630 l_forward[last] = B_i_c; 631 l_backward[B_i_c] = last; 632 l_forward[B_i_c] = anchorL; 633 } 634 else { 635 int last = l_backward[anchorL]; 636 l_backward[anchorL] = B_k_c; 637 l_forward[last] = B_k_c; 638 l_backward[B_k_c] = last; 639 l_forward[B_k_c] = anchorL; 640 } 641 } 642 } 643 } 644 } 645 646 649 667 668 670 int trans [] = new int [numStates]; 673 674 boolean kill [] = new boolean [numStates]; 676 677 int move [] = new int [numStates]; 680 681 for (int b = b0+1; b <= lastBlock; b++) { int s = b_forward[b]; 685 int min_s = s; for (; s != b; s = b_forward[s]) 687 if (min_s > s) min_s = s; 688 min_s--; 691 for (s = b_forward[b]-1; s != b-1; s = b_forward[s+1]-1) { 692 trans[s] = min_s; 693 kill[s] = s != min_s; 694 } 695 } 696 697 int amount = 0; 699 for (int i = 0; i < numStates; i++) { 700 if ( kill[i] ) 701 amount++; 702 else 703 move[i] = amount; 704 } 705 706 int i,j; 707 for (i = 0, j = 0; i < numStates; i++) { 710 711 if ( !kill[i] ) { 713 714 for (int c = 0; c < numInput; c++) { 716 if ( table[i][c] >= 0 ) { 717 table[j][c] = trans[ table[i][c] ]; 718 table[j][c]-= move[ table[j][c] ]; 719 } 720 else { 721 table[j][c] = table[i][c]; 722 } 723 } 724 725 isFinal[j] = isFinal[i]; 726 isPushback[j] = isPushback[i]; 727 isLookEnd[j] = isLookEnd[i]; 728 action[j] = action[i]; 729 730 j++; 731 } 732 } 733 734 numStates = j; 735 736 for (i = 0; i < lexState.length; i++) { 738 lexState[i] = trans[ lexState[i] ]; 739 lexState[i]-= move[ lexState[i] ]; 740 } 741 742 Out.println(numStates+" states in minimized DFA"); 743 } 744 745 public String toString(int [] a) { 746 String r = "{"; 747 int i; 748 for (i = 0; i < a.length-1; i++) r += a[i]+","; 749 return r+a[i]+"}"; 750 } 751 752 public void printBlocks(int [] b, int [] b_f, int [] b_b, int last) { 753 Out.dump("block : "+toString(b)); 754 Out.dump("b_forward : "+toString(b_f)); 755 Out.dump("b_backward: "+toString(b_b)); 756 Out.dump("lastBlock : "+last); 757 final int n = numStates+1; 758 for (int i = n; i <= last; i ++) { 759 Out.dump("Block "+(i-n)+" (size "+b[i]+"):"); 760 String line = "{"; 761 int s = b_f[i]; 762 while (s != i) { 763 line = line+(s-1); 764 int t = s; 765 s = b_f[s]; 766 if (s != i) { 767 line = line+","; 768 if (b[s] != i) Out.dump("consistency error for state "+(s-1)+" (block "+b[s]+")"); 769 } 770 if (b_b[s] != t) Out.dump("consistency error for b_back in state "+(s-1)+" (back = "+b_b[s]+", should be = "+t+")"); 771 } 772 Out.dump(line+"}"); 773 } 774 } 775 776 public void printL(int [] l_f, int [] l_b, int anchor) { 777 String l = "L = {"; 778 int bc = l_f[anchor]; 779 while (bc != anchor) { 780 int b = bc / numInput; 781 int c = bc % numInput; 782 l+= "("+b+","+c+")"; 783 int old_bc = bc; 784 bc = l_f[bc]; 785 if (bc != anchor) l+= ","; 786 if (l_b[bc] != old_bc) Out.dump("consistency error for ("+b+","+c+")"); 787 } 788 Out.dump(l+"}"); 789 } 790 791 792 public boolean [] [] old_minimize() { 793 794 int i,j; 795 char c; 796 797 Out.print(numStates+" states before minimization, "); 798 799 if (numStates == 0) { 800 Out.error(ErrorMessages.ZERO_STATES); 801 throw new GeneratorException(); 802 } 803 804 if (Options.no_minimize) { 805 Out.println("minimization skipped."); 806 return null; 807 } 808 809 boolean [] [] equiv = new boolean [numStates] []; 811 812 StatePairList [] [] list = new StatePairList [numStates] []; 815 816 for (i = 1; i < numStates; i++) { 819 list[i] = new StatePairList[i]; 820 equiv[i] = new boolean [i]; 821 for (j = 0; j < i; j++) { 822 826 if ( isFinal[i] && isFinal[j] && (isPushback[i] == isPushback[j]) && (isLookEnd[i] == isLookEnd[j]) ) 827 equiv[i][j] = action[i].isEquiv(action[j]); 828 else 829 equiv[i][j] = !isFinal[j] && !isFinal[i] && (isPushback[i] == isPushback[j]) && (isLookEnd[i] == isLookEnd[j]); 830 } 831 } 832 833 834 for (i = 1; i < numStates; i++) { 835 836 Out.debug("Testing state "+i); 837 838 for (j = 0; j < i; j++) { 839 840 if ( equiv[i][j] ) { 841 842 for (c = 0; c < numInput; c++) { 843 844 if (equiv[i][j]) { 845 846 int p = table[i][c]; 847 int q = table[j][c]; 848 if (p < q) { 849 int t = p; 850 p = q; 851 q = t; 852 } 853 if ( p >= 0 || q >= 0 ) { 854 if ( p!=q && (p == -1 || q == -1 || !equiv[p][q]) ) { 857 equiv[i][j] = false; 858 if (list[i][j] != null) list[i][j].markAll(list,equiv); 859 } 860 } } } 865 867 if ( equiv[i][j] ) { 868 869 871 for (c = 0; c < numInput; c++) { 872 873 int p = table[i][c]; 874 int q = table[j][c]; 875 if (p < q) { 876 int t = p; 877 p = q; 878 q = t; 879 } 880 881 if (p != q && p >= 0 && q >= 0) { 882 if ( list[p][q] == null ) { 883 list[p][q] = new StatePairList(); 884 } 885 list[p][q].addPair(i,j); 886 } 887 } 888 } 889 else { 890 } 892 893 } } } 898 900 return equiv; 901 } 902 903 904 public void printInvDelta(int [] [] inv_delta, int [] inv_delta_set) { 905 Out.dump("Inverse of transition table: "); 906 for (int s = 0; s < numStates+1; s++) { 907 Out.dump("State ["+(s-1)+"]"); 908 for (int c = 0; c < numInput; c++) { 909 String line = "With <"+c+"> in {"; 910 int t = inv_delta[s][c]; 911 while (inv_delta_set[t] != -1) { 912 line += inv_delta_set[t++]-1; 913 if (inv_delta_set[t] != -1) line += ","; 914 } 915 if (inv_delta_set[inv_delta[s][c]] != -1) 916 Out.dump(line+"}"); 917 } 918 } 919 } 920 921 public void printTable(boolean [] [] equiv) { 922 923 Out.dump("Equivalence table is : "); 924 for (int i = 1; i < numStates; i++) { 925 String line = i+" :"; 926 for (int j = 0; j < i; j++) { 927 if (equiv[i][j]) 928 line+= " E"; 929 else 930 line+= " x"; 931 } 932 Out.dump(line); 933 } 934 } 935 936 } 937 | Popular Tags |