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