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