001/* 002 * Units of Measurement Systems 003 * Copyright (c) 2005-2021, Jean-Marie Dautelle, Werner Keil and others. 004 * 005 * All rights reserved. 006 * 007 * Redistribution and use in source and binary forms, with or without modification, 008 * are permitted provided that the following conditions are met: 009 * 010 * 1. Redistributions of source code must retain the above copyright notice, 011 * this list of conditions and the following disclaimer. 012 * 013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions 014 * and the following disclaimer in the documentation and/or other materials provided with the distribution. 015 * 016 * 3. Neither the name of JSR-385, Units of Measurement nor the names of their contributors may be used to 017 * endorse or promote products derived from this software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package systems.uom.ucum.internal.format; 031 032import static systems.uom.ucum.internal.format.UnitTokenConstants.*; 033import static tech.units.indriya.AbstractUnit.ONE; 034 035import javax.measure.Unit; 036import javax.measure.Prefix; 037 038import tech.units.indriya.format.SymbolMap; 039import tech.units.indriya.function.LogConverter; 040import tech.units.indriya.function.MultiplyConverter; 041 042 043@SuppressWarnings({"rawtypes", "unchecked"}) 044public final class UnitFormatParser { 045 046 private static class Exponent { 047 048 public final int pow; 049 050 public final int root; 051 052 public Exponent(int pow, int root) { 053 this.pow = pow; 054 this.root = root; 055 } 056 } 057 private SymbolMap symbols; 058 059 public UnitFormatParser(SymbolMap symbols, java.io.Reader in) { 060 this(in); 061 this.symbols = symbols; 062 } 063 064 065 final public Unit parseUnit() throws TokenException { 066 Unit result = CompoundExpr(); 067 consumeToken(0); 068 { 069 return result; 070 } 071 } 072 073 final public Unit CompoundExpr() throws TokenException { 074 throw new UnsupportedOperationException("Compound units not supported"); 075 } 076 077 final public Unit AddExpr() throws TokenException { 078 Unit result = ONE; 079 Number n1 = null; 080 Token sign1 = null; 081 Number n2 = null; 082 Token sign2 = null; 083 if (jj_2_1(2147483647)) { 084 n1 = NumberExpr(); 085 sign1 = Sign(); 086 } else { 087 } 088 result = MulExpr(); 089 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 090 case PLUS: 091 case MINUS: 092 sign2 = Sign(); 093 n2 = NumberExpr(); 094 break; 095 default: 096 laA[1] = genInt; 097 } 098 if (n1 != null) { 099 if (sign1.image.equals("-")) { 100 result = result.multiply(-1); 101 } 102 result = result.shift(n1.doubleValue()); 103 } 104 if (n2 != null) { 105 double offset = n2.doubleValue(); 106 if (sign2.image.equals("-")) { 107 offset = -offset; 108 } 109 result = result.shift(offset); 110 } 111 { 112 return result; 113 } 114 } 115 116 final public Unit MulExpr() throws TokenException { 117 Unit result = ONE; 118 Unit temp = ONE; 119 result = ExponentExpr(); 120 label_2: 121 while (true) { 122 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 123 case ASTERISK: 124 case MIDDLE_DOT: 125 case SOLIDUS: 126 break; 127 default: 128 laA[2] = genInt; 129 break label_2; 130 } 131 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 132 case ASTERISK: 133 case MIDDLE_DOT: 134 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 135 case ASTERISK: 136 consumeToken(ASTERISK); 137 break; 138 case MIDDLE_DOT: 139 consumeToken(MIDDLE_DOT); 140 break; 141 default: 142 laA[3] = genInt; 143 consumeToken(-1); 144 throw new TokenException(); 145 } 146 temp = ExponentExpr(); 147 result = result.multiply(temp); 148 break; 149 case SOLIDUS: 150 consumeToken(SOLIDUS); 151 temp = ExponentExpr(); 152 result = result.divide(temp); 153 break; 154 default: 155 laA[4] = genInt; 156 consumeToken(-1); 157 throw new TokenException(); 158 } 159 } 160 { 161 return result; 162 } 163 } 164 165 final public Unit ExponentExpr() throws TokenException { 166 Unit result = ONE; 167 Exponent exponent = null; 168 Token token = null; 169 if (jj_2_2(2147483647)) { 170 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 171 case INTEGER: 172 token = consumeToken(INTEGER); 173 break; 174 case E: 175 token = consumeToken(E); 176 break; 177 default: 178 laA[5] = genInt; 179 consumeToken(-1); 180 throw new TokenException(); 181 } 182 consumeToken(CARET); 183 result = AtomicExpr(); 184 double base; 185 if (token.kind == INTEGER) { 186 base = Integer.parseInt(token.image); 187 } else { 188 base = StrictMath.E; 189 } 190 { 191 return result.transform(new LogConverter(base).inverse()); 192 } 193 } else { 194 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 195 case OPEN_PAREN: 196 case INTEGER: 197 case FLOATING_POINT: 198 case UNIT_IDENTIFIER: 199 result = AtomicExpr(); 200 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 201 case CARET: 202 case SUPERSCRIPT_INTEGER: 203 exponent = Exp(); 204 break; 205 default: 206 laA[6] = genInt; 207 } 208 if (exponent != null) { 209 if (exponent.pow != 1) { 210 result = result.pow(exponent.pow); 211 } 212 if (exponent.root != 1) { 213 result = result.root(exponent.root); 214 } 215 } { 216 return result; 217 } 218 case LOG: 219 case NAT_LOG: 220 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 221 case LOG: 222 consumeToken(LOG); 223 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 224 case INTEGER: 225 token = consumeToken(INTEGER); 226 break; 227 default: 228 laA[7] = genInt; 229 } 230 break; 231 case NAT_LOG: 232 token = consumeToken(NAT_LOG); 233 break; 234 default: 235 laA[8] = genInt; 236 consumeToken(-1); 237 throw new TokenException(); 238 } 239 consumeToken(OPEN_PAREN); 240 result = AddExpr(); 241 consumeToken(CLOSE_PAREN); 242 double base = 10; 243 if (token != null) { 244 if (token.kind == INTEGER) { 245 base = Integer.parseInt(token.image); 246 } else if (token.kind == NAT_LOG) { 247 base = StrictMath.E; 248 } 249 } { 250 return result.transform(new LogConverter(base)); 251 } 252 default: 253 laA[9] = genInt; 254 consumeToken(-1); 255 throw new TokenException(); 256 } 257 } 258 } 259 260 final public Unit AtomicExpr() throws TokenException { 261 Unit result = ONE; 262 Number n = null; 263 Token token = null; 264 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 265 case INTEGER: 266 case FLOATING_POINT: 267 n = NumberExpr(); 268 if (n instanceof Integer) { 269 { 270 return result.multiply(n.intValue()); 271 } 272 } else { 273 { 274 return result.multiply(n.doubleValue()); 275 } 276 } 277 case UNIT_IDENTIFIER: 278 token = consumeToken(UNIT_IDENTIFIER); 279 Unit unit = symbols.getUnit(token.image); 280 if (unit == null) { 281 Prefix prefix = symbols.getPrefix(token.image); 282 if (prefix != null) { 283 String prefixSymbol = symbols.getSymbol(prefix); 284 unit = symbols.getUnit(token.image.substring(prefixSymbol.length())); 285 if (unit != null) { 286 { 287 return unit.transform(MultiplyConverter.ofPrefix(prefix)); 288 } 289 } 290 } 291 { 292 throw new TokenException(); 293 } 294 } else { 295 { 296 return unit; 297 } 298 } 299 case OPEN_PAREN: 300 consumeToken(OPEN_PAREN); 301 result = AddExpr(); 302 consumeToken(CLOSE_PAREN); { 303 return result; 304 } 305 default: 306 laA[10] = genInt; 307 consumeToken(-1); 308 throw new TokenException(); 309 } 310 } 311 312 final public Token Sign() throws TokenException { 313 Token result = null; 314 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 315 case PLUS: 316 result = consumeToken(PLUS); 317 break; 318 case MINUS: 319 result = consumeToken(MINUS); 320 break; 321 default: 322 laA[11] = genInt; 323 consumeToken(-1); 324 throw new TokenException(); 325 } 326 { 327 return result; 328 } 329 } 330 331 final public Number NumberExpr() throws TokenException { 332 Token token = null; 333 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 334 case INTEGER: 335 token = consumeToken(INTEGER); { 336 return Long.valueOf(token.image); 337 } 338 case FLOATING_POINT: 339 token = consumeToken(FLOATING_POINT); { 340 return Double.valueOf(token.image); 341 } 342 default: 343 laA[12] = genInt; 344 consumeToken(-1); 345 throw new TokenException(); 346 } 347 } 348 349 final public Exponent Exp() throws TokenException { 350 Token powSign = null; 351 Token powToken = null; 352 Token rootSign = null; 353 Token rootToken = null; 354 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 355 case CARET: 356 consumeToken(CARET); 357 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 358 case PLUS: 359 case MINUS: 360 case INTEGER: 361 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 362 case PLUS: 363 case MINUS: 364 powSign = Sign(); 365 break; 366 default: 367 laA[13] = genInt; 368 } 369 powToken = consumeToken(INTEGER); 370 int pow = Integer.parseInt(powToken.image); 371 if ((powSign != null) && powSign.image.equals("-")) { 372 pow = -pow; 373 } { 374 return new Exponent(pow, 1); 375 } 376 case OPEN_PAREN: 377 consumeToken(OPEN_PAREN); 378 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 379 case PLUS: 380 case MINUS: 381 powSign = Sign(); 382 break; 383 default: 384 laA[14] = genInt; 385 } 386 powToken = consumeToken(INTEGER); 387 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 388 case SOLIDUS: 389 consumeToken(SOLIDUS); 390 switch ((nextTokenIndex == -1) ? jj_ntk() : nextTokenIndex) { 391 case PLUS: 392 case MINUS: 393 rootSign = Sign(); 394 break; 395 default: 396 laA[15] = genInt; 397 } 398 rootToken = consumeToken(INTEGER); 399 break; 400 default: 401 laA[16] = genInt; 402 } 403 consumeToken(CLOSE_PAREN); 404 pow = Integer.parseInt(powToken.image); 405 if ((powSign != null) && powSign.image.equals("-")) { 406 pow = -pow; 407 } 408 int root = 1; 409 if (rootToken != null) { 410 root = Integer.parseInt(rootToken.image); 411 if ((rootSign != null) && rootSign.image.equals("-")) { 412 root = -root; 413 } 414 } { 415 return new Exponent(pow, root); 416 } 417 default: 418 laA[17] = genInt; 419 consumeToken(-1); 420 throw new TokenException(); 421 } 422 case SUPERSCRIPT_INTEGER: 423 powToken = consumeToken(SUPERSCRIPT_INTEGER); 424 int pow = 0; 425 for (int i = 0; i < powToken.image.length(); i += 1) { 426 pow *= 10; 427 switch (powToken.image.charAt(i)) { 428 case '\u00b9': 429 pow += 1; 430 break; 431 case '\u00b2': 432 pow += 2; 433 break; 434 case '\u00b3': 435 pow += 3; 436 break; 437 case '\u2074': 438 pow += 4; 439 break; 440 case '\u2075': 441 pow += 5; 442 break; 443 case '\u2076': 444 pow += 6; 445 break; 446 case '\u2077': 447 pow += 7; 448 break; 449 case '\u2078': 450 pow += 8; 451 break; 452 case '\u2079': 453 pow += 9; 454 break; 455 } 456 } { 457 return new Exponent(pow, 1); 458 } 459 default: 460 laA[18] = genInt; 461 consumeToken(-1); 462 throw new TokenException(); 463 } 464 } 465 466 private boolean jj_2_1(int xla) { 467 laInt = xla; 468 lastpos = scanpos = token; 469 try { 470 return !jj_3_1(); 471 } catch (LookaheadSuccess ls) { 472 return true; 473 } finally { 474 jj_save(0, xla); 475 } 476 } 477 478 private boolean jj_2_2(int xla) { 479 laInt = xla; 480 lastpos = scanpos = token; 481 try { 482 return !jj_3_2(); 483 } catch (LookaheadSuccess ls) { 484 return true; 485 } finally { 486 jj_save(1, xla); 487 } 488 } 489 490 private boolean jj_3R_3() { 491 Token xsp; 492 xsp = scanpos; 493 if (jj_3R_5()) { 494 scanpos = xsp; 495 if (jj_3R_6()) 496 return true; 497 } 498 return false; 499 } 500 501 private boolean jj_3R_6() { 502 return scanToken(FLOATING_POINT); 503 } 504 505 private boolean jj_3_2() { 506 Token xsp; 507 xsp = scanpos; 508 if (scanToken(14)) { 509 scanpos = xsp; 510 if (scanToken(19)) 511 return true; 512 } 513 return scanToken(CARET); 514 } 515 516 private boolean jj_3_1() { 517 return jj_3R_3() || jj_3R_4(); 518 } 519 520 private boolean jj_3R_4() { 521 Token xsp; 522 xsp = scanpos; 523 if (scanToken(5)) { 524 scanpos = xsp; 525 if (scanToken(6)) 526 return true; 527 } 528 return false; 529 } 530 531 private boolean jj_3R_5() { 532 return scanToken(INTEGER); 533 } 534 /** Generated Token Manager. */ 535 public UnitTokenManager tokenSource; 536 537 UCUMCharStream inputStream; 538 539 /** Current token. */ 540 public Token token; 541 542 /** Next token. */ 543 public Token nextToken; 544 545 private int nextTokenIndex; 546 547 private Token scanpos, lastpos; 548 549 private int laInt; 550 551 private int genInt; 552 553 final private int[] laA = new int[19]; 554 555 static private int[] laB; 556 557 static { 558 init(); 559 } 560 561 private static void init() { 562 laB = new int[]{0x800, 0x60, 0x380, 0x180, 0x380, 0x84000, 0x8400, 0x4000, 0x60000, 0x175000, 0x115000, 0x60, 0x14000, 0x60, 0x60, 0x60, 0x200, 0x5060, 0x8400,}; 563 } 564 final private JJCalls[] rtns = new JJCalls[2]; 565 566 private boolean rescan = false; 567 568 private int gcInt = 0; 569 570 /** Constructor with InputStream. */ 571 public UnitFormatParser(java.io.InputStream stream) { 572 this(stream, null); 573 } 574 575 /** Constructor with InputStream and supplied encoding */ 576 public UnitFormatParser(java.io.InputStream stream, String encoding) { 577 try { 578 inputStream = new UCUMCharStream(stream, encoding, 1, 1); 579 } catch (java.io.UnsupportedEncodingException e) { 580 throw new RuntimeException(e); 581 } 582 tokenSource = new UnitTokenManager(inputStream); 583 token = new Token(); 584 nextTokenIndex = -1; 585 genInt = 0; 586 for (int i = 0; i < 19; i++) { 587 laA[i] = -1; 588 } 589 for (int i = 0; i < rtns.length; i++) { 590 rtns[i] = new JJCalls(); 591 } 592 } 593 594 /** Reinitialise. */ 595 public void ReInit(java.io.InputStream stream) { 596 ReInit(stream, null); 597 } 598 599 /** Reinitialise. */ 600 public void ReInit(java.io.InputStream stream, String encoding) { 601 try { 602 inputStream.ReInit(stream, encoding, 1, 1); 603 } catch (java.io.UnsupportedEncodingException e) { 604 throw new RuntimeException(e); 605 } 606 tokenSource.ReInit(inputStream); 607 token = new Token(); 608 nextTokenIndex = -1; 609 genInt = 0; 610 for (int i = 0; i < 19; i++) { 611 laA[i] = -1; 612 } 613 for (int i = 0; i < rtns.length; i++) { 614 rtns[i] = new JJCalls(); 615 } 616 } 617 618 /** Constructor. */ 619 public UnitFormatParser(java.io.Reader stream) { 620 inputStream = new UCUMCharStream(stream, 1, 1); 621 tokenSource = new UnitTokenManager(inputStream); 622 token = new Token(); 623 nextTokenIndex = -1; 624 genInt = 0; 625 for (int i = 0; i < 19; i++) { 626 laA[i] = -1; 627 } 628 for (int i = 0; i < rtns.length; i++) { 629 rtns[i] = new JJCalls(); 630 } 631 } 632 633 /** Reinitialise. */ 634 public void ReInit(java.io.Reader stream) { 635 inputStream.ReInit(stream, 1, 1); 636 tokenSource.ReInit(inputStream); 637 token = new Token(); 638 nextTokenIndex = -1; 639 genInt = 0; 640 for (int i = 0; i < 19; i++) { 641 laA[i] = -1; 642 } 643 for (int i = 0; i < rtns.length; i++) { 644 rtns[i] = new JJCalls(); 645 } 646 } 647 648 /** Constructor with generated Token Manager. */ 649 public UnitFormatParser(UnitTokenManager tm) { 650 tokenSource = tm; 651 token = new Token(); 652 nextTokenIndex = -1; 653 genInt = 0; 654 for (int i = 0; i < 19; i++) { 655 laA[i] = -1; 656 } 657 for (int i = 0; i < rtns.length; i++) { 658 rtns[i] = new JJCalls(); 659 } 660 } 661 662 /** Reinitialise. */ 663 public void ReInit(UnitTokenManager tm) { 664 tokenSource = tm; 665 token = new Token(); 666 nextTokenIndex = -1; 667 genInt = 0; 668 for (int i = 0; i < 19; i++) { 669 laA[i] = -1; 670 } 671 for (int i = 0; i < rtns.length; i++) { 672 rtns[i] = new JJCalls(); 673 } 674 } 675 676 private Token consumeToken(int kind) throws TokenException { 677 Token oldToken; 678 if ((oldToken = token).next != null) 679 token = token.next; 680 else 681 token = token.next = tokenSource.getNextToken(); 682 nextTokenIndex = -1; 683 if (token.kind == kind) { 684 genInt++; 685 if (++gcInt > 100) { 686 gcInt = 0; 687 for (JJCalls jj_2_rtn : rtns) { 688 JJCalls c = jj_2_rtn; 689 while (c != null) { 690 if (c.gen < genInt) 691 c.first = null; 692 c = c.next; 693 } 694 } 695 } 696 return token; 697 } 698 token = oldToken; 699 this.kind = kind; 700 throw raiseTokenException(); 701 } 702 703 static private final class LookaheadSuccess extends java.lang.RuntimeException { 704 private static final long serialVersionUID = 2205332054119123041L; 705 } 706 707 private boolean scanToken(int kind) { 708 if (scanpos == lastpos) { 709 laInt--; 710 if (scanpos.next == null) { 711 lastpos = scanpos = scanpos.next = tokenSource.getNextToken(); 712 } else { 713 lastpos = scanpos = scanpos.next; 714 } 715 } else { 716 scanpos = scanpos.next; 717 } 718 if (rescan) { 719 int i = 0; 720 Token tok = token; 721 while (tok != null && tok != scanpos) { 722 i++; 723 tok = tok.next; 724 } 725 if (tok != null) 726 jj_add_error_token(kind, i); 727 } 728 if (scanpos.kind != kind) 729 return true; 730 if (laInt == 0 && scanpos == lastpos) 731 throw new LookaheadSuccess(); 732 return false; 733 } 734 735 /** Get the next Token. */ 736 final public Token getNextToken() { 737 if (token.next != null) 738 token = token.next; 739 else 740 token = token.next = tokenSource.getNextToken(); 741 nextTokenIndex = -1; 742 genInt++; 743 return token; 744 } 745 746 /** Get the specific Token. */ 747 final public Token getToken(int index) { 748 Token t = token; 749 for (int i = 0; i < index; i++) { 750 if (t.next != null) 751 t = t.next; 752 else 753 t = t.next = tokenSource.getNextToken(); 754 } 755 return t; 756 } 757 758 private int jj_ntk() { 759 if ((nextToken = token.next) == null) { 760 return (nextTokenIndex = (token.next = tokenSource.getNextToken()).kind); 761 } 762 else { 763 return (nextTokenIndex = nextToken.kind); 764 } 765 } 766 private java.util.List<int[]> expentries = new java.util.ArrayList<>(); 767 768 private int[] expentry; 769 770 private int kind = -1; 771 772 private int[] lastTokens = new int[100]; 773 774 private int endpos; 775 776 private void jj_add_error_token(int kind, int pos) { 777 if (pos >= 100) 778 return; 779 if (pos == endpos + 1) { 780 lastTokens[endpos++] = kind; 781 } else if (endpos != 0) { 782 expentry = new int[endpos]; 783 System.arraycopy(lastTokens, 0, expentry, 0, endpos); 784 entriesLoop: 785 for (int[] jj_expentry1 : expentries) { 786 if (jj_expentry1.length == expentry.length) { 787 for (int i = 0; i < expentry.length; i++) { 788 if (jj_expentry1[i] != expentry[i]) { 789 continue entriesLoop; 790 } 791 } 792 expentries.add(expentry); 793 break; 794 } 795 } 796 if (pos != 0) 797 lastTokens[(endpos = pos) - 1] = kind; 798 } 799 } 800 801 /** Generate TokenException. */ 802 TokenException raiseTokenException() { 803 expentries.clear(); 804 boolean[] la1tokens = new boolean[21]; 805 if (kind >= 0) { 806 la1tokens[kind] = true; 807 kind = -1; 808 } 809 for (int i = 0; i < 19; i++) { 810 if (laA[i] == genInt) { 811 for (int j = 0; j < 32; j++) { 812 if ((laB[i] & (1 << j)) != 0) { 813 la1tokens[j] = true; 814 } 815 } 816 } 817 } 818 for (int i = 0; i < 21; i++) { 819 if (la1tokens[i]) { 820 expentry = new int[1]; 821 expentry[0] = i; 822 expentries.add(expentry); 823 } 824 } 825 endpos = 0; 826 jj_rescan_token(); 827 jj_add_error_token(0, 0); 828 int[][] exptokseq = new int[expentries.size()][]; 829 for (int i = 0; i < expentries.size(); i++) { 830 exptokseq[i] = expentries.get(i); 831 } 832 return new TokenException(token, exptokseq, tokenImage); 833 } 834 835 /** Enable tracing. */ 836 final public void enable_tracing() { 837 } 838 839 /** Disable tracing. */ 840 final public void disable_tracing() { 841 } 842 843 private void jj_rescan_token() { 844 rescan = true; 845 for (int i = 0; i < 2; i++) { 846 try { 847 JJCalls p = rtns[i]; 848 do { 849 if (p.gen > genInt) { 850 laInt = p.arg; 851 lastpos = scanpos = p.first; 852 switch (i) { 853 case 0: 854 jj_3_1(); 855 break; 856 case 1: 857 jj_3_2(); 858 break; 859 } 860 } 861 p = p.next; 862 } while (p != null); 863 } catch (LookaheadSuccess ls) { 864 } 865 } 866 rescan = false; 867 } 868 869 private void jj_save(int index, int xla) { 870 JJCalls p = rtns[index]; 871 while (p.gen > genInt) { 872 if (p.next == null) { 873 p = p.next = new JJCalls(); 874 break; 875 } 876 p = p.next; 877 } 878 p.gen = genInt + xla - laInt; 879 p.first = token; 880 p.arg = xla; 881 } 882 883 static final class JJCalls { 884 885 int gen; 886 887 Token first; 888 889 int arg; 890 891 JJCalls next; 892 893 } 894}