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