001/* 002 * Units of Measurement Reference Implementation 003 * Copyright (c) 2005-2021, Jean-Marie Dautelle, Werner Keil, Otavio Santana. 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, Indriya nor the names of their contributors may be used to endorse or promote products 017 * 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 tech.units.indriya.internal.format; 031 032import static org.apiguardian.api.API.Status.INTERNAL; 033 034import javax.measure.MeasurementError; 035import javax.measure.Prefix; 036import javax.measure.Unit; 037 038import org.apiguardian.api.API; 039 040import tech.units.indriya.AbstractUnit; 041import tech.units.indriya.format.SymbolMap; 042import tech.units.indriya.format.Token; 043import tech.units.indriya.format.TokenException; 044import tech.units.indriya.function.LogConverter; 045import tech.units.indriya.function.MultiplyConverter; 046 047@API(status=INTERNAL) 048public final class UnitFormatParser implements UnitTokenConstants { 049 050 private static class Exponent { 051 final int pow; 052 final int root; 053 054 public Exponent(int pow, int root) { 055 this.pow = pow; 056 this.root = root; 057 } 058 } 059 060 private SymbolMap symbols; 061 062 public UnitFormatParser(SymbolMap symbols, java.io.Reader in) { // TODO visiblity 063 this(in); 064 this.symbols = symbols; 065 } 066 067 // 068 // Parser productions 069 // 070 @SuppressWarnings("unused") 071 public Unit<?> parseUnit() throws TokenException { // TODO visibility 072 Unit<?> result; 073 result = mixExpr(); 074 jj_consume_token(0); 075 { 076 if (true) 077 return result; 078 } 079 throw new MeasurementError("Missing return statement in function"); 080 } 081 082 @SuppressWarnings("unused") 083 Unit<?> mixExpr() throws TokenException { 084 Unit<?> result = AbstractUnit.ONE; 085 result = addExpr(); 086 label_1: while (true) { 087 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 088 case COLON: 089 break; 090 default: 091 jj_la1[0] = jj_gen; 092 break label_1; 093 } 094 jj_consume_token(COLON); 095 } 096 { 097 if (true) 098 return result; 099 } 100 throw new MeasurementError("Missing return statement in function"); 101 } 102 103 @SuppressWarnings("unused") 104 Unit<?> addExpr() throws TokenException { 105 Unit<?> result = AbstractUnit.ONE; 106 Number n1 = null; 107 Token sign1 = null; 108 Number n2 = null; 109 Token sign2 = null; 110 if (jj_2_1(2147483647)) { 111 n1 = numberExpr(); 112 sign1 = sign(); 113 } else { 114 } 115 result = mulExpr(); 116 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 117 case PLUS: 118 case MINUS: 119 sign2 = sign(); 120 n2 = numberExpr(); 121 break; 122 default: 123 jj_la1[1] = jj_gen; 124 } 125 if (n1 != null) { 126 if (sign1.image.equals("-")) { 127 result = result.multiply(-1); 128 } 129 result = result.shift(n1.doubleValue()); 130 } 131 if (n2 != null) { 132 double offset = n2.doubleValue(); 133 if ("-".equals(sign2.image)) { 134 offset = -offset; 135 } 136 result = result.shift(offset); 137 } 138 { 139 if (true) 140 return result; 141 } 142 throw new MeasurementError("Missing return statement in function"); 143 } 144 145 Unit<?> mulExpr() throws TokenException { 146 Unit<?> result = AbstractUnit.ONE; 147 Unit<?> temp = AbstractUnit.ONE; 148 result = exponentExpr(); 149 label_2: while (true) { 150 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 151 case ASTERISK: 152 case MIDDLE_DOT: 153 case SOLIDUS: 154 break; 155 default: 156 jj_la1[2] = jj_gen; 157 break label_2; 158 } 159 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 160 case ASTERISK: 161 case MIDDLE_DOT: 162 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 163 case ASTERISK: 164 jj_consume_token(ASTERISK); 165 break; 166 case MIDDLE_DOT: 167 jj_consume_token(MIDDLE_DOT); 168 break; 169 default: 170 jj_la1[3] = jj_gen; 171 jj_consume_token(-1); 172 throw new TokenException(); 173 } 174 temp = exponentExpr(); 175 result = result.multiply(temp); 176 break; 177 case SOLIDUS: 178 jj_consume_token(SOLIDUS); 179 temp = exponentExpr(); 180 result = result.divide(temp); 181 break; 182 default: 183 jj_la1[4] = jj_gen; 184 jj_consume_token(-1); 185 throw new TokenException(); 186 } 187 } 188 // {if (true) 189 return result;// } 190 // throw new MeasurementError("Missing return statement in function"); 191 } 192 193 @SuppressWarnings("unused") 194 Unit<?> exponentExpr() throws TokenException { 195 Unit<?> result = AbstractUnit.ONE; 196 Exponent exponent = null; 197 Token theToken = null; 198 if (jj_2_2(2147483647)) { 199 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 200 case INTEGER: 201 theToken = jj_consume_token(INTEGER); 202 break; 203 case E: 204 theToken = jj_consume_token(E); 205 break; 206 default: 207 jj_la1[5] = jj_gen; 208 jj_consume_token(-1); 209 throw new TokenException(); 210 } 211 jj_consume_token(CARET); 212 result = atomicExpr(); 213 double base; 214 if (theToken.kind == INTEGER) { 215 base = Integer.parseInt(theToken.image); 216 } else { 217 base = E; 218 } 219 { 220 if (true) 221 return result.transform(new LogConverter(base).inverse()); 222 } 223 } else { 224 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 225 case OPEN_PAREN: 226 case INTEGER: 227 case FLOATING_POINT: 228 case UNIT_IDENTIFIER: 229 result = atomicExpr(); 230 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 231 case CARET: 232 case SUPERSCRIPT_INTEGER: 233 exponent = exp(); 234 break; 235 default: 236 jj_la1[6] = jj_gen; 237 } 238 if (exponent != null) { 239 if (exponent.pow != 1) { 240 result = result.pow(exponent.pow); 241 } 242 if (exponent.root != 1) { 243 result = result.root(exponent.root); 244 } 245 } 246 return result; 247 case LOG: 248 case NAT_LOG: 249 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 250 case LOG: 251 jj_consume_token(LOG); 252 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 253 case INTEGER: 254 theToken = jj_consume_token(INTEGER); 255 break; 256 default: 257 jj_la1[7] = jj_gen; 258 } 259 break; 260 case NAT_LOG: 261 theToken = jj_consume_token(NAT_LOG); 262 break; 263 default: 264 jj_la1[8] = jj_gen; 265 jj_consume_token(-1); 266 throw new TokenException(); 267 } 268 jj_consume_token(OPEN_PAREN); 269 result = addExpr(); 270 jj_consume_token(CLOSE_PAREN); 271 double base = 10; 272 if (theToken != null) { 273 if (theToken.kind == INTEGER) { 274 base = Integer.parseInt(theToken.image); 275 } else if (theToken.kind == NAT_LOG) { 276 base = E; 277 } 278 } 279 return result.transform(new LogConverter(base)); 280 default: 281 jj_la1[9] = jj_gen; 282 jj_consume_token(-1); 283 throw new TokenException(); 284 } 285 } 286 throw new MeasurementError("Missing return statement in function"); 287 } 288 289 Unit<?> atomicExpr() throws TokenException { 290 Unit<?> result = AbstractUnit.ONE; 291 // Unit<?> temp = AbstractUnit.ONE; 292 Number n = null; 293 Token theToken = null; 294 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 295 case INTEGER: 296 case FLOATING_POINT: 297 n = numberExpr(); 298 return n instanceof Integer ? result.multiply(n.intValue()) : result.multiply(n.doubleValue()); 299 case UNIT_IDENTIFIER: 300 theToken = jj_consume_token(UNIT_IDENTIFIER); 301 Unit<?> unit = symbols.getUnit(theToken.image); 302 if (unit == null) { 303 Prefix prefix = symbols.getPrefix(theToken.image); 304 if (prefix != null) { 305 String prefixSymbol = symbols.getSymbol(prefix); 306 unit = symbols.getUnit(theToken.image.substring(prefixSymbol.length())); 307 if (unit != null) { 308 { 309 if (true) 310 return unit.transform(MultiplyConverter.ofPrefix(prefix)); // TODO try unit.multiply(factor) 311 } 312 } 313 } 314 throw new TokenException(); 315 } 316 return unit; 317 case OPEN_PAREN: 318 jj_consume_token(OPEN_PAREN); 319 result = addExpr(); 320 jj_consume_token(CLOSE_PAREN); 321 return result; 322 default: 323 jj_la1[10] = jj_gen; 324 jj_consume_token(-1); 325 throw new TokenException(); 326 } 327 // throw new MeasurementError("Missing return statement in function"); 328 } 329 330 @SuppressWarnings("unused") 331 Token sign() throws TokenException { 332 Token result = null; 333 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 334 case PLUS: 335 result = jj_consume_token(PLUS); 336 break; 337 case MINUS: 338 result = jj_consume_token(MINUS); 339 break; 340 default: 341 jj_la1[11] = jj_gen; 342 jj_consume_token(-1); 343 throw new TokenException(); 344 } 345 { 346 if (true) 347 return result; 348 } 349 throw new MeasurementError("Missing return statement in function"); 350 } 351 352 Number numberExpr() throws TokenException { 353 Token theToken = null; 354 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 355 case INTEGER: 356 theToken = jj_consume_token(INTEGER); 357 return Long.valueOf(theToken.image); 358 case FLOATING_POINT: 359 theToken = jj_consume_token(FLOATING_POINT); 360 return Double.valueOf(theToken.image); 361 default: 362 jj_la1[12] = jj_gen; 363 jj_consume_token(-1); 364 throw new TokenException(); 365 } 366 // throw new MeasurementError("Missing return statement in function"); 367 } 368 369 Exponent exp() throws TokenException { 370 Token powSign = null; 371 Token powToken = null; 372 Token rootSign = null; 373 Token rootToken = null; 374 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 375 case CARET: 376 jj_consume_token(CARET); 377 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 378 case PLUS: 379 case MINUS: 380 case INTEGER: 381 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 382 case PLUS: 383 case MINUS: 384 powSign = sign(); 385 break; 386 default: 387 jj_la1[13] = jj_gen; 388 } 389 powToken = jj_consume_token(INTEGER); 390 int pow = Integer.parseInt(powToken.image); 391 if ((powSign != null) && powSign.image.equals("-")) { 392 pow = -pow; 393 } 394 return new Exponent(pow, 1); 395 case OPEN_PAREN: 396 jj_consume_token(OPEN_PAREN); 397 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 398 case PLUS: 399 case MINUS: 400 powSign = sign(); 401 break; 402 default: 403 jj_la1[14] = jj_gen; 404 } 405 powToken = jj_consume_token(INTEGER); 406 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 407 case SOLIDUS: 408 jj_consume_token(SOLIDUS); 409 switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { 410 case PLUS: 411 case MINUS: 412 rootSign = sign(); 413 break; 414 default: 415 jj_la1[15] = jj_gen; 416 } 417 rootToken = jj_consume_token(INTEGER); 418 break; 419 default: 420 jj_la1[16] = jj_gen; 421 } 422 jj_consume_token(CLOSE_PAREN); 423 pow = Integer.parseInt(powToken.image); 424 if ((powSign != null) && powSign.image.equals("-")) { 425 pow = -pow; 426 } 427 int root = 1; 428 if (rootToken != null) { 429 root = Integer.parseInt(rootToken.image); 430 if ((rootSign != null) && rootSign.image.equals("-")) { 431 root = -root; 432 } 433 } 434 return new Exponent(pow, root); 435 default: 436 jj_la1[17] = jj_gen; 437 jj_consume_token(-1); 438 throw new TokenException(); 439 } 440 case SUPERSCRIPT_INTEGER: 441 powToken = jj_consume_token(SUPERSCRIPT_INTEGER); 442 int pow = 0; 443 for (int i = 0; i < powToken.image.length(); i += 1) { 444 pow *= 10; 445 switch (powToken.image.charAt(i)) { 446 case '\u00b9': 447 pow += 1; 448 break; 449 case '\u00b2': 450 pow += 2; 451 break; 452 case '\u00b3': 453 pow += 3; 454 break; 455 case '\u2074': 456 pow += 4; 457 break; 458 case '\u2075': 459 pow += 5; 460 break; 461 case '\u2076': 462 pow += 6; 463 break; 464 case '\u2077': 465 pow += 7; 466 break; 467 case '\u2078': 468 pow += 8; 469 break; 470 case '\u2079': 471 pow += 9; 472 break; 473 } 474 } 475 return new Exponent(pow, 1); 476 default: 477 jj_la1[18] = jj_gen; 478 jj_consume_token(-1); 479 throw new TokenException(); 480 } 481 // throw new MeasurementError("Missing return statement in function"); 482 } 483 484 private boolean jj_2_1(int xla) { 485 jj_la = xla; 486 jj_lastpos = jj_scanpos = token; 487 try { 488 return !jj_3_1(); 489 } catch (LookaheadSuccess ls) { 490 return true; 491 } finally { 492 jj_save(0, xla); 493 } 494 } 495 496 private boolean jj_2_2(int xla) { 497 jj_la = xla; 498 jj_lastpos = jj_scanpos = token; 499 try { 500 return !jj_3_2(); 501 } catch (LookaheadSuccess ls) { 502 return true; 503 } finally { 504 jj_save(1, xla); 505 } 506 } 507 508 private boolean jj_3R_3() { 509 Token xsp; 510 xsp = jj_scanpos; 511 if (jj_3R_5()) { 512 jj_scanpos = xsp; 513 if (jj_3R_6()) 514 return true; 515 } 516 return false; 517 } 518 519 private boolean jj_3R_6() { 520 return jj_scan_token(FLOATING_POINT); 521 } 522 523 private boolean jj_3_2() { 524 Token xsp; 525 xsp = jj_scanpos; 526 if (jj_scan_token(14)) { 527 jj_scanpos = xsp; 528 if (jj_scan_token(19)) 529 return true; 530 } 531 return jj_scan_token(CARET); 532 } 533 534 private boolean jj_3_1() { 535 return jj_3R_3() || jj_3R_4(); 536 } 537 538 private boolean jj_3R_4() { 539 Token xsp; 540 xsp = jj_scanpos; 541 if (jj_scan_token(5)) { 542 jj_scanpos = xsp; 543 if (jj_scan_token(6)) 544 return true; 545 } 546 return false; 547 } 548 549 private boolean jj_3R_5() { 550 return jj_scan_token(INTEGER); 551 } 552 553 /** Generated Token Manager. */ 554 private UnitTokenManager token_source; 555 private DefaultCharStream jj_input_stream; 556 /** Current token. */ 557 private Token token; 558 /** Next token. */ 559 private Token jj_nt; 560 private int jj_ntk; 561 private Token jj_scanpos, jj_lastpos; 562 private int jj_la; 563 private int jj_gen; 564 final private int[] jj_la1 = new int[19]; 565 static private int[] jj_la1_0; 566 static { 567 jj_la1_init_0(); 568 } 569 570 private static void jj_la1_init_0() { 571 jj_la1_0 = new int[] { 0x800, 0x60, 0x380, 0x180, 0x380, 0x84000, 0x8400, 0x4000, 0x60000, 0x175000, 0x115000, 0x60, 0x14000, 0x60, 0x60, 0x60, 572 0x200, 0x5060, 0x8400, }; 573 } 574 575 final private JJCalls[] jj_2_rtns = new JJCalls[2]; 576 private boolean jj_rescan = false; 577 private int jj_gc = 0; 578 579 /** Constructor with InputStream. */ 580 UnitFormatParser(java.io.InputStream stream) { 581 this(stream, null); 582 } 583 584 /** Constructor with InputStream and supplied encoding */ 585 UnitFormatParser(java.io.InputStream stream, String encoding) { 586 try { 587 jj_input_stream = new DefaultCharStream(stream, encoding, 1, 1); 588 } catch (java.io.UnsupportedEncodingException e) { 589 throw new RuntimeException(e); 590 } 591 token_source = new UnitTokenManager(jj_input_stream); 592 token = new Token(); 593 jj_ntk = -1; 594 jj_gen = 0; 595 for (int i = 0; i < 19; i++) 596 jj_la1[i] = -1; 597 for (int i = 0; i < jj_2_rtns.length; i++) 598 jj_2_rtns[i] = new JJCalls(); 599 } 600 601 /** Constructor. */ 602 UnitFormatParser(java.io.Reader stream) { 603 jj_input_stream = new DefaultCharStream(stream, 1, 1); 604 token_source = new UnitTokenManager(jj_input_stream); 605 token = new Token(); 606 jj_ntk = -1; 607 jj_gen = 0; 608 for (int i = 0; i < 19; i++) 609 jj_la1[i] = -1; 610 for (int i = 0; i < jj_2_rtns.length; i++) 611 jj_2_rtns[i] = new JJCalls(); 612 } 613 614 /** Reinitialise. */ 615 // private void reInit(java.io.Reader stream) { 616 // jj_input_stream.reInit(stream, 1, 1); 617 // token_source.reInit(jj_input_stream); 618 // token = new Token(); 619 // jj_ntk = -1; 620 // jj_gen = 0; 621 // for (int i = 0; i < 19; i++) jj_la1[i] = -1; 622 // for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); 623 // } 624 625 /** Constructor with generated Token Manager. */ 626 UnitFormatParser(UnitTokenManager tm) { 627 token_source = tm; 628 token = new Token(); 629 jj_ntk = -1; 630 jj_gen = 0; 631 for (int i = 0; i < 19; i++) 632 jj_la1[i] = -1; 633 for (int i = 0; i < jj_2_rtns.length; i++) 634 jj_2_rtns[i] = new JJCalls(); 635 } 636 637 /** Reinitialise. */ 638 // private void reInit(UnitTokenManager tm) { 639 // token_source = tm; 640 // token = new Token(); 641 // jj_ntk = -1; 642 // jj_gen = 0; 643 // for (int i = 0; i < 19; i++) jj_la1[i] = -1; 644 // for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); 645 // } 646 647 private Token jj_consume_token(int kind) throws TokenException { 648 Token oldToken; 649 if ((oldToken = token).next != null) 650 token = token.next; 651 else 652 token = token.next = token_source.getNextToken(); 653 jj_ntk = -1; 654 if (token.kind == kind) { 655 jj_gen++; 656 if (++jj_gc > 100) { 657 jj_gc = 0; 658 for (int i = 0; i < jj_2_rtns.length; i++) { 659 JJCalls c = jj_2_rtns[i]; 660 while (c != null) { 661 if (c.gen < jj_gen) 662 c.first = null; 663 c = c.next; 664 } 665 } 666 } 667 return token; 668 } 669 token = oldToken; 670 jj_kind = kind; 671 throw generateParseException(); 672 } 673 674 static private final class LookaheadSuccess extends java.lang.Error { 675 676 /** 677 * 678 */ 679 private static final long serialVersionUID = -8192240240676284081L; 680 } 681 682 final private LookaheadSuccess jj_ls = new LookaheadSuccess(); 683 684 private boolean jj_scan_token(int kind) { 685 if (jj_scanpos == jj_lastpos) { 686 jj_la--; 687 if (jj_scanpos.next == null) { 688 jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken(); 689 } else { 690 jj_lastpos = jj_scanpos = jj_scanpos.next; 691 } 692 } else { 693 jj_scanpos = jj_scanpos.next; 694 } 695 if (jj_rescan) { 696 int i = 0; 697 Token tok = token; 698 while (tok != null && tok != jj_scanpos) { 699 i++; 700 tok = tok.next; 701 } 702 if (tok != null) 703 jj_add_error_token(kind, i); 704 } 705 if (jj_scanpos.kind != kind) 706 return true; 707 if (jj_la == 0 && jj_scanpos == jj_lastpos) 708 throw jj_ls; 709 return false; 710 } 711 712 /** Get the next Token. */ 713 final Token getNextToken() { 714 if (token.next != null) 715 token = token.next; 716 else 717 token = token.next = token_source.getNextToken(); 718 jj_ntk = -1; 719 jj_gen++; 720 return token; 721 } 722 723 /** Get the specific Token. */ 724 final Token getToken(int index) { 725 Token t = token; 726 for (int i = 0; i < index; i++) { 727 if (t.next != null) 728 t = t.next; 729 else 730 t = t.next = token_source.getNextToken(); 731 } 732 return t; 733 } 734 735 private int jj_ntk() { 736 if ((jj_nt = token.next) == null) return (jj_ntk = (token.next = token_source.getNextToken()).kind); 737 return (jj_ntk = jj_nt.kind); 738 } 739 740 private final java.util.List<int[]> jj_expentries = new java.util.ArrayList<>(); 741 private int[] jj_expentry; 742 private int jj_kind = -1; 743 private int[] jj_lasttokens = new int[100]; 744 private int jj_endpos; 745 746 private void jj_add_error_token(int kind, int pos) { 747 if (pos >= 100) 748 return; 749 if (pos == jj_endpos + 1) { 750 jj_lasttokens[jj_endpos++] = kind; 751 } else if (jj_endpos != 0) { 752 jj_expentry = new int[jj_endpos]; 753 System.arraycopy(jj_lasttokens, 0, jj_expentry, 0, jj_endpos); 754 jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) { 755 int[] oldentry = (int[]) (it.next()); 756 if (oldentry.length == jj_expentry.length) { 757 for (int i = 0; i < jj_expentry.length; i++) { 758 if (oldentry[i] != jj_expentry[i]) { 759 continue jj_entries_loop; 760 } 761 } 762 jj_expentries.add(jj_expentry); 763 break; 764 } 765 } 766 if (pos != 0) 767 jj_lasttokens[(jj_endpos = pos) - 1] = kind; 768 } 769 } 770 771 /** Generate TokenException. */ 772 TokenException generateParseException() { 773 jj_expentries.clear(); 774 boolean[] la1tokens = new boolean[21]; 775 if (jj_kind >= 0) { 776 la1tokens[jj_kind] = true; 777 jj_kind = -1; 778 } 779 for (int i = 0; i < 19; i++) { 780 if (jj_la1[i] == jj_gen) { 781 for (int j = 0; j < 32; j++) { 782 if ((jj_la1_0[i] & (1 << j)) != 0) { 783 la1tokens[j] = true; 784 } 785 } 786 } 787 } 788 for (int i = 0; i < 21; i++) { 789 if (la1tokens[i]) { 790 jj_expentry = new int[1]; 791 jj_expentry[0] = i; 792 jj_expentries.add(jj_expentry); 793 } 794 } 795 jj_endpos = 0; 796 jj_rescan_token(); 797 jj_add_error_token(0, 0); 798 int[][] exptokseq = new int[jj_expentries.size()][]; 799 for (int i = 0; i < jj_expentries.size(); i++) { 800 exptokseq[i] = jj_expentries.get(i); 801 } 802 return new TokenException(token, exptokseq, tokenImage); 803 } 804 805 /** Enable tracing. */ 806 final void enable_tracing() { 807 } 808 809 /** Disable tracing. */ 810 final void disable_tracing() { 811 } 812 813 private void jj_rescan_token() { 814 jj_rescan = true; 815 for (int i = 0; i < 2; i++) { 816 try { 817 JJCalls p = jj_2_rtns[i]; 818 do { 819 if (p.gen > jj_gen) { 820 jj_la = p.arg; 821 jj_lastpos = jj_scanpos = p.first; 822 switch (i) { 823 case 0: 824 jj_3_1(); 825 break; 826 case 1: 827 jj_3_2(); 828 break; 829 } 830 } 831 p = p.next; 832 } while (p != null); 833 } catch (LookaheadSuccess ls) { 834 } 835 } 836 jj_rescan = false; 837 } 838 839 private void jj_save(int index, int xla) { 840 JJCalls p = jj_2_rtns[index]; 841 while (p.gen > jj_gen) { 842 if (p.next == null) { 843 p = p.next = new JJCalls(); 844 break; 845 } 846 p = p.next; 847 } 848 p.gen = jj_gen + xla - jj_la; 849 p.first = token; 850 p.arg = xla; 851 } 852 853 static final class JJCalls { 854 int gen; 855 Token first; 856 int arg; 857 JJCalls next; 858 } 859 860}