1 22 23 package org.javacc.parser; 24 25 import java.util.*; 26 27 public class NfaState 28 { 29 public static boolean unicodeWarningGiven = false; 30 public static int generatedStates = 0; 31 static int idCnt = 0; 32 static int lohiByteCnt; 33 static int dummyStateIndex = -1; 34 static boolean done; 35 static boolean mark[]; 36 static boolean stateDone[]; 37 static boolean nonAsciiIntersections[][] = new boolean[20][20]; 38 39 static Vector allStates = new Vector(); 40 static Vector indexedAllStates = new Vector(); 41 static Vector nonAsciiTableForMethod = new Vector(); 42 static Hashtable equivStatesTable = new Hashtable(); 43 static Hashtable allNextStates = new Hashtable(); 44 static Hashtable lohiByteTab = new Hashtable(); 45 static Hashtable stateNameForComposite = new Hashtable(); 46 static Hashtable compositeStateTable = new Hashtable(); 47 static Hashtable stateBlockTable = new Hashtable(); 48 static Hashtable stateSetsToFix = new Hashtable(); 49 50 public static void ReInit() 51 { 52 generatedStates = 0; 53 idCnt = 0; 54 dummyStateIndex = -1; 55 done = false; 56 mark = null; 57 stateDone = null; 58 59 allStates.removeAllElements(); 60 indexedAllStates.removeAllElements(); 61 equivStatesTable.clear(); 62 allNextStates.clear(); 63 compositeStateTable.clear(); 64 stateBlockTable.clear(); 65 stateNameForComposite.clear(); 66 stateSetsToFix.clear(); 67 } 68 69 long[] asciiMoves = new long[2]; 70 char[] charMoves = null; 71 char[] rangeMoves = null; 72 NfaState next = null; 73 NfaState stateForCase; 74 Vector epsilonMoves = new Vector(); 75 String epsilonMovesString; 76 NfaState[] epsilonMoveArray; 77 78 int id; 79 int stateName = -1; 80 int kind = Integer.MAX_VALUE; 81 int lookingFor; 82 int usefulEpsilonMoves = 0; 83 int inNextOf; 84 private int lexState; 85 int nonAsciiMethod = -1; 86 int kindToPrint = Integer.MAX_VALUE; 87 boolean dummy = false; 88 boolean isComposite = false; 89 int[] compositeStates = null; 90 boolean isFinal = false; 91 public Vector loByteVec; 92 public int[] nonAsciiMoveIndices; 93 int round = 0; 94 int onlyChar = 0; 95 char matchSingleChar; 96 97 NfaState() 98 { 99 id = idCnt++; 100 allStates.addElement(this); 101 lexState = LexGen.lexStateIndex; 102 lookingFor = LexGen.curKind; 103 } 104 105 NfaState CreateClone() 106 { 107 NfaState retVal = new NfaState(); 108 109 retVal.isFinal = isFinal; 110 retVal.kind = kind; 111 retVal.lookingFor = lookingFor; 112 retVal.lexState = lexState; 113 retVal.inNextOf = inNextOf; 114 115 retVal.MergeMoves(this); 116 117 return retVal; 118 } 119 120 static void InsertInOrder(Vector v, NfaState s) 121 { 122 int j; 123 124 for (j = 0; j < v.size(); j++) 125 if (((NfaState)v.elementAt(j)).id > s.id) 126 break; 127 else if (((NfaState)v.elementAt(j)).id == s.id) 128 return; 129 130 v.insertElementAt(s, j); 131 } 132 133 private static char[] ExpandCharArr(char[] oldArr, int incr) 134 { 135 char[] ret = new char[oldArr.length + incr]; 136 System.arraycopy(oldArr, 0, ret, 0, oldArr.length); 137 return ret; 138 } 139 140 void AddMove(NfaState newState) 141 { 142 if (!epsilonMoves.contains(newState)) 143 InsertInOrder(epsilonMoves, newState); 144 } 145 146 private final void AddASCIIMove(char c) 147 { 148 asciiMoves[c / 64] |= (1L << (c % 64)); 149 } 150 151 void AddChar(char c) 152 { 153 onlyChar++; 154 matchSingleChar = c; 155 int i; 156 char temp; 157 char temp1; 158 159 if ((int)c < 128) { 161 AddASCIIMove(c); 162 return; 163 } 164 165 if (charMoves == null) 166 charMoves = new char[10]; 167 168 int len = charMoves.length; 169 170 if (charMoves[len - 1] != 0) 171 { 172 charMoves = ExpandCharArr(charMoves, 10); 173 len += 10; 174 } 175 176 for (i = 0; i < len; i++) 177 if (charMoves[i] == 0 || charMoves[i] > c) 178 break; 179 180 if (!unicodeWarningGiven && c > 0xff && 181 !Options.getJavaUnicodeEscape() && 182 !Options.getUserCharStream()) 183 { 184 unicodeWarningGiven = true; 185 JavaCCErrors.warning(LexGen.curRE, "Non-ASCII characters used in regular expression.\n" + 186 "Please make sure you use the correct Reader when you create the parser that can handle your character set."); 187 } 188 189 temp = charMoves[i]; 190 charMoves[i] = c; 191 192 for (i++; i < len; i++) 193 { 194 if (temp == 0) 195 break; 196 197 temp1 = charMoves[i]; 198 charMoves[i] = temp; 199 temp = temp1; 200 } 201 } 202 203 void AddRange(char left, char right) 204 { 205 onlyChar = 2; 206 int i; 207 char tempLeft1, tempLeft2, tempRight1, tempRight2; 208 209 if (left < 128) 210 { 211 if (right < 128) 212 { 213 for (; left <= right; left++) 214 AddASCIIMove(left); 215 216 return; 217 } 218 219 for (; left < 128; left++) 220 AddASCIIMove(left); 221 } 222 223 if (!unicodeWarningGiven && (left > 0xff || right > 0xff) && 224 !Options.getJavaUnicodeEscape() && 225 !Options.getUserCharStream()) 226 { 227 unicodeWarningGiven = true; 228 JavaCCErrors.warning(LexGen.curRE, "Non-ASCII characters used in regular expression.\n" + 229 "Please make sure you use the correct Reader when you create the parser that can handle your character set."); 230 } 231 232 if (rangeMoves == null) 233 rangeMoves = new char[20]; 234 235 int len = rangeMoves.length; 236 237 if (rangeMoves[len - 1] != 0) 238 { 239 rangeMoves = ExpandCharArr(rangeMoves, 20); 240 len += 20; 241 } 242 243 for (i = 0; i < len; i += 2) 244 if (rangeMoves[i] == 0 || 245 (rangeMoves[i] > left) || 246 ((rangeMoves[i] == left) && (rangeMoves[i + 1] > right))) 247 break; 248 249 tempLeft1 = rangeMoves[i]; 250 tempRight1 = rangeMoves[i + 1]; 251 rangeMoves[i] = left; 252 rangeMoves[i + 1] = right; 253 254 for (i += 2; i < len; i += 2) 255 { 256 if (tempLeft1 == 0) 257 break; 258 259 tempLeft2 = rangeMoves[i]; 260 tempRight2 = rangeMoves[i + 1]; 261 rangeMoves[i] = tempLeft1; 262 rangeMoves[i + 1] = tempRight1; 263 tempLeft1 = tempLeft2; 264 tempRight1 = tempRight2; 265 } 266 } 267 268 270 private static boolean EqualCharArr(char[] arr1, char[] arr2) 271 { 272 if (arr1 == arr2) 273 return true; 274 275 if (arr1 != null && 276 arr2 != null && 277 arr1.length == arr2.length) 278 { 279 for (int i = arr1.length; i-- > 0;) 280 if (arr1[i] != arr2[i]) 281 return false; 282 283 return true; 284 } 285 286 return false; 287 } 288 289 private boolean closureDone = false; 290 291 296 297 private void EpsilonClosure() 298 { 299 int i = 0; 300 301 if (closureDone || mark[id]) 302 return; 303 304 mark[id] = true; 305 306 for (i = 0; i < epsilonMoves.size(); i++) 308 ((NfaState)epsilonMoves.elementAt(i)).EpsilonClosure(); 309 310 Enumeration e = epsilonMoves.elements(); 311 312 while (e.hasMoreElements()) 313 { 314 NfaState tmp = (NfaState)e.nextElement(); 315 316 for (i = 0; i < tmp.epsilonMoves.size(); i++) 317 { 318 NfaState tmp1 = (NfaState)tmp.epsilonMoves.elementAt(i); 319 if (tmp1.UsefulState() && !epsilonMoves.contains(tmp1)) 320 { 321 InsertInOrder(epsilonMoves, tmp1); 322 done = false; 323 } 324 } 325 326 if (kind > tmp.kind) 327 kind = tmp.kind; 328 } 329 330 if (HasTransitions() && !epsilonMoves.contains(this)) 331 InsertInOrder(epsilonMoves, this); 332 } 333 334 private boolean UsefulState() 335 { 336 return isFinal || HasTransitions(); 337 } 338 339 public boolean HasTransitions() 340 { 341 return (asciiMoves[0] != 0L || asciiMoves[1] != 0L || 342 (charMoves != null && charMoves[0] != 0) || 343 (rangeMoves != null && rangeMoves[0] != 0)); 344 } 345 346 void MergeMoves(NfaState other) 347 { 348 if (asciiMoves == other.asciiMoves) 350 { 351 JavaCCErrors.semantic_error("Bug in JavaCC : Please send " + 352 "a report along with the input that caused this. Thank you."); 353 throw new Error (); 354 } 355 356 asciiMoves[0] = asciiMoves[0] | other.asciiMoves[0]; 357 asciiMoves[1] = asciiMoves[1] | other.asciiMoves[1]; 358 359 if (other.charMoves != null) 360 { 361 if (charMoves == null) 362 charMoves = other.charMoves; 363 else 364 { 365 char[] tmpCharMoves = new char[charMoves.length + 366 other.charMoves.length]; 367 System.arraycopy(charMoves, 0, tmpCharMoves, 0, charMoves.length); 368 charMoves = tmpCharMoves; 369 370 for (int i = 0; i < other.charMoves.length; i++) 371 AddChar(other.charMoves[i]); 372 } 373 } 374 375 if (other.rangeMoves != null) 376 { 377 if (rangeMoves == null) 378 rangeMoves = other.rangeMoves; 379 else 380 { 381 char[] tmpRangeMoves = new char[rangeMoves.length + 382 other.rangeMoves.length]; 383 System.arraycopy(rangeMoves, 0, tmpRangeMoves, 384 0, rangeMoves.length); 385 rangeMoves = tmpRangeMoves; 386 for (int i = 0; i < other.rangeMoves.length; i += 2) 387 AddRange(other.rangeMoves[i], other.rangeMoves[i + 1]); 388 } 389 } 390 391 if (other.kind < kind) 392 kind = other.kind; 393 394 if (other.kindToPrint < kindToPrint) 395 kindToPrint = other.kindToPrint; 396 397 isFinal |= other.isFinal; 398 } 399 400 NfaState CreateEquivState(Vector states) 401 { 402 NfaState newState = ((NfaState)states.elementAt(0)).CreateClone(); 403 404 newState.next = new NfaState(); 405 406 InsertInOrder(newState.next.epsilonMoves, 407 ((NfaState)states.elementAt(0)).next); 408 409 for (int i = 1; i < states.size(); i++) 410 { 411 NfaState tmp2 = ((NfaState)states.elementAt(i)); 412 413 if (tmp2.kind < newState.kind) 414 newState.kind = tmp2.kind; 415 416 newState.isFinal |= tmp2.isFinal; 417 418 InsertInOrder(newState.next.epsilonMoves, tmp2.next); 419 } 420 421 return newState; 422 } 423 424 private NfaState GetEquivalentRunTimeState() 425 { 426 Outer : 427 for (int i = allStates.size(); i-- > 0;) 428 { 429 NfaState other = (NfaState)allStates.elementAt(i); 430 431 if (this != other && other.stateName != -1 && 432 kindToPrint == other.kindToPrint && 433 asciiMoves[0] == other.asciiMoves[0] && 434 asciiMoves[1] == other.asciiMoves[1] && 435 EqualCharArr(charMoves, other.charMoves) && 436 EqualCharArr(rangeMoves, other.rangeMoves)) 437 { 438 if (next == other.next) 439 return other; 440 else if (next != null && other.next != null) 441 { 442 if (next.epsilonMoves.size() == other.next.epsilonMoves.size()) 443 { 444 for (int j = 0; j < next.epsilonMoves.size(); j++) 445 if (next.epsilonMoves.elementAt(j) != 446 other.next.epsilonMoves.elementAt(j)) 447 continue Outer; 448 449 return other; 450 } 451 } 452 } 453 } 454 455 return null; 456 } 457 458 void GenerateCode() 460 { 461 if (stateName != -1) 462 return; 463 464 if (next != null) 465 { 466 next.GenerateCode(); 467 if (next.kind != Integer.MAX_VALUE) 468 kindToPrint = next.kind; 469 } 470 471 if (stateName == -1 && HasTransitions()) 472 { 473 NfaState tmp = GetEquivalentRunTimeState(); 474 475 if (tmp != null) 476 { 477 stateName = tmp.stateName; 478 dummy = true; 482 return; 483 } 484 485 stateName = generatedStates++; 486 indexedAllStates.addElement(this); 487 GenerateNextStatesCode(); 488 } 489 } 490 491 public static void ComputeClosures() 492 { 493 for (int i = allStates.size(); i-- > 0; ) 494 { 495 NfaState tmp = (NfaState)allStates.elementAt(i); 496 497 if (!tmp.closureDone) 498 tmp.OptimizeEpsilonMoves(true); 499 } 500 501 for (int i = 0; i < allStates.size(); i++) 502 { 503 NfaState tmp = (NfaState)allStates.elementAt(i); 504 505 if (!tmp.closureDone) 506 tmp.OptimizeEpsilonMoves(false); 507 } 508 509 for (int i = 0; i < allStates.size(); i++) 510 { 511 NfaState tmp = (NfaState)allStates.elementAt(i); 512 tmp.epsilonMoveArray = new NfaState[tmp.epsilonMoves.size()]; 513 tmp.epsilonMoves.copyInto(tmp.epsilonMoveArray); 514 } 515 } 516 517 void OptimizeEpsilonMoves(boolean optReqd) 518 { 519 int i; 520 521 done = false; 523 while (!done) 524 { 525 if (mark == null || mark.length < allStates.size()) 526 mark = new boolean[allStates.size()]; 527 528 for (i = allStates.size(); i-- > 0;) 529 mark[i] = false; 530 531 done = true; 532 EpsilonClosure(); 533 } 534 535 for (i = allStates.size(); i-- > 0;) 536 ((NfaState)allStates.elementAt(i)).closureDone = 537 mark[((NfaState)allStates.elementAt(i)).id]; 538 539 542 boolean sometingOptimized = true; 543 544 NfaState newState = null; 545 NfaState tmp1, tmp2; 546 int j; 547 Vector equivStates = null; 548 549 while (sometingOptimized) 550 { 551 sometingOptimized = false; 552 for (i = 0; optReqd && i < epsilonMoves.size(); i++) 553 { 554 if ((tmp1 = (NfaState)epsilonMoves.elementAt(i)).HasTransitions()) 555 { 556 for (j = i + 1; j < epsilonMoves.size(); j++) 557 { 558 if ((tmp2 = (NfaState)epsilonMoves.elementAt(j)). 559 HasTransitions() && 560 (tmp1.asciiMoves[0] == tmp2.asciiMoves[0] && 561 tmp1.asciiMoves[1] == tmp2.asciiMoves[1] && 562 EqualCharArr(tmp1.charMoves, tmp2.charMoves) && 563 EqualCharArr(tmp1.rangeMoves, tmp2.rangeMoves))) 564 { 565 if (equivStates == null) 566 { 567 equivStates = new Vector(); 568 equivStates.addElement(tmp1); 569 } 570 571 InsertInOrder(equivStates, tmp2); 572 epsilonMoves.removeElementAt(j--); 573 } 574 } 575 } 576 577 if (equivStates != null) 578 { 579 sometingOptimized = true; 580 String tmp = ""; 581 for (int l = 0; l < equivStates.size(); l++) 582 tmp += String.valueOf( 583 ((NfaState)equivStates.elementAt(l)).id) + ", "; 584 585 if ((newState = (NfaState)equivStatesTable.get(tmp)) == null) 586 { 587 newState = CreateEquivState(equivStates); 588 equivStatesTable.put(tmp, newState); 589 } 590 591 epsilonMoves.removeElementAt(i--); 592 epsilonMoves.addElement(newState); 593 equivStates = null; 594 newState = null; 595 } 596 } 597 598 for (i = 0; i < epsilonMoves.size(); i++) 599 { 600 tmp1 = (NfaState)epsilonMoves.elementAt(i); 603 604 for (j = i + 1; j < epsilonMoves.size(); j++) 605 { 606 tmp2 = (NfaState)epsilonMoves.elementAt(j); 607 608 if (tmp1.next == tmp2.next) 609 { 610 if (newState == null) 611 { 612 newState = tmp1.CreateClone(); 613 newState.next = tmp1.next; 614 sometingOptimized = true; 615 } 616 617 newState.MergeMoves(tmp2); 618 epsilonMoves.removeElementAt(j--); 619 } 620 } 621 622 if (newState != null) 623 { 624 epsilonMoves.removeElementAt(i--); 625 epsilonMoves.addElement(newState); 626 newState = null; 627 } 628 } 629 } 630 631 633 if (epsilonMoves.size() > 0) 635 { 636 for (i = 0; i < epsilonMoves.size(); i++) 637 if (((NfaState)epsilonMoves.elementAt(i)).HasTransitions()) 639 usefulEpsilonMoves++; 640 else 641 epsilonMoves.removeElementAt(i--); 642 } 643 } 644 645 void GenerateNextStatesCode() 646 { 647 if (next.usefulEpsilonMoves > 0) 648 next.GetEpsilonMovesString(); 649 } 650 651 String GetEpsilonMovesString() 652 { 653 int[] stateNames = new int[usefulEpsilonMoves]; 654 int cnt = 0; 655 656 if (epsilonMovesString != null) 657 return epsilonMovesString; 658 659 if (usefulEpsilonMoves > 0) 660 { 661 NfaState tempState; 662 epsilonMovesString = "{ "; 663 for (int i = 0; i < epsilonMoves.size(); i++) 664 { 665 if ((tempState = (NfaState)epsilonMoves.elementAt(i)). 666 HasTransitions()) 667 { 668 if (tempState.stateName == -1) 669 tempState.GenerateCode(); 670 671 ((NfaState)indexedAllStates.elementAt(tempState.stateName)).inNextOf++; 672 stateNames[cnt] = tempState.stateName; 673 epsilonMovesString += tempState.stateName + ", "; 674 if (cnt++ > 0 && cnt % 16 == 0) 675 epsilonMovesString += "\n"; 676 } 677 } 678 679 epsilonMovesString += "};"; 680 } 681 682 usefulEpsilonMoves = cnt; 683 if (epsilonMovesString != null && 684 allNextStates.get(epsilonMovesString) == null) 685 { 686 int[] statesToPut = new int[usefulEpsilonMoves]; 687 688 System.arraycopy(stateNames, 0, statesToPut, 0, cnt); 689 allNextStates.put(epsilonMovesString, statesToPut); 690 } 691 692 return epsilonMovesString; 693 } 694 695 public static boolean CanStartNfaUsingAscii(char c) 696 { 697 if (c >= 128) 698 throw new Error ("JavaCC Bug: Please send mail to sankar@cs.stanford.edu"); 699 700 String s = LexGen.initialState.GetEpsilonMovesString(); 701 702 if (s == null || s.equals("null;")) 703 return false; 704 705 int[] states = (int[])allNextStates.get(s); 706 707 for (int i = 0; i < states.length; i++) 708 { 709 NfaState tmp = (NfaState)indexedAllStates.elementAt(states[i]); 710 711 if ((tmp.asciiMoves[c / 64 ] & (1L << c % 64)) != 0L) 712 return true; 713 } 714 715 return false; 716 } 717 718 final boolean CanMoveUsingChar(char c) 719 { 720 int i; 721 722 if (onlyChar == 1) 723 return c == matchSingleChar; 724 725 if (c < 128) 726 return ((asciiMoves[c / 64 ] & (1L << c % 64)) != 0L); 727 728 if (charMoves != null && charMoves[0] != 0) 730 { 731 for (i = 0; i < charMoves.length; i++) 732 { 733 if (c == charMoves[i]) 734 return true; 735 else if (c < charMoves[i] || charMoves[i] == 0) 736 break; 737 } 738 } 739 740 741 if (rangeMoves != null && rangeMoves[0] != 0) 744 for (i = 0; i < rangeMoves.length; i += 2) 745 if (c >= rangeMoves[i] && c <= rangeMoves[i + 1]) 746 return true; 747 else if (c < rangeMoves[i] || rangeMoves[i] == 0) 748 break; 749 750 return false; 752 } 753 754 public int getFirstValidPos(String s, int i, int len) 755 { 756 if (onlyChar == 1) 757 { 758 char c = matchSingleChar; 759 while (c != s.charAt(i) && ++i < len); 760 return i; 761 } 762 763 do 764 { 765 if (CanMoveUsingChar(s.charAt(i))) 766 return i; 767 } while (++i < len); 768 769 return i; 770 } 771 772 public int MoveFrom(char c, Vector newStates) 773 { 774 if (CanMoveUsingChar(c)) 775 { 776 for (int i = next.epsilonMoves.size(); i-- > 0;) 777 InsertInOrder(newStates, (NfaState)next.epsilonMoves.elementAt(i)); 778 779 return kindToPrint; 780 } 781 782 return Integer.MAX_VALUE; 783 } 784 785 public static int MoveFromSet(char c, Vector states, Vector newStates) 786 { 787 int tmp; 788 int retVal = Integer.MAX_VALUE; 789 790 for (int i = states.size(); i-- > 0;) 791 if (retVal > 792 (tmp = ((NfaState)states.elementAt(i)).MoveFrom(c, newStates))) 793 retVal = tmp; 794 795 return retVal; 796 } 797 798 public static int moveFromSetForRegEx(char c, NfaState[] states, NfaState[] newStates, int round) 799 { 800 int start = 0; 801 int sz = states.length; 802 803 for (int i = 0; i < sz; i++) 804 { 805 NfaState tmp1, tmp2; 806 807 if ((tmp1 = states[i]) == null) 808 break; 809 810 if (tmp1.CanMoveUsingChar(c)) 811 { 812 if (tmp1.kindToPrint != Integer.MAX_VALUE) 813 { 814 newStates[start] = null; 815 return 1; 816 } 817 818 NfaState[] v = tmp1.next.epsilonMoveArray; 819 for (int j = v.length; j-- > 0;) 820 { 821 if ((tmp2 = v[j]).round != round) 822 { 823 tmp2.round = round; 824 newStates[start++] = tmp2; 825 } 826 } 827 } 828 } 829 830 newStates[start] = null; 831 return Integer.MAX_VALUE; 832 } 833 834 static Vector allBitVectors = new Vector(); 835 836 842 843 static int[] tmpIndices = new int[512]; void GenerateNonAsciiMoves(java.io.PrintWriter ostr) 845 { 846 int i = 0, j = 0; 847 char hiByte; 848 int cnt = 0; 849 long[][] loBytes = new long[256][4]; 850 851 if ((charMoves == null || charMoves[0] == 0) && 852 (rangeMoves == null || rangeMoves[0] == 0)) 853 return; 854 855 if (charMoves != null) 856 { 857 for (i = 0; i < charMoves.length; i++) 858 { 859 if (charMoves[i] == 0) 860 break; 861 862 hiByte = (char)(charMoves[i] >> 8); 863 loBytes[hiByte][(charMoves[i] & 0xff) / 64] |= 864 (1L << ((charMoves[i] & 0xff) % 64)); 865 } 866 } 867 868 if (rangeMoves != null) 869 { 870 for (i = 0; i < rangeMoves.length; i += 2) 871 { 872 if (rangeMoves[i] == 0) 873 break; 874 875 char c, r; 876 877 r = (char)(rangeMoves[i + 1] & 0xff); 878 hiByte = (char)(rangeMoves[i] >> 8); 879 880 if (hiByte == (char)(rangeMoves[i + 1] >> 8)) 881 { 882 for (c = (char)(rangeMoves[i] & 0xff); c <= r; c++) 883 loBytes[hiByte][c / 64] |= (1L << (c % 64)); 884 885 continue; 886 } 887 888 for (c = (char)(rangeMoves[i] & 0xff); c <= 0xff; c++) 889 loBytes[hiByte][c / 64] |= (1L << (c % 64)); 890 891 while (++hiByte < (char)(rangeMoves[i + 1] >> 8)) 892 { 893 loBytes[hiByte][0] |= 0xffffffffffffffffL; 894 loBytes[hiByte][1] |= 0xffffffffffffffffL; 895 loBytes[hiByte][2] |= 0xffffffffffffffffL; 896 loBytes[hiByte][3] |= 0xffffffffffffffffL; 897 } 898 899 for (c = 0; c <= r; c++) 900 loBytes[hiByte][c / 64] |= (1L << (c % 64)); 901 } 902 } 903 904 long[] common = null; 905 boolean[] done = new boolean[256]; 906 907 for (i = 0; i <= 255; i++) 908 { 909 if (done[i] || 910 (done[i] = 911 loBytes[i][0] == 0 && 912 loBytes[i][1] == 0 && 913 loBytes[i][2] == 0 && 914 loBytes[i][3] == 0)) 915 continue; 916 917 for (j = i + 1; j < 256; j++) 918 { 919 if (done[j]) 920 continue; 921 922 if (loBytes[i][0] == loBytes[j][0] && 923 loBytes[i][1] == loBytes[j][1] && 924 loBytes[i][2] == loBytes[j][2] && 925 loBytes[i][3] == loBytes[j][3]) 926 { 927 done[j] = true; 928 if (common == null) 929 { 930 done[i] = true; 931 common = new long[4]; 932 common[i / 64] |= (1L << (i % 64)); 933 } 934 935 common[j / 64] |= (1L << (j % 64)); 936 } 937 } 938 939 if (common != null) 940 { 941 Integer ind; 942 String tmp; 943 944 tmp = "{\n 0x" + Long.toHexString(common[0]) + "L, " + 945 "0x" + Long.toHexString(common[1]) + "L, " + 946 "0x" + Long.toHexString(common[2]) + "L, " + 947 "0x" + Long.toHexString(common[3]) + "L\n};"; 948 if ((ind = (Integer )lohiByteTab.get(tmp)) == null) 949 { 950 allBitVectors.addElement(tmp); 951 952 if (!AllBitsSet(tmp)) 953 ostr.println("static final long[] jjbitVec" + lohiByteCnt + " = " + tmp); 954 lohiByteTab.put(tmp, ind = new Integer (lohiByteCnt++)); 955 } 956 957 tmpIndices[cnt++] = ind.intValue(); 958 959 tmp = "{\n 0x" + Long.toHexString(loBytes[i][0]) + "L, " + 960 "0x" + Long.toHexString(loBytes[i][1]) + "L, " + 961 "0x" + Long.toHexString(loBytes[i][2]) + "L, " + 962 "0x" + Long.toHexString(loBytes[i][3]) + "L\n};"; 963 if ((ind = (Integer )lohiByteTab.get(tmp)) == null) 964 { 965 allBitVectors.addElement(tmp); 966 967 if (!AllBitsSet(tmp)) 968 ostr.println("static final long[] jjbitVec" + lohiByteCnt + " = " + tmp); 969 lohiByteTab.put(tmp, ind = new Integer (lohiByteCnt++)); 970 } 971 972 tmpIndices[cnt++] = ind.intValue(); 973 974 common = null; 975 } 976 } 977 978 nonAsciiMoveIndices = new int[cnt]; 979 System.arraycopy(tmpIndices, 0, nonAsciiMoveIndices, 0, cnt); 980 981 990 991 for (i = 0; i < 256; i++) 992 { 993 if (done[i]) 994 loBytes[i] = null; 995 else 996 { 997 String tmp; 999 Integer ind; 1000 1001 tmp = "{\n 0x" + Long.toHexString(loBytes[i][0]) + "L, " + 1002 "0x" + Long.toHexString(loBytes[i][1]) + "L, " + 1003 "0x" + Long.toHexString(loBytes[i][2]) + "L, " + 1004 "0x" + Long.toHexString(loBytes[i][3]) + "L\n};"; 1005 1006 if ((ind = (Integer )lohiByteTab.get(tmp)) == null) 1007 { 1008 allBitVectors.addElement(tmp); 1009 1010 if (!AllBitsSet(tmp)) 1011 ostr.println("static final long[] jjbitVec" + lohiByteCnt + " = " + tmp); 1012 lohiByteTab.put(tmp, ind = new Integer (lohiByteCnt++)); 1013 } 1014 1015 if (loByteVec == null) 1016 loByteVec = new Vector(); 1017 1018 loByteVec.addElement(new Integer (i)); 1019 loByteVec.addElement(ind); 1020 } 1021 } 1022 UpdateDuplicateNonAsciiMoves(); 1024 } 1025 1026 private void UpdateDuplicateNonAsciiMoves() 1027 { 1028 for (int i = 0; i < nonAsciiTableForMethod.size(); i++) 1029 { 1030 NfaState tmp = (NfaState)nonAsciiTableForMethod.elementAt(i); 1031 if (EqualLoByteVectors(loByteVec, tmp.loByteVec) && 1032 EqualNonAsciiMoveIndices(nonAsciiMoveIndices, tmp.nonAsciiMoveIndices)) 1033 { 1034 nonAsciiMethod = i; 1035 return; 1036 } 1037 } 1038 1039 nonAsciiMethod = nonAsciiTableForMethod.size(); 1040 nonAsciiTableForMethod.addElement(this); 1041 } 1042 1043 private static boolean EqualLoByteVectors(Vector vec1, Vector vec2) 1044 { 1045 if (vec1 == null || vec2 == null) 1046 return false; 1047 1048 if (vec1 == vec2) 1049 return true; 1050 1051 if (vec1.size() != vec2.size()) 1052 return false; 1053 1054 for (int i = 0; i < vec1.size(); i++) 1055 { 1056 if (((Integer )vec1.elementAt(i)).intValue() != 1057 ((Integer )vec2.elementAt(i)).intValue()) 1058 return false; 1059 } 1060 1061 return true; 1062 } 1063 1064 private static boolean EqualNonAsciiMoveIndices(int[] moves1, int[] moves2) 1065 { 1066 if (moves1 == moves2) 1067 return true; 1068 1069 if (moves1 == null || moves2 == null) 1070 return false; 1071 1072 if (moves1.length != moves2.length) 1073 return false; 1074 1075 for (int i = 0; i < moves1.length;i++) 1076 { 1077 if (moves1[i] != moves2[i]) 1078 return false; 1079 } 1080 1081 return true; 1082 } 1083 1084 static String allBits = "{\n 0xffffffffffffffffL, " + 1085 "0xffffffffffffffffL, " + 1086 "0xffffffffffffffffL, " + 1087 "0xffffffffffffffffL\n};"; 1088 1089 static boolean AllBitsSet(String bitVec) 1090 { 1091 return bitVec.equals(allBits); 1092 } 1093 1094 static int AddStartStateSet(String stateSetString) 1095 { 1096 return AddCompositeStateSet(stateSetString, true); 1097 } 1098 1099 private static int AddCompositeStateSet(String stateSetString, boolean starts) 1100 { 1101 Integer stateNameToReturn; 1102 1103 if ((stateNameToReturn = (Integer )stateNameForComposite.get(stateSetString)) != null) 1104 return stateNameToReturn.intValue(); 1105 1106 int toRet = 0; 1107 int[] nameSet = (int[])allNextStates.get(stateSetString); 1108 1109 if (!starts) 1110 stateBlockTable.put(stateSetString, stateSetString); 1111 1112 if (nameSet == null) 1113 throw new Error ("JavaCC Bug: Please send mail to sankar@cs.stanford.edu; nameSet null for : " + stateSetString); 1114 1115 if (nameSet.length == 1) 1116 { 1117 stateNameToReturn = new Integer (nameSet[0]); 1118 stateNameForComposite.put(stateSetString, stateNameToReturn); 1119 return nameSet[0]; 1120 } 1121 1122 for (int i = 0; i < nameSet.length; i++) 1123 { 1124 if (nameSet[i] == -1) 1125 continue; 1126 1127 NfaState st = (NfaState)indexedAllStates.elementAt(nameSet[i]); 1128 st.isComposite = true; 1129 st.compositeStates = nameSet; 1130 } 1131 1132 while (toRet < nameSet.length && 1133 (starts && ((NfaState)indexedAllStates.elementAt(nameSet[toRet])).inNextOf > 1)) 1134 toRet++; 1135 1136 Enumeration e = compositeStateTable.keys(); 1137 String s; 1138 while (e.hasMoreElements()) 1139 { 1140 s = (String )e.nextElement(); 1141 if (!s.equals(stateSetString) && Intersect(stateSetString, s)) 1142 { 1143 int[] other = (int[])compositeStateTable.get(s); 1144 1145 while (toRet < nameSet.length && 1146 ((starts && ((NfaState)indexedAllStates.elementAt(nameSet[toRet])).inNextOf > 1) || 1147 ElemOccurs(nameSet[toRet], other) >= 0)) 1148 toRet++; 1149 } 1150 } 1151 1152 int tmp; 1153 1154 if (toRet >= nameSet.length) 1155 { 1156 if (dummyStateIndex == -1) 1157 tmp = dummyStateIndex = generatedStates; 1158 else 1159 tmp = ++dummyStateIndex; 1160 } 1161 else 1162 tmp = nameSet[toRet]; 1163 1164 stateNameToReturn = new Integer (tmp); 1165 stateNameForComposite.put(stateSetString, stateNameToReturn); 1166 compositeStateTable.put(stateSetString, nameSet); 1167 1168 return tmp; 1169 } 1170 1171 private static int StateNameForComposite(String stateSetString) 1172 { 1173 return ((Integer )stateNameForComposite.get(stateSetString)).intValue(); 1174 } 1175 1176 static int InitStateName() 1177 { 1178 String s = LexGen.initialState.GetEpsilonMovesString(); 1179 1180 if (LexGen.initialState.usefulEpsilonMoves != 0) 1181 return StateNameForComposite(s); 1182 return -1; 1183 } 1184 1185 public void GenerateInitMoves(java.io.PrintWriter ostr) 1186 { 1187 GetEpsilonMovesString(); 1188 1189 if (epsilonMovesString == null) 1190 epsilonMovesString = "null;"; 1191 1192 AddStartStateSet(epsilonMovesString); 1193 } 1194 1195 static Hashtable tableToDump = new Hashtable(); 1196 static Vector orderedStateSet = new Vector(); 1197 1198 static int lastIndex = 0; 1199 private static int[] GetStateSetIndicesForUse(String arrayString) 1200 { 1201 int[] ret; 1202 int[] set = (int[])allNextStates.get(arrayString); 1203 1204 if ((ret = (int[])tableToDump.get(arrayString)) == null) 1205 { 1206 ret = new int[2]; 1207 ret[0] = lastIndex; 1208 ret[1] = lastIndex + set.length - 1; 1209 lastIndex += set.length; 1210 tableToDump.put(arrayString, ret); 1211 orderedStateSet.addElement(set); 1212 } 1213 1214 return ret; 1215 } 1216 1217 public static void DumpStateSets(java.io.PrintWriter ostr) 1218 { 1219 int cnt = 0; 1220 1221 ostr.print("static final int[] jjnextStates = {"); 1222 for (int i = 0; i < orderedStateSet.size(); i++) 1223 { 1224 int[] set = (int[])orderedStateSet.elementAt(i); 1225 1226 for (int j = 0; j < set.length; j++) 1227 { 1228 if (cnt++ % 16 == 0) 1229 ostr.print("\n "); 1230 1231 ostr.print(set[j] + ", "); 1232 } 1233 } 1234 1235 ostr.println("\n};"); 1236 } 1237 1238 static String GetStateSetString(int[] states) 1239 { 1240 String retVal = "{ "; 1241 for (int i = 0; i < states.length; ) 1242 { 1243 retVal += states[i] + ", "; 1244 1245 if (i++ > 0 && i % 16 == 0) 1246 retVal += "\n"; 1247 } 1248 1249 retVal += "};"; 1250 allNextStates.put(retVal, states); 1251 return retVal; 1252 } 1253 1254 static String GetStateSetString(Vector states) 1255 { 1256 if (states == null || states.size() == 0) 1257 return "null;"; 1258 1259 int[] set = new int[states.size()]; 1260 String retVal = "{ "; 1261 for (int i = 0; i < states.size(); ) 1262 { 1263 int k; 1264 retVal += (k = ((NfaState)states.elementAt(i)).stateName) + ", "; 1265 set[i] = k; 1266 1267 if (i++ > 0 && i % 16 == 0) 1268 retVal += "\n"; 1269 } 1270 1271 retVal += "};"; 1272 allNextStates.put(retVal, set); 1273 return retVal; 1274 } 1275 1276 static int NumberOfBitsSet(long l) 1277 { 1278 int ret = 0; 1279 for (int i = 0; i < 63; i++) 1280 if (((l >> i) & 1L) != 0L) 1281 ret++; 1282 1283 return ret; 1284 } 1285 1286 static int OnlyOneBitSet(long l) 1287 { 1288 int oneSeen = -1; 1289 for (int i = 0; i < 64; i++) 1290 if (((l >> i) & 1L) != 0L) 1291 { 1292 if (oneSeen >= 0) 1293 return -1; 1294 oneSeen = i; 1295 } 1296 1297 return oneSeen; 1298 } 1299 1300 private static int ElemOccurs(int elem, int[] arr) 1301 { 1302 for (int i = arr.length; i-- > 0;) 1303 if (arr[i] == elem) 1304 return i; 1305 1306 return -1; 1307 } 1308 1309 private boolean FindCommonBlocks() 1310 { 1311 if (next == null || next.usefulEpsilonMoves <= 1) 1312 return false; 1313 1314 if (stateDone == null) 1315 stateDone = new boolean[generatedStates]; 1316 1317 String set = next.epsilonMovesString; 1318 1319 int[] nameSet = (int[])allNextStates.get(set); 1320 1321 if (nameSet.length <= 2 || compositeStateTable.get(set) != null) 1322 return false; 1323 1324 int i; 1325 int freq[] = new int[nameSet.length]; 1326 boolean live[] = new boolean[nameSet.length]; 1327 int[] count = new int[allNextStates.size()]; 1328 1329 for (i = 0; i < nameSet.length; i++) 1330 { 1331 if (nameSet[i] != -1) 1332 { 1333 if (live[i] = !stateDone[nameSet[i]]) 1334 count[0]++; 1335 } 1336 } 1337 1338 int j, blockLen = 0, commonFreq = 0; 1339 Enumeration e = allNextStates.keys(); 1340 boolean needUpdate; 1341 1342 while (e.hasMoreElements()) 1343 { 1344 int[] tmpSet = (int[])allNextStates.get(e.nextElement()); 1345 if (tmpSet == nameSet) 1346 continue; 1347 1348 needUpdate = false; 1349 for (j = 0; j < nameSet.length; j++) 1350 { 1351 if (nameSet[j] == -1) 1352 continue; 1353 1354 if (live[j] && ElemOccurs(nameSet[j], tmpSet) >= 0) 1355 { 1356 if (!needUpdate) 1357 { 1358 needUpdate = true; 1359 commonFreq++; 1360 } 1361 1362 count[freq[j]]--; 1363 count[commonFreq]++; 1364 freq[j] = commonFreq; 1365 } 1366 } 1367 1368 if (needUpdate) 1369 { 1370 int foundFreq = -1; 1371 blockLen = 0; 1372 1373 for (j = 0; j <= commonFreq; j++) 1374 if (count[j] > blockLen) 1375 { 1376 foundFreq = j; 1377 blockLen = count[j]; 1378 } 1379 1380 if (blockLen <= 1) 1381 return false; 1382 1383 for (j = 0; j < nameSet.length; j++) 1384 if (nameSet[j] != -1 && freq[j] != foundFreq) 1385 { 1386 live[j] = false; 1387 count[freq[j]]--; 1388 } 1389 } 1390 } 1391 1392 if (blockLen <= 1) 1393 return false; 1394 1395 int[] commonBlock = new int[blockLen]; 1396 int cnt = 0; 1397 for (i = 0; i < nameSet.length; i++) 1399 { 1400 if (live[i]) 1401 { 1402 if (((NfaState)indexedAllStates.elementAt(nameSet[i])).isComposite) 1403 return false; 1404 1405 stateDone[nameSet[i]] = true; 1406 commonBlock[cnt++] = nameSet[i]; 1407 } 1409 } 1410 1411 1413 String s = GetStateSetString(commonBlock); 1414 e = allNextStates.keys(); 1415 1416 Outer : 1417 while (e.hasMoreElements()) 1418 { 1419 int at; 1420 boolean firstOne = true; 1421 String stringToFix; 1422 int[] setToFix = (int[])allNextStates.get(stringToFix = (String )e.nextElement()); 1423 1424 if (setToFix == commonBlock) 1425 continue; 1426 1427 for (int k = 0; k < cnt; k++) 1428 { 1429 if ((at = ElemOccurs(commonBlock[k], setToFix)) >= 0) 1430 { 1431 if (!firstOne) 1432 setToFix[at] = -1; 1433 firstOne = false; 1434 } 1435 else 1436 continue Outer; 1437 } 1438 1439 if (stateSetsToFix.get(stringToFix) == null) 1440 stateSetsToFix.put(stringToFix, setToFix); 1441 } 1442 1443 next.usefulEpsilonMoves -= blockLen - 1; 1444 AddCompositeStateSet(s, false); 1445 return true; 1446 } 1447 1448 private boolean CheckNextOccursTogether() 1449 { 1450 if (next == null || next.usefulEpsilonMoves <= 1) 1451 return true; 1452 1453 String set = next.epsilonMovesString; 1454 1455 int[] nameSet = (int[])allNextStates.get(set); 1456 1457 if (nameSet.length == 1 || compositeStateTable.get(set) != null || 1458 stateSetsToFix.get(set) != null) 1459 return false; 1460 1461 int i; 1462 Hashtable occursIn = new Hashtable(); 1463 NfaState tmp = (NfaState)allStates.elementAt(nameSet[0]); 1464 1465 for (i = 1; i < nameSet.length; i++) 1466 { 1467 NfaState tmp1 = (NfaState)allStates.elementAt(nameSet[i]); 1468 1469 if (tmp.inNextOf != tmp1.inNextOf) 1470 return false; 1471 } 1472 1473 int isPresent, j; 1474 Enumeration e = allNextStates.keys(); 1475 while (e.hasMoreElements()) 1476 { 1477 String s; 1478 int[] tmpSet = (int[])allNextStates.get(s = (String )e.nextElement()); 1479 1480 if (tmpSet == nameSet) 1481 continue; 1482 1483 isPresent = 0; 1484 Outer: 1485 for (j = 0; j < nameSet.length; j++) 1486 { 1487 if (ElemOccurs(nameSet[j], tmpSet) >= 0) 1488 isPresent++; 1489 else if (isPresent > 0) 1490 return false; 1491 } 1492 1493 if (isPresent == j) 1494 { 1495 if (tmpSet.length > nameSet.length) 1496 occursIn.put(s, tmpSet); 1497 1498 1499 if (compositeStateTable.get(s) != null || 1500 stateSetsToFix.get(s) != null) 1501 return false; 1502 } 1503 else if (isPresent != 0) 1504 return false; 1505 } 1506 1507 e = occursIn.keys(); 1508 while (e.hasMoreElements()) 1509 { 1510 String s; 1511 int[] setToFix = (int[])occursIn.get(s = (String )e.nextElement()); 1512 1513 if (stateSetsToFix.get(s) == null) 1514 stateSetsToFix.put(s, setToFix); 1515 1516 for (int k = 0; k < setToFix.length; k++) 1517 if (ElemOccurs(setToFix[k], nameSet) > 0) setToFix[k] = -1; 1519 } 1520 1521 next.usefulEpsilonMoves = 1; 1522 AddCompositeStateSet(next.epsilonMovesString, false); 1523 return true; 1524 } 1525 1526 private static void FixStateSets() 1527 { 1528 Hashtable fixedSets = new Hashtable(); 1529 Enumeration e = stateSetsToFix.keys(); 1530 int[] tmp = new int[generatedStates]; 1531 int i; 1532 1533 while (e.hasMoreElements()) 1534 { 1535 String s; 1536 int[] toFix = (int[])stateSetsToFix.get(s = (String )e.nextElement()); 1537 int cnt = 0; 1538 1539 for (i = 0; i < toFix.length; i++) 1541 { 1542 if (toFix[i] != -1) 1544 tmp[cnt++] = toFix[i]; 1545 } 1546 1547 int[] fixed = new int[cnt]; 1548 System.arraycopy(tmp, 0, fixed, 0, cnt); 1549 fixedSets.put(s, fixed); 1550 allNextStates.put(s, fixed); 1551 } 1553 1554 for (i = 0; i < allStates.size(); i++) 1555 { 1556 NfaState tmpState = (NfaState)allStates.elementAt(i); 1557 int[] newSet; 1558 1559 if (tmpState.next == null || tmpState.next.usefulEpsilonMoves == 0) 1560 continue; 1561 1562 if ((newSet = (int[])fixedSets.get(tmpState.next.epsilonMovesString)) != null) 1565 tmpState.FixNextStates(newSet); 1566 } 1567 } 1568 1569 private final void FixNextStates(int[] newSet) 1570 { 1571 next.usefulEpsilonMoves = newSet.length; 1572 } 1574 1575 private static boolean Intersect(String set1, String set2) 1576 { 1577 if (set1 == null || set2 == null) 1578 return false; 1579 1580 int[] nameSet1 = (int[])allNextStates.get(set1); 1581 int[] nameSet2 = (int[])allNextStates.get(set2); 1582 1583 if (nameSet1 == null || nameSet2 == null) 1584 return false; 1585 1586 if (nameSet1 == nameSet2) 1587 return true; 1588 1589 for (int i = nameSet1.length; i-- > 0; ) 1590 for (int j = nameSet2.length; j-- > 0; ) 1591 if (nameSet1[i] == nameSet2[j]) 1592 return true; 1593 1594 return false; 1595 } 1596 1597 private static void DumpHeadForCase(java.io.PrintWriter ostr, int byteNum) 1598 { 1599 if (byteNum == 0) 1600 ostr.println(" long l = 1L << curChar;"); 1601 else if (byteNum == 1) 1602 ostr.println(" long l = 1L << (curChar & 077);"); 1603 1604 else 1605 { 1606 if (Options.getJavaUnicodeEscape() || unicodeWarningGiven) 1607 { 1608 ostr.println(" int hiByte = (int)(curChar >> 8);"); 1609 ostr.println(" int i1 = hiByte >> 6;"); 1610 ostr.println(" long l1 = 1L << (hiByte & 077);"); 1611 } 1612 1613 ostr.println(" int i2 = (curChar & 0xff) >> 6;"); 1614 ostr.println(" long l2 = 1L << (curChar & 077);"); 1615 } 1616 1617 ostr.println(" MatchLoop: do"); 1618 ostr.println(" {"); 1619 1620 ostr.println(" switch(jjstateSet[--i])"); 1621 ostr.println(" {"); 1622 } 1623 1624 private static Vector PartitionStatesSetForAscii(int[] states, int byteNum) 1625 { 1626 int[] cardinalities = new int[states.length]; 1627 Vector original = new Vector(); 1628 Vector partition = new Vector(); 1629 NfaState tmp; 1630 1631 original.setSize(states.length); 1632 int cnt = 0; 1633 for (int i = 0; i < states.length; i++) 1634 { 1635 tmp = (NfaState)allStates.elementAt(states[i]); 1636 1637 if (tmp.asciiMoves[byteNum] != 0L) 1638 { 1639 int j; 1640 int p = NumberOfBitsSet(tmp.asciiMoves[byteNum]); 1641 1642 for (j = 0; j < i; j++) 1643 if (cardinalities[j] <= p) 1644 break; 1645 1646 for (int k = i; k > j; k--) 1647 cardinalities[k] = cardinalities[k - 1]; 1648 1649 cardinalities[j] = p; 1650 1651 original.insertElementAt(tmp, j); 1652 cnt++; 1653 } 1654 } 1655 1656 original.setSize(cnt); 1657 1658 while (original.size() > 0) 1659 { 1660 tmp = (NfaState)original.elementAt(0); 1661 original.removeElement(tmp); 1662 1663 long bitVec = tmp.asciiMoves[byteNum]; 1664 Vector subSet = new Vector(); 1665 subSet.addElement(tmp); 1666 1667 for (int j = 0; j < original.size(); j++) 1668 { 1669 NfaState tmp1 = (NfaState)original.elementAt(j); 1670 1671 if ((tmp1.asciiMoves[byteNum] & bitVec) == 0L) 1672 { 1673 bitVec |= tmp1.asciiMoves[byteNum]; 1674 subSet.addElement(tmp1); 1675 original.removeElementAt(j--); 1676 } 1677 } 1678 1679 partition.addElement(subSet); 1680 } 1681 1682 return partition; 1683 } 1684 1685 private String PrintNoBreak(java.io.PrintWriter ostr, int byteNum, boolean[] dumped) 1686 { 1687 if (inNextOf != 1) 1688 throw new Error ("JavaCC Bug: Please send mail to sankar@cs.stanford.edu"); 1689 1690 dumped[stateName] = true; 1691 1692 if (byteNum >= 0) 1693 { 1694 if (asciiMoves[byteNum] != 0L) 1695 { 1696 ostr.println(" case " + stateName + ":"); 1697 DumpAsciiMoveForCompositeState(ostr, byteNum, false); 1698 return ""; 1699 } 1700 } 1701 else if (nonAsciiMethod != -1) 1702 { 1703 ostr.println(" case " + stateName + ":"); 1704 DumpNonAsciiMoveForCompositeState(ostr); 1705 return ""; 1706 } 1707 1708 return (" case " + stateName + ":\n"); 1709 } 1710 1711 private static void DumpCompositeStatesAsciiMoves(java.io.PrintWriter ostr, 1712 String key, int byteNum, boolean[] dumped) 1713 { 1714 int i; 1715 1716 int[] nameSet = (int[])allNextStates.get(key); 1717 1718 if (nameSet.length == 1 || dumped[StateNameForComposite(key)]) 1719 return; 1720 1721 NfaState toBePrinted = null; 1722 int neededStates = 0; 1723 NfaState tmp; 1724 NfaState stateForCase = null; 1725 String toPrint = ""; 1726 boolean stateBlock = (stateBlockTable.get(key) != null); 1727 1728 for (i = 0; i < nameSet.length; i++) 1729 { 1730 tmp = (NfaState)allStates.elementAt(nameSet[i]); 1731 1732 if (tmp.asciiMoves[byteNum] != 0L) 1733 { 1734 if (neededStates++ == 1) 1735 break; 1736 else 1737 toBePrinted = tmp; 1738 } 1739 else 1740 dumped[tmp.stateName] = true; 1741 1742 if (tmp.stateForCase != null) 1743 { 1744 if (stateForCase != null) 1745 throw new Error ("JavaCC Bug: Please send mail to sankar@cs.stanford.edu : "); 1746 1747 stateForCase = tmp.stateForCase; 1748 } 1749 } 1750 1751 if (stateForCase != null) 1752 toPrint = stateForCase.PrintNoBreak(ostr, byteNum, dumped); 1753 1754 if (neededStates == 0) 1755 { 1756 if (stateForCase != null && toPrint.equals("")) 1757 ostr.println(" break;"); 1758 return; 1759 } 1760 1761 if (neededStates == 1) 1762 { 1763 1767 if (!toPrint.equals("")) 1768 ostr.print(toPrint); 1769 1770 ostr.println(" case " + StateNameForComposite(key) + ":"); 1771 1772 if (!dumped[toBePrinted.stateName] && !stateBlock && toBePrinted.inNextOf > 1) 1773 ostr.println(" case " + toBePrinted.stateName + ":"); 1774 1775 dumped[toBePrinted.stateName] = true; 1776 toBePrinted.DumpAsciiMove(ostr, byteNum, dumped); 1777 return; 1778 } 1779 1780 Vector partition = PartitionStatesSetForAscii(nameSet, byteNum); 1781 1782 if (!toPrint.equals("")) 1783 ostr.print(toPrint); 1784 1785 int keyState = StateNameForComposite(key); 1786 ostr.println(" case " + keyState + ":"); 1787 if (keyState < generatedStates) 1788 dumped[keyState] = true; 1789 1790 for (i = 0; i < partition.size(); i++) 1791 { 1792 Vector subSet = (Vector)partition.elementAt(i); 1793 1794 for (int j = 0; j < subSet.size(); j++) 1795 { 1796 tmp = (NfaState)subSet.elementAt(j); 1797 1798 if (stateBlock) 1799 dumped[tmp.stateName] = true; 1800 tmp.DumpAsciiMoveForCompositeState(ostr, byteNum, j != 0); 1801 } 1802 } 1803 1804 if (stateBlock) 1805 ostr.println(" break;"); 1806 else 1807 ostr.println(" break;"); 1808 } 1809 1810 private boolean selfLoop() 1811 { 1812 if (next == null || next.epsilonMovesString == null) 1813 return false; 1814 1815 int[] set = (int[])allNextStates.get(next.epsilonMovesString); 1816 return ElemOccurs(stateName, set) >= 0; 1817 } 1818 1819 private void DumpAsciiMoveForCompositeState(java.io.PrintWriter ostr, int byteNum, boolean elseNeeded) 1820 { 1821 boolean nextIntersects = selfLoop(); 1822 1823 for (int j = 0; j < allStates.size(); j++) 1824 { 1825 NfaState temp1 = (NfaState)allStates.elementAt(j); 1826 1827 if (this == temp1 || temp1.stateName == -1 || temp1.dummy || 1828 stateName == temp1.stateName || temp1.asciiMoves[byteNum] == 0L) 1829 continue; 1830 1831 if (!nextIntersects && Intersect(temp1.next.epsilonMovesString, 1832 next.epsilonMovesString)) 1833 { 1834 nextIntersects = true; 1835 break; 1836 } 1837 } 1838 1839 String prefix = ""; 1841 if (asciiMoves[byteNum] != 0xffffffffffffffffL) 1842 { 1843 int oneBit = OnlyOneBitSet(asciiMoves[byteNum]); 1844 1845 if (oneBit != -1) 1846 ostr.println(" " + (elseNeeded ? "else " : "") + "if (curChar == " + 1847 (64 * byteNum + oneBit) + ")"); 1848 else 1849 ostr.println(" " + (elseNeeded ? "else " : "") + "if ((0x" + Long.toHexString(asciiMoves[byteNum]) + 1850 "L & l) != 0L)"); 1851 prefix = " "; 1852 } 1853 1854 if (kindToPrint != Integer.MAX_VALUE) 1855 { 1856 if (asciiMoves[byteNum] != 0xffffffffffffffffL) 1857 { 1858 ostr.println(" {"); 1859 } 1860 1861 ostr.println(prefix + " if (kind > " + kindToPrint + ")"); 1862 ostr.println(prefix + " kind = " + kindToPrint + ";"); 1863 } 1864 1865 if (next != null && next.usefulEpsilonMoves > 0) 1866 { 1867 int[] stateNames = (int[])allNextStates.get( 1868 next.epsilonMovesString); 1869 if (next.usefulEpsilonMoves == 1) 1870 { 1871 int name = stateNames[0]; 1872 1873 if (nextIntersects) 1874 ostr.println(prefix + " jjCheckNAdd(" + name + ");"); 1875 else 1876 ostr.println(prefix + " jjstateSet[jjnewStateCnt++] = " + name + ";"); 1877 } 1878 else if (next.usefulEpsilonMoves == 2 && nextIntersects) 1879 { 1880 ostr.println(prefix + " jjCheckNAddTwoStates(" + 1881 stateNames[0] + ", " + stateNames[1] + ");"); 1882 } 1883 else 1884 { 1885 int[] indices = GetStateSetIndicesForUse(next.epsilonMovesString); 1886 boolean notTwo = (indices[0] + 1 != indices[1]); 1887 1888 if (nextIntersects) 1889 ostr.println(prefix + " jjCheckNAddStates(" + 1890 indices[0] + (notTwo ? (", " + indices[1]) : "") + ");"); 1891 else 1892 ostr.println(prefix + " jjAddStates(" + 1893 indices[0] + ", " + indices[1] + ");"); 1894 } 1895 } 1896 1897 if (asciiMoves[byteNum] != 0xffffffffffffffffL && kindToPrint != Integer.MAX_VALUE) 1898 ostr.println(" }"); 1899 } 1900 1901 private void DumpAsciiMove(java.io.PrintWriter ostr, int byteNum, boolean dumped[]) 1902 { 1903 boolean nextIntersects = selfLoop() && isComposite; 1904 boolean onlyState = true; 1905 1906 for (int j = 0; j < allStates.size(); j++) 1907 { 1908 NfaState temp1 = (NfaState)allStates.elementAt(j); 1909 1910 if (this == temp1 || temp1.stateName == -1 || temp1.dummy || 1911 stateName == temp1.stateName || temp1.asciiMoves[byteNum] == 0L) 1912 continue; 1913 1914 if (onlyState && (asciiMoves[byteNum] & temp1.asciiMoves[byteNum]) != 0L) 1915 onlyState = false; 1916 1917 if (!nextIntersects && Intersect(temp1.next.epsilonMovesString, 1918 next.epsilonMovesString)) 1919 nextIntersects = true; 1920 1921 if (!dumped[temp1.stateName] && !temp1.isComposite && 1922 asciiMoves[byteNum] == temp1.asciiMoves[byteNum] && 1923 kindToPrint == temp1.kindToPrint && 1924 (next.epsilonMovesString == temp1.next.epsilonMovesString || 1925 (next.epsilonMovesString != null && 1926 temp1.next.epsilonMovesString != null && 1927 next.epsilonMovesString.equals( 1928 temp1.next.epsilonMovesString)))) 1929 { 1930 dumped[temp1.stateName] = true; 1931 ostr.println(" case " + temp1.stateName + ":"); 1932 } 1933 } 1934 1935 1938 int oneBit = OnlyOneBitSet(asciiMoves[byteNum]); 1939 if (asciiMoves[byteNum] != 0xffffffffffffffffL) 1940 { 1941 if ((next == null || next.usefulEpsilonMoves == 0) && 1942 kindToPrint != Integer.MAX_VALUE) 1943 { 1944 String kindCheck = ""; 1945 1946 if (!onlyState) 1947 kindCheck = " && kind > " + kindToPrint; 1948 1949 if (oneBit != -1) 1950 ostr.println(" if (curChar == " + 1951 (64 * byteNum + oneBit) + kindCheck + ")"); 1952 else 1953 ostr.println(" if ((0x" + 1954 Long.toHexString(asciiMoves[byteNum]) + 1955 "L & l) != 0L" + kindCheck + ")"); 1956 1957 ostr.println(" kind = " + kindToPrint + ";"); 1958 1959 if (onlyState) 1960 ostr.println(" break;"); 1961 else 1962 ostr.println(" break;"); 1963 1964 return; 1965 } 1966 } 1967 1968 String prefix = ""; 1969 if (kindToPrint != Integer.MAX_VALUE) 1970 { 1971 1972 if (oneBit != -1) 1973 { 1974 ostr.println(" if (curChar != " + 1975 (64 * byteNum + oneBit) + ")"); 1976 ostr.println(" break;"); 1977 } 1978 else if (asciiMoves[byteNum] != 0xffffffffffffffffL) 1979 { 1980 ostr.println(" if ((0x" + Long.toHexString(asciiMoves[byteNum]) + "L & l) == 0L)"); 1981 ostr.println(" break;"); 1982 } 1983 1984 if (onlyState) 1985 { 1986 ostr.println(" kind = " + kindToPrint + ";"); 1987 } 1988 else 1989 { 1990 ostr.println(" if (kind > " + kindToPrint + ")"); 1991 ostr.println(" kind = " + kindToPrint + ";"); 1992 } 1993 } 1994 else 1995 { 1996 if (oneBit != -1) 1997 { 1998 ostr.println(" if (curChar == " + 1999 (64 * byteNum + oneBit) + ")"); 2000 prefix = " "; 2001 } 2002 else if (asciiMoves[byteNum] != 0xffffffffffffffffL) 2003 { 2004 ostr.println(" if ((0x" + Long.toHexString(asciiMoves[byteNum]) + "L & l) != 0L)"); 2005 prefix = " "; 2006 } 2007 } 2008 2009 if (next != null && next.usefulEpsilonMoves > 0) 2010 { 2011 int[] stateNames = (int[])allNextStates.get( 2012 next.epsilonMovesString); 2013 if (next.usefulEpsilonMoves == 1) 2014 { 2015 int name = stateNames[0]; 2016 if (nextIntersects) 2017 ostr.println(prefix + " jjCheckNAdd(" + name + ");"); 2018 else 2019 ostr.println(prefix + " jjstateSet[jjnewStateCnt++] = " + name + ";"); 2020 } 2021 else if (next.usefulEpsilonMoves == 2 && nextIntersects) 2022 { 2023 ostr.println(prefix + " jjCheckNAddTwoStates(" + 2024 stateNames[0] + ", " + stateNames[1] + ");"); 2025 } 2026 else 2027 { 2028 int[] indices = GetStateSetIndicesForUse(next.epsilonMovesString); 2029 boolean notTwo = (indices[0] + 1 != indices[1]); 2030 2031 if (nextIntersects) 2032 ostr.println(prefix + " jjCheckNAddStates(" + 2033 indices[0] + (notTwo ? (", " + indices[1]) : "") + ");"); 2034 else 2035 ostr.println(prefix + " jjAddStates(" + 2036 indices[0] + ", " + indices[1] + ");"); 2037 } 2038 } 2039 2040 if (onlyState) 2041 ostr.println(" break;"); 2042 else 2043 ostr.println(" break;"); 2044 } 2045 2046 private static void DumpAsciiMoves(java.io.PrintWriter ostr, int byteNum) 2047 { 2048 boolean[] dumped = new boolean[Math.max(generatedStates, dummyStateIndex + 1)]; 2049 Enumeration e = compositeStateTable.keys(); 2050 2051 DumpHeadForCase(ostr, byteNum); 2052 2053 while (e.hasMoreElements()) 2054 DumpCompositeStatesAsciiMoves(ostr, (String )e.nextElement(), byteNum, dumped); 2055 2056 for (int i = 0; i < allStates.size(); i++) 2057 { 2058 NfaState temp = (NfaState)allStates.elementAt(i); 2059 2060 if (dumped[temp.stateName] || temp.lexState != LexGen.lexStateIndex || 2061 !temp.HasTransitions() || temp.dummy || 2062 temp.stateName == -1) 2063 continue; 2064 2065 String toPrint = ""; 2066 2067 if (temp.stateForCase != null) 2068 { 2069 if (temp.inNextOf == 1) 2070 continue; 2071 2072 if (dumped[temp.stateForCase.stateName]) 2073 continue; 2074 2075 toPrint = (temp.stateForCase.PrintNoBreak(ostr, byteNum, dumped)); 2076 2077 if (temp.asciiMoves[byteNum] == 0L) 2078 { 2079 if (toPrint.equals("")) 2080 ostr.println(" break;"); 2081 2082 continue; 2083 } 2084 } 2085 2086 if (temp.asciiMoves[byteNum] == 0L) 2087 continue; 2088 2089 if (!toPrint.equals("")) 2090 ostr.print(toPrint); 2091 2092 dumped[temp.stateName] = true; 2093 ostr.println(" case " + temp.stateName + ":"); 2094 temp.DumpAsciiMove(ostr, byteNum, dumped); 2095 } 2096 2097 ostr.println(" default : break;"); 2098 ostr.println(" }"); 2099 ostr.println(" } while(i != startsAt);"); 2100 } 2101 2102 private static void DumpCompositeStatesNonAsciiMoves(java.io.PrintWriter ostr, 2103 String key, boolean[] dumped) 2104 { 2105 int i; 2106 int[] nameSet = (int[])allNextStates.get(key); 2107 2108 if (nameSet.length == 1 || dumped[StateNameForComposite(key)]) 2109 return; 2110 2111 NfaState toBePrinted = null; 2112 int neededStates = 0; 2113 NfaState tmp; 2114 NfaState stateForCase = null; 2115 String toPrint = ""; 2116 boolean stateBlock = (stateBlockTable.get(key) != null); 2117 2118 for (i = 0; i < nameSet.length; i++) 2119 { 2120 tmp = (NfaState)allStates.elementAt(nameSet[i]); 2121 2122 if (tmp.nonAsciiMethod != -1) 2123 { 2124 if (neededStates++ == 1) 2125 break; 2126 else 2127 toBePrinted = tmp; 2128 } 2129 else 2130 dumped[tmp.stateName] = true; 2131 2132 if (tmp.stateForCase != null) 2133 { 2134 if (stateForCase != null) 2135 throw new Error ("JavaCC Bug: Please send mail to sankar@cs.stanford.edu : "); 2136 2137 stateForCase = tmp.stateForCase; 2138 } 2139 } 2140 2141 if (stateForCase != null) 2142 toPrint = stateForCase.PrintNoBreak(ostr, -1, dumped); 2143 2144 if (neededStates == 0) 2145 { 2146 if (stateForCase != null && toPrint.equals("")) 2147 ostr.println(" break;"); 2148 2149 return; 2150 } 2151 2152 if (neededStates == 1) 2153 { 2154 if (!toPrint.equals("")) 2155 ostr.print(toPrint); 2156 2157 ostr.println(" case " + StateNameForComposite(key) + ":"); 2158 2159 if (!dumped[toBePrinted.stateName] && !stateBlock && toBePrinted.inNextOf > 1) 2160 ostr.println(" case " + toBePrinted.stateName + ":"); 2161 2162 dumped[toBePrinted.stateName] = true; 2163 toBePrinted.DumpNonAsciiMove(ostr, dumped); 2164 return; 2165 } 2166 2167 if (!toPrint.equals("")) 2168 ostr.print(toPrint); 2169 2170 int keyState = StateNameForComposite(key); 2171 ostr.println(" case " + keyState + ":"); 2172 if (keyState < generatedStates) 2173 dumped[keyState] = true; 2174 2175 for (i = 0; i < nameSet.length; i++) 2176 { 2177 tmp = (NfaState)allStates.elementAt(nameSet[i]); 2178 2179 if (tmp.nonAsciiMethod != -1) 2180 { 2181 if (stateBlock) 2182 dumped[tmp.stateName] = true; 2183 tmp.DumpNonAsciiMoveForCompositeState(ostr); 2184 } 2185 } 2186 2187 if (stateBlock) 2188 ostr.println(" break;"); 2189 else 2190 ostr.println(" break;"); 2191 } 2192 2193 private final void DumpNonAsciiMoveForCompositeState(java.io.PrintWriter ostr) 2194 { 2195 boolean nextIntersects = selfLoop(); 2196 for (int j = 0; j < allStates.size(); j++) 2197 { 2198 NfaState temp1 = (NfaState)allStates.elementAt(j); 2199 2200 if (this == temp1 || temp1.stateName == -1 || temp1.dummy || 2201 stateName == temp1.stateName || (temp1.nonAsciiMethod == -1)) 2202 continue; 2203 2204 if (!nextIntersects && Intersect(temp1.next.epsilonMovesString, 2205 next.epsilonMovesString)) 2206 { 2207 nextIntersects = true; 2208 break; 2209 } 2210 } 2211 2212 if (!Options.getJavaUnicodeEscape() && !unicodeWarningGiven) 2213 { 2214 if (loByteVec != null && loByteVec.size() > 1) 2215 ostr.println(" if ((jjbitVec" + 2216 ((Integer )loByteVec.elementAt(1)).intValue() + "[i2" + 2217 "] & l2) != 0L)"); 2218 } 2219 else 2220 { 2221 ostr.println(" if (jjCanMove_" + nonAsciiMethod + 2222 "(hiByte, i1, i2, l1, l2))"); 2223 } 2224 2225 if (kindToPrint != Integer.MAX_VALUE) 2226 { 2227 ostr.println(" {"); 2228 ostr.println(" if (kind > " + kindToPrint + ")"); 2229 ostr.println(" kind = " + kindToPrint + ";"); 2230 } 2231 2232 if (next != null && next.usefulEpsilonMoves > 0) 2233 { 2234 int[] stateNames = (int[])allNextStates.get( 2235 next.epsilonMovesString); 2236 if (next.usefulEpsilonMoves == 1) 2237 { 2238 int name = stateNames[0]; 2239 if (nextIntersects) 2240 ostr.println(" jjCheckNAdd(" + name + ");"); 2241 else 2242 ostr.println(" jjstateSet[jjnewStateCnt++] = " + name + ";"); 2243 } 2244 else if (next.usefulEpsilonMoves == 2 && nextIntersects) 2245 { 2246 ostr.println(" jjCheckNAddTwoStates(" + 2247 stateNames[0] + ", " + stateNames[1] + ");"); 2248 } 2249 else 2250 { 2251 int[] indices = GetStateSetIndicesForUse(next.epsilonMovesString); 2252 boolean notTwo = (indices[0] + 1 != indices[1]); 2253 2254 if (nextIntersects) 2255 ostr.println(" jjCheckNAddStates(" + 2256 indices[0] + (notTwo ? (", " + indices[1]) : "") + ");"); 2257 else 2258 ostr.println(" jjAddStates(" + 2259 indices[0] + ", " + indices[1] + ");"); 2260 } 2261 } 2262 2263 if (kindToPrint != Integer.MAX_VALUE) 2264 ostr.println(" }"); 2265 } 2266 2267 private final void DumpNonAsciiMove(java.io.PrintWriter ostr, boolean dumped[]) 2268 { 2269 boolean nextIntersects = selfLoop() && isComposite; 2270 2271 for (int j = 0; j < allStates.size(); j++) 2272 { 2273 NfaState temp1 = (NfaState)allStates.elementAt(j); 2274 2275 if (this == temp1 || temp1.stateName == -1 || temp1.dummy || 2276 stateName == temp1.stateName || (temp1.nonAsciiMethod == -1)) 2277 continue; 2278 2279 if (!nextIntersects && Intersect(temp1.next.epsilonMovesString, 2280 next.epsilonMovesString)) 2281 nextIntersects = true; 2282 2283 if (!dumped[temp1.stateName] && !temp1.isComposite && 2284 nonAsciiMethod == temp1.nonAsciiMethod && 2285 kindToPrint == temp1.kindToPrint && 2286 (next.epsilonMovesString == temp1.next.epsilonMovesString || 2287 (next.epsilonMovesString != null && 2288 temp1.next.epsilonMovesString != null && 2289 next.epsilonMovesString.equals(temp1.next.epsilonMovesString)))) 2290 { 2291 dumped[temp1.stateName] = true; 2292 ostr.println(" case " + temp1.stateName + ":"); 2293 } 2294 } 2295 2296 if (next == null || next.usefulEpsilonMoves <= 0) 2297 { 2298 String kindCheck = " && kind > " + kindToPrint; 2299 2300 if (!Options.getJavaUnicodeEscape() && !unicodeWarningGiven) 2301 { 2302 if (loByteVec != null && loByteVec.size() > 1) 2303 ostr.println(" if ((jjbitVec" + 2304 ((Integer )loByteVec.elementAt(1)).intValue() + "[i2" + 2305 "] & l2) != 0L" + kindCheck + ")"); 2306 } 2307 else 2308 { 2309 ostr.println(" if (jjCanMove_" + nonAsciiMethod + 2310 "(hiByte, i1, i2, l1, l2)" + kindCheck + ")"); 2311 } 2312 ostr.println(" kind = " + kindToPrint + ";"); 2313 ostr.println(" break;"); 2314 return; 2315 } 2316 2317 String prefix = " "; 2318 if (kindToPrint != Integer.MAX_VALUE) 2319 { 2320 if (!Options.getJavaUnicodeEscape() && !unicodeWarningGiven) 2321 { 2322 if (loByteVec != null && loByteVec.size() > 1) 2323 { 2324 ostr.println(" if ((jjbitVec" + 2325 ((Integer )loByteVec.elementAt(1)).intValue() + "[i2" + 2326 "] & l2) == 0L)"); 2327 ostr.println(" break;"); 2328 } 2329 } 2330 else 2331 { 2332 ostr.println(" if (!jjCanMove_" + nonAsciiMethod + 2333 "(hiByte, i1, i2, l1, l2))"); 2334 ostr.println(" break;"); 2335 } 2336 2337 ostr.println(" if (kind > " + kindToPrint + ")"); 2338 ostr.println(" kind = " + kindToPrint + ";"); 2339 prefix = ""; 2340 } 2341 else if (!Options.getJavaUnicodeEscape() && !unicodeWarningGiven) 2342 { 2343 if (loByteVec != null && loByteVec.size() > 1) 2344 ostr.println(" if ((jjbitVec" + 2345 ((Integer )loByteVec.elementAt(1)).intValue() + "[i2" + 2346 "] & l2) != 0L)"); 2347 } 2348 else 2349 { 2350 ostr.println(" if (jjCanMove_" + nonAsciiMethod + 2351 "(hiByte, i1, i2, l1, l2))"); 2352 } 2353 2354 if (next != null && next.usefulEpsilonMoves > 0) 2355 { 2356 int[] stateNames = (int[])allNextStates.get( 2357 next.epsilonMovesString); 2358 if (next.usefulEpsilonMoves == 1) 2359 { 2360 int name = stateNames[0]; 2361 if (nextIntersects) 2362 ostr.println(prefix + " jjCheckNAdd(" + name + ");"); 2363 else 2364 ostr.println(prefix + " jjstateSet[jjnewStateCnt++] = " + name + ";"); 2365 } 2366 else if (next.usefulEpsilonMoves == 2 && nextIntersects) 2367 { 2368 ostr.println(prefix + " jjCheckNAddTwoStates(" + 2369 stateNames[0] + ", " + stateNames[1] + ");"); 2370 } 2371 else 2372 { 2373 int[] indices = GetStateSetIndicesForUse(next.epsilonMovesString); 2374 boolean notTwo = (indices[0] + 1 != indices[1]); 2375 2376 if (nextIntersects) 2377 ostr.println(prefix + " jjCheckNAddStates(" + 2378 indices[0] + (notTwo ? (", " + indices[1]) : "") + ");"); 2379 else 2380 ostr.println(prefix + " jjAddStates(" + 2381 indices[0] + ", " + indices[1] + ");"); 2382 } 2383 } 2384 2385 ostr.println(" break;"); 2386 } 2387 2388 public static void DumpCharAndRangeMoves(java.io.PrintWriter ostr) 2389 { 2390 boolean[] dumped = new boolean[Math.max(generatedStates, dummyStateIndex + 1)]; 2391 Enumeration e = compositeStateTable.keys(); 2392 int i; 2393 2394 DumpHeadForCase(ostr, -1); 2395 2396 while (e.hasMoreElements()) 2397 DumpCompositeStatesNonAsciiMoves(ostr, (String )e.nextElement(), dumped); 2398 2399 for (i = 0; i < allStates.size(); i++) 2400 { 2401 NfaState temp = (NfaState)allStates.elementAt(i); 2402 2403 if (dumped[temp.stateName] || temp.lexState != LexGen.lexStateIndex || 2404 !temp.HasTransitions() || temp.dummy || temp.stateName == -1) 2405 continue; 2406 2407 String toPrint = ""; 2408 2409 if (temp.stateForCase != null) 2410 { 2411 if (temp.inNextOf == 1) 2412 continue; 2413 2414 if (dumped[temp.stateForCase.stateName]) 2415 continue; 2416 2417 toPrint = (temp.stateForCase.PrintNoBreak(ostr, -1, dumped)); 2418 2419 if (temp.nonAsciiMethod == -1) 2420 { 2421 if (toPrint.equals("")) 2422 ostr.println(" break;"); 2423 2424 continue; 2425 } 2426 } 2427 2428 if (temp.nonAsciiMethod == -1) 2429 continue; 2430 2431 if (!toPrint.equals("")) 2432 ostr.print(toPrint); 2433 2434 dumped[temp.stateName] = true; 2435 ostr.println(" case " + temp.stateName + ":"); 2437 temp.DumpNonAsciiMove(ostr, dumped); 2438 } 2439 2440 ostr.println(" default : break;"); 2441 ostr.println(" }"); 2442 ostr.println(" } while(i != startsAt);"); 2443 } 2444 2445 public static void DumpNonAsciiMoveMethods(java.io.PrintWriter ostr) 2446 { 2447 if (!Options.getJavaUnicodeEscape() && !unicodeWarningGiven) 2448 return; 2449 2450 if (nonAsciiTableForMethod.size() <= 0) 2451 return; 2452 2453 for (int i = 0; i < nonAsciiTableForMethod.size(); i++) 2454 { 2455 NfaState tmp = (NfaState)nonAsciiTableForMethod.elementAt(i); 2456 tmp.DumpNonAsciiMoveMethod(ostr); 2457 } 2458 } 2459 2460 void DumpNonAsciiMoveMethod(java.io.PrintWriter ostr) 2461 { 2462 int j; 2463 ostr.println("private static final boolean jjCanMove_" + nonAsciiMethod + 2464 "(int hiByte, int i1, int i2, long l1, long l2)"); 2465 ostr.println("{"); 2466 ostr.println(" switch(hiByte)"); 2467 ostr.println(" {"); 2468 2469 if (loByteVec != null && loByteVec.size() > 0) 2470 { 2471 for (j = 0; j < loByteVec.size(); j += 2) 2472 { 2473 ostr.println(" case " + 2474 ((Integer )loByteVec.elementAt(j)).intValue() + ":"); 2475 if (!AllBitsSet((String )allBitVectors.elementAt( 2476 ((Integer )loByteVec.elementAt(j + 1)).intValue()))) 2477 { 2478 ostr.println(" return ((jjbitVec" + 2479 ((Integer )loByteVec.elementAt(j + 1)).intValue() + "[i2" + 2480 "] & l2) != 0L);"); 2481 } 2482 else 2483 ostr.println(" return true;"); 2484 } 2485 } 2486 2487 ostr.println(" default : "); 2488 2489 if (nonAsciiMoveIndices != null && 2490 (j = nonAsciiMoveIndices.length) > 0) 2491 { 2492 do 2493 { 2494 if (!AllBitsSet((String )allBitVectors.elementAt( 2495 nonAsciiMoveIndices[j - 2]))) 2496 ostr.println(" if ((jjbitVec" + nonAsciiMoveIndices[j - 2] + 2497 "[i1] & l1) != 0L)"); 2498 if (!AllBitsSet((String )allBitVectors.elementAt( 2499 nonAsciiMoveIndices[j - 1]))) 2500 { 2501 ostr.println(" if ((jjbitVec" + nonAsciiMoveIndices[j - 1] + 2502 "[i2] & l2) == 0L)"); 2503 ostr.println(" return false;"); 2504 ostr.println(" else"); 2505 } 2506 ostr.println(" return true;"); 2507 } 2508 while ((j -= 2) > 0); 2509 } 2510 2511 ostr.println(" return false;"); 2512 ostr.println(" }"); 2513 ostr.println("}"); 2514 } 2515 2516 private static void ReArrange() 2517 { 2518 Vector v = allStates; 2519 allStates = new Vector(); 2520 allStates.setSize(generatedStates); 2521 2522 for (int j = 0; j < v.size(); j++) 2523 { 2524 NfaState tmp = (NfaState)v.elementAt(j); 2525 if (tmp.stateName != -1 && !tmp.dummy) 2526 allStates.setElementAt(tmp, tmp.stateName); 2527 } 2528 } 2529 2530 private static boolean boilerPlateDumped = false; 2531 static void PrintBoilerPlate(java.io.PrintWriter ostr) 2532 { 2533 ostr.println((Options.getStatic() ? "static " : "") + "private final void " + 2534 "jjCheckNAdd(int state)"); 2535 ostr.println("{"); 2536 ostr.println(" if (jjrounds[state] != jjround)"); 2537 ostr.println(" {"); 2538 ostr.println(" jjstateSet[jjnewStateCnt++] = state;"); 2539 ostr.println(" jjrounds[state] = jjround;"); 2540 ostr.println(" }"); 2541 ostr.println("}"); 2542 2543 ostr.println((Options.getStatic() ? "static " : "") + "private final void " + 2544 "jjAddStates(int start, int end)"); 2545 ostr.println("{"); 2546 ostr.println(" do {"); 2547 ostr.println(" jjstateSet[jjnewStateCnt++] = jjnextStates[start];"); 2548 ostr.println(" } while (start++ != end);"); 2549 ostr.println("}"); 2550 2551 ostr.println((Options.getStatic() ? "static " : "") + "private final void " + 2552 "jjCheckNAddTwoStates(int state1, int state2)"); 2553 ostr.println("{"); 2554 ostr.println(" jjCheckNAdd(state1);"); 2555 ostr.println(" jjCheckNAdd(state2);"); 2556 ostr.println("}"); 2557 2558 ostr.println((Options.getStatic() ? "static " : "") + "private final void " + 2559 "jjCheckNAddStates(int start, int end)"); 2560 ostr.println("{"); 2561 ostr.println(" do {"); 2562 ostr.println(" jjCheckNAdd(jjnextStates[start]);"); 2563 ostr.println(" } while (start++ != end);"); 2564 ostr.println("}"); 2565 2566 ostr.println((Options.getStatic() ? "static " : "") + "private final void " + 2567 "jjCheckNAddStates(int start)"); 2568 ostr.println("{"); 2569 ostr.println(" jjCheckNAdd(jjnextStates[start]);"); 2570 ostr.println(" jjCheckNAdd(jjnextStates[start + 1]);"); 2571 ostr.println("}"); 2572 } 2573 2574 private static void FindStatesWithNoBreak() 2575 { 2576 Hashtable printed = new Hashtable(); 2577 boolean[] put = new boolean[generatedStates]; 2578 int cnt = 0; 2579 int i, j, foundAt = 0; 2580 2581 Outer : 2582 for (j = 0; j < allStates.size(); j++) 2583 { 2584 NfaState stateForCase = null; 2585 NfaState tmpState = (NfaState)allStates.elementAt(j); 2586 2587 if (tmpState.stateName == -1 || tmpState.dummy || !tmpState.UsefulState() || 2588 tmpState.next == null || tmpState.next.usefulEpsilonMoves < 1) 2589 continue; 2590 2591 String s = tmpState.next.epsilonMovesString; 2592 2593 if (compositeStateTable.get(s) != null || printed.get(s) != null) 2594 continue; 2595 2596 printed.put(s, s); 2597 int[] nexts = (int[])allNextStates.get(s); 2598 2599 if (nexts.length == 1) 2600 continue; 2601 2602 int state = cnt; 2603 for (i = 0; i < nexts.length; i++) 2605 { 2606 if ((state = nexts[i]) == -1) 2607 continue; 2608 2609 NfaState tmp = (NfaState)allStates.elementAt(state); 2610 2611 if (!tmp.isComposite && tmp.inNextOf == 1) 2612 { 2613 if (put[state]) 2614 throw new Error ("JavaCC Bug: Please send mail to sankar@cs.stanford.edu"); 2615 2616 foundAt = i; 2617 cnt++; 2618 stateForCase = tmp; 2619 put[state] = true; 2620 2621 break; 2623 } 2624 } 2625 2627 if (stateForCase == null) 2628 continue; 2629 2630 for (i = 0; i < nexts.length; i++) 2631 { 2632 if ((state = nexts[i]) == -1) 2633 continue; 2634 2635 NfaState tmp = (NfaState)allStates.elementAt(state); 2636 2637 if (!put[state] && tmp.inNextOf > 1 && !tmp.isComposite && tmp.stateForCase == null) 2638 { 2639 cnt++; 2640 nexts[i] = -1; 2641 put[state] = true; 2642 2643 int toSwap = nexts[0]; 2644 nexts[0] = nexts[foundAt]; 2645 nexts[foundAt] = toSwap; 2646 2647 tmp.stateForCase = stateForCase; 2648 stateForCase.stateForCase = tmp; 2649 stateSetsToFix.put(s, nexts); 2650 2651 2654 continue Outer; 2655 } 2656 } 2657 2658 for (i = 0; i < nexts.length; i++) 2659 { 2660 if ((state = nexts[i]) == -1) 2661 continue; 2662 2663 NfaState tmp = (NfaState)allStates.elementAt(state); 2664 if (tmp.inNextOf <= 1) 2665 put[state] = false; 2666 } 2667 } 2668 } 2669 2670 static int[][] kinds; 2671 static int[][][] statesForState; 2672 public static void DumpMoveNfa(java.io.PrintWriter ostr) 2673 { 2674 if (!boilerPlateDumped) 2675 PrintBoilerPlate(ostr); 2676 2677 boilerPlateDumped = true; 2678 int i; 2679 int[] kindsForStates = null; 2680 2681 if (kinds == null) 2682 { 2683 kinds = new int[LexGen.maxLexStates][]; 2684 statesForState = new int[LexGen.maxLexStates][][]; 2685 } 2686 2687 ReArrange(); 2688 2689 for (i = 0; i < allStates.size(); i++) 2690 { 2691 NfaState temp = (NfaState)allStates.elementAt(i); 2692 2693 if (temp.lexState != LexGen.lexStateIndex || 2694 !temp.HasTransitions() || temp.dummy || 2695 temp.stateName == -1) 2696 continue; 2697 2698 if (kindsForStates == null) 2699 { 2700 kindsForStates = new int[generatedStates]; 2701 statesForState[LexGen.lexStateIndex] = new int[Math.max(generatedStates, dummyStateIndex + 1)][]; 2702 } 2703 2704 kindsForStates[temp.stateName] = temp.lookingFor; 2705 statesForState[LexGen.lexStateIndex][temp.stateName] = temp.compositeStates; 2706 2707 temp.GenerateNonAsciiMoves(ostr); 2708 } 2709 2710 Enumeration e = stateNameForComposite.keys(); 2711 2712 while (e.hasMoreElements()) 2713 { 2714 String s = (String )e.nextElement(); 2715 int state = ((Integer )stateNameForComposite.get(s)).intValue(); 2716 2717 if (state >= generatedStates) 2718 statesForState[LexGen.lexStateIndex][state] = (int[])allNextStates.get(s); 2719 } 2720 2721 if (stateSetsToFix.size() != 0) 2722 FixStateSets(); 2723 2724 kinds[LexGen.lexStateIndex] = kindsForStates; 2725 2726 ostr.println((Options.getStatic() ? "static " : "") + "private final int " + 2727 "jjMoveNfa" + LexGen.lexStateSuffix + "(int startState, int curPos)"); 2728 ostr.println("{"); 2729 2730 if (generatedStates == 0) 2731 { 2732 ostr.println(" return curPos;"); 2733 ostr.println("}"); 2734 return; 2735 } 2736 2737 if (LexGen.mixed[LexGen.lexStateIndex]) 2738 { 2739 ostr.println(" int strKind = jjmatchedKind;"); 2740 ostr.println(" int strPos = jjmatchedPos;"); 2741 ostr.println(" int seenUpto;"); 2742 ostr.println(" input_stream.backup(seenUpto = curPos + 1);"); 2743 ostr.println(" try { curChar = input_stream.readChar(); }"); 2744 ostr.println(" catch(java.io.IOException e) { throw new Error(\"Internal Error\"); }"); 2745 ostr.println(" curPos = 0;"); 2746 } 2747 2748 ostr.println(" int[] nextStates;"); 2749 ostr.println(" int startsAt = 0;"); 2750 ostr.println(" jjnewStateCnt = " + generatedStates + ";"); 2751 ostr.println(" int i = 1;"); 2752 ostr.println(" jjstateSet[0] = startState;"); 2753 2754 if (Options.getDebugTokenManager()) 2755 ostr.println(" debugStream.println(\" Starting NFA to match one of : \" + " + 2756 "jjKindsForStateVector(curLexState, jjstateSet, 0, 1));"); 2757 2758 if (Options.getDebugTokenManager()) 2759 ostr.println(" debugStream.println(" + (LexGen.maxLexStates > 1 ? "\"<\" + lexStateNames[curLexState] + \">\" + " : "") + "\"Current character : \" + " + 2760 "TokenMgrError.addEscapes(String.valueOf(curChar)) + \" (\" + (int)curChar + \") at line \" + input_stream.getLine() + \" column \" + input_stream.getColumn());"); 2761 2762 ostr.println(" int j, kind = 0x" + Integer.toHexString(Integer.MAX_VALUE) + ";"); 2763 ostr.println(" for (;;)"); 2764 ostr.println(" {"); 2765 ostr.println(" if (++jjround == 0x" + Integer.toHexString(Integer.MAX_VALUE) + ")"); 2766 ostr.println(" ReInitRounds();"); 2767 ostr.println(" if (curChar < 64)"); 2768 ostr.println(" {"); 2769 2770 DumpAsciiMoves(ostr, 0); 2771 2772 ostr.println(" }"); 2773 2774 ostr.println(" else if (curChar < 128)"); 2775 2776 ostr.println(" {"); 2777 2778 DumpAsciiMoves(ostr, 1); 2779 2780 ostr.println(" }"); 2781 2782 ostr.println(" else"); 2783 ostr.println(" {"); 2784 2785 DumpCharAndRangeMoves(ostr); 2786 2787 ostr.println(" }"); 2788 2789 ostr.println(" if (kind != 0x" + Integer.toHexString(Integer.MAX_VALUE) + ")"); 2790 ostr.println(" {"); 2791 ostr.println(" jjmatchedKind = kind;"); 2792 ostr.println(" jjmatchedPos = curPos;"); 2793 ostr.println(" kind = 0x" + Integer.toHexString(Integer.MAX_VALUE) + ";"); 2794 ostr.println(" }"); 2795 ostr.println(" ++curPos;"); 2796 2797 if (Options.getDebugTokenManager()) 2798 { 2799 ostr.println(" if (jjmatchedKind != 0 && jjmatchedKind != 0x" + Integer.toHexString(Integer.MAX_VALUE) + ")"); 2800 ostr.println(" debugStream.println(\" Currently matched the first \" + (jjmatchedPos + 1) + \" characters as a \" + tokenImage[jjmatchedKind] + \" token.\");"); 2801 } 2802 2803 ostr.println(" if ((i = jjnewStateCnt) == (startsAt = " + 2804 generatedStates + " - (jjnewStateCnt = startsAt)))"); 2805 if (LexGen.mixed[LexGen.lexStateIndex]) 2806 ostr.println(" break;"); 2807 else 2808 ostr.println(" return curPos;"); 2809 2810 if (Options.getDebugTokenManager()) 2811 ostr.println(" debugStream.println(\" Possible kinds of longer matches : \" + " + 2812 "jjKindsForStateVector(curLexState, jjstateSet, startsAt, i));"); 2813 2814 ostr.println(" try { curChar = input_stream.readChar(); }"); 2815 2816 if (LexGen.mixed[LexGen.lexStateIndex]) 2817 ostr.println(" catch(java.io.IOException e) { break; }"); 2818 else 2819 ostr.println(" catch(java.io.IOException e) { return curPos; }"); 2820 2821 if (Options.getDebugTokenManager()) 2822 ostr.println(" debugStream.println(" + (LexGen.maxLexStates > 1 ? "\"<\" + lexStateNames[curLexState] + \">\" + " : "") + "\"Current character : \" + " + 2823 "TokenMgrError.addEscapes(String.valueOf(curChar)) + \" (\" + (int)curChar + \") at line \" + input_stream.getLine() + \" column \" + input_stream.getColumn());"); 2824 2825 ostr.println(" }"); 2826 2827 if (LexGen.mixed[LexGen.lexStateIndex]) 2828 { 2829 ostr.println(" if (jjmatchedPos > strPos)"); 2830 ostr.println(" return curPos;"); 2831 ostr.println(""); 2832 ostr.println(" int toRet = Math.max(curPos, seenUpto);"); 2833 ostr.println(""); 2834 ostr.println(" if (curPos < toRet)"); 2835 ostr.println(" for (i = toRet - Math.min(curPos, seenUpto); i-- > 0; )"); 2836 ostr.println(" try { curChar = input_stream.readChar(); }"); 2837 ostr.println(" catch(java.io.IOException e) { throw new Error(\"Internal Error : Please send a bug report.\"); }"); 2838 ostr.println(""); 2839 ostr.println(" if (jjmatchedPos < strPos)"); 2840 ostr.println(" {"); 2841 ostr.println(" jjmatchedKind = strKind;"); 2842 ostr.println(" jjmatchedPos = strPos;"); 2843 ostr.println(" }"); 2844 ostr.println(" else if (jjmatchedPos == strPos && jjmatchedKind > strKind)"); 2845 ostr.println(" jjmatchedKind = strKind;"); 2846 ostr.println(""); 2847 ostr.println(" return toRet;"); 2848 } 2849 2850 ostr.println("}"); 2851 allStates.removeAllElements(); 2852 } 2853 2854 public static void DumpStatesForState(java.io.PrintWriter ostr) 2855 { 2856 ostr.print("protected static final int[][][] statesForState = "); 2857 2858 if (statesForState == null) 2859 { 2860 ostr.println("null;"); 2861 return; 2862 } 2863 else 2864 ostr.println("{"); 2865 2866 for (int i = 0; i < statesForState.length; i++) 2867 { 2868 2869 if (statesForState[i] == null) 2870 { 2871 ostr.println(" null, "); 2872 continue; 2873 } 2874 2875 ostr.println(" {"); 2876 2877 for (int j = 0; j < statesForState[i].length; j++) 2878 { 2879 int[] stateSet = statesForState[i][j]; 2880 2881 if (stateSet == null) 2882 { 2883 ostr.println(" { " + j + " }, "); 2884 continue; 2885 } 2886 2887 ostr.print(" { "); 2888 2889 for (int k = 0; k < stateSet.length; k++) 2890 ostr.print(stateSet[k] + ", "); 2891 2892 ostr.println("},"); 2893 } 2894 ostr.println(" },"); 2895 } 2896 ostr.println("\n};"); 2897 } 2898 2899 public static void DumpStatesForKind(java.io.PrintWriter ostr) 2900 { 2901 DumpStatesForState(ostr); 2902 boolean moreThanOne = false; 2903 int cnt = 0; 2904 2905 ostr.print("protected static final int[][] kindForState = "); 2906 2907 if (kinds == null) 2908 { 2909 ostr.println("null;"); 2910 return; 2911 } 2912 else 2913 ostr.println("{"); 2914 2915 for (int i = 0; i < kinds.length; i++) 2916 { 2917 if (moreThanOne) 2918 ostr.println(", "); 2919 moreThanOne = true; 2920 2921 if (kinds[i] == null) 2922 ostr.println("null"); 2923 else 2924 { 2925 cnt = 0; 2926 ostr.print("{ "); 2927 for (int j = 0; j < kinds[i].length; j++) 2928 { 2929 if (cnt++ > 0) 2930 ostr.print(", "); 2931 2932 if (cnt % 15 == 0) 2933 ostr.print("\n "); 2934 2935 ostr.print(kinds[i][j]); 2936 } 2937 ostr.print("}"); 2938 } 2939 } 2940 ostr.println("\n};"); 2941 } 2942 2943 public static void reInit() 2944 { 2945 unicodeWarningGiven = false; 2946 generatedStates = 0; 2947 idCnt = 0; 2948 lohiByteCnt = 0; 2949 dummyStateIndex = -1; 2950 done = false; 2951 mark = null; 2952 stateDone = null; 2953 nonAsciiIntersections = new boolean[20][20]; 2954 allStates = new Vector(); 2955 indexedAllStates = new Vector(); 2956 nonAsciiTableForMethod = new Vector(); 2957 equivStatesTable = new Hashtable(); 2958 allNextStates = new Hashtable(); 2959 lohiByteTab = new Hashtable(); 2960 stateNameForComposite = new Hashtable(); 2961 compositeStateTable = new Hashtable(); 2962 stateBlockTable = new Hashtable(); 2963 stateSetsToFix = new Hashtable(); 2964 allBitVectors = new Vector(); 2965 tmpIndices = new int[512]; 2966 allBits = "{\n 0xffffffffffffffffL, " + 2967 "0xffffffffffffffffL, " + 2968 "0xffffffffffffffffL, " + 2969 "0xffffffffffffffffL\n};"; 2970 tableToDump = new Hashtable(); 2971 orderedStateSet = new Vector(); 2972 lastIndex = 0; 2973 boilerPlateDumped = false; 2974 kinds = null; 2975 statesForState = null; 2976 } 2977 2978} 2979 | Popular Tags |