001    /* Generated By:JavaCC: Do not edit this line. AnimTimeParser.java */
002    package com.kitfox.svg.animation.parser;
003    
004    import java.util.*;
005    import java.io.*;
006    import com.kitfox.svg.animation.*;
007    
008    public class AnimTimeParser implements AnimTimeParserConstants {
009        /**
010         * Test the parser
011         */
012        public static void main(String args[]) throws ParseException
013        {
014    //        AnimTimeParser parser = new AnimTimeParser(System.in);
015            StringReader reader;
016    
017            reader = new StringReader("1:30 + 5ms");
018            AnimTimeParser parser = new AnimTimeParser(reader);
019            TimeBase tc;
020    
021            tc = parser.Expr();
022            System.err.println("AnimTimeParser eval to " + tc.evalTime());
023    
024            reader = new StringReader("19");
025            parser.ReInit(reader);
026            tc = parser.Expr();
027            System.err.println("AnimTimeParser eval to " + tc.evalTime());
028        }
029    
030    /**
031     * Expression structure
032     */
033      final public TimeBase Expr() throws ParseException {
034        TimeBase term;
035        ArrayList list = new ArrayList();
036        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
037        case INTEGER:
038        case FLOAT:
039        case INDEFINITE:
040        case MOUSE_OVER:
041        case WHEN_NOT_ACTIVE:
042        case IDENTIFIER:
043          term = Sum();
044                list.add(term);
045          break;
046        default:
047          jj_la1[0] = jj_gen;
048          ;
049        }
050        label_1:
051        while (true) {
052          if (jj_2_1(2)) {
053            ;
054          } else {
055            break label_1;
056          }
057          jj_consume_token(15);
058          term = Sum();
059                list.add(term);
060        }
061        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
062        case 15:
063          jj_consume_token(15);
064          break;
065        default:
066          jj_la1[1] = jj_gen;
067          ;
068        }
069            switch (list.size())
070            {
071                case 0:
072                    {if (true) return new TimeIndefinite();}
073                case 1:
074                    {if (true) return (TimeBase)list.get(0);}
075                default:
076                    {if (true) return new TimeCompound(list);}
077            }
078        throw new Error("Missing return statement in function");
079      }
080    
081      final public TimeBase Sum() throws ParseException {
082        Token t = null;
083        TimeBase t1;
084        TimeBase t2 = null;
085        t1 = Term();
086        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
087        case 16:
088        case 17:
089          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
090          case 16:
091            t = jj_consume_token(16);
092            break;
093          case 17:
094            t = jj_consume_token(17);
095            break;
096          default:
097            jj_la1[2] = jj_gen;
098            jj_consume_token(-1);
099            throw new ParseException();
100          }
101          t2 = Term();
102          break;
103        default:
104          jj_la1[3] = jj_gen;
105          ;
106        }
107                if (t2 == null) {if (true) return t1;}
108    
109                if (t.image.equals("-"))
110                {
111                    {if (true) return new TimeSum(t1, t2, false);}
112                }
113                else
114                {
115                    {if (true) return new TimeSum(t1, t2, true);}
116                }
117        throw new Error("Missing return statement in function");
118      }
119    
120      final public TimeBase Term() throws ParseException {
121        TimeBase base;
122        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
123        case INDEFINITE:
124          base = IndefiniteTime();
125              {if (true) return base;}
126          break;
127        case INTEGER:
128        case FLOAT:
129          base = LiteralTime();
130              {if (true) return base;}
131          break;
132        case IDENTIFIER:
133          base = LookupTime();
134              {if (true) return base;}
135          break;
136        case MOUSE_OVER:
137        case WHEN_NOT_ACTIVE:
138          base = EventTime();
139              {if (true) return base;}
140          break;
141        default:
142          jj_la1[4] = jj_gen;
143          jj_consume_token(-1);
144          throw new ParseException();
145        }
146        throw new Error("Missing return statement in function");
147      }
148    
149      final public TimeIndefinite IndefiniteTime() throws ParseException {
150        jj_consume_token(INDEFINITE);
151            {if (true) return new TimeIndefinite();}
152        throw new Error("Missing return statement in function");
153      }
154    
155      final public TimeDiscrete EventTime() throws ParseException {
156        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
157        case MOUSE_OVER:
158          jj_consume_token(MOUSE_OVER);
159          break;
160        case WHEN_NOT_ACTIVE:
161          jj_consume_token(WHEN_NOT_ACTIVE);
162          break;
163        default:
164          jj_la1[5] = jj_gen;
165          jj_consume_token(-1);
166          throw new ParseException();
167        }
168                //For now, map all events to the zero time
169                {if (true) return new TimeDiscrete(0);}
170        throw new Error("Missing return statement in function");
171      }
172    
173      final public TimeDiscrete LiteralTime() throws ParseException {
174        double t1, t2, t3 = Double.NaN, value;
175        Token t;
176        t1 = Number();
177                value = t1;
178        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
179        case UNITS:
180        case 18:
181          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
182          case 18:
183            jj_consume_token(18);
184            t2 = Number();
185            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
186            case 18:
187              jj_consume_token(18);
188              t3 = Number();
189              break;
190            default:
191              jj_la1[6] = jj_gen;
192              ;
193            }
194                //Return clock time format (convert to seconds)
195                if (Double.isNaN(t3))
196                {
197                    value = t1 * 60 + t2;
198                }
199                else
200                {
201                    value = t1 * 3600 + t2 * 60 + t3;
202                }
203            break;
204          case UNITS:
205            t = jj_consume_token(UNITS);
206                //Return units format (convert to seconds)
207                if (t.image.equals("ms")) value = t1 / 1000;
208                if (t.image.equals("min")) value = t1 * 60;
209                if (t.image.equals("h")) value = t1 * 3600;
210            break;
211          default:
212            jj_la1[7] = jj_gen;
213            jj_consume_token(-1);
214            throw new ParseException();
215          }
216          break;
217        default:
218          jj_la1[8] = jj_gen;
219          ;
220        }
221            {if (true) return new TimeDiscrete(value);}
222        throw new Error("Missing return statement in function");
223      }
224    
225      final public TimeLookup LookupTime() throws ParseException {
226        double paramNum = 0.0;
227        Token node, event;
228        node = jj_consume_token(IDENTIFIER);
229        jj_consume_token(19);
230        event = jj_consume_token(IDENTIFIER);
231        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
232        case 20:
233          paramNum = ParamList();
234          break;
235        default:
236          jj_la1[9] = jj_gen;
237          ;
238        }
239            {if (true) return new TimeLookup(null, node.image, event.image, "" + paramNum);}
240        throw new Error("Missing return statement in function");
241      }
242    
243      final public double ParamList() throws ParseException {
244        double num;
245        jj_consume_token(20);
246        num = Number();
247        jj_consume_token(21);
248            {if (true) return num;}
249        throw new Error("Missing return statement in function");
250      }
251    
252      final public double Number() throws ParseException {
253        Token t;
254        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
255        case FLOAT:
256          t = jj_consume_token(FLOAT);
257            try { {if (true) return Double.parseDouble(t.image);} }
258            catch (Exception e) { e.printStackTrace(); }
259    
260            {if (true) return 0.0;}
261          break;
262        case INTEGER:
263          t = jj_consume_token(INTEGER);
264            try { {if (true) return Double.parseDouble(t.image);} }
265            catch (Exception e) { e.printStackTrace(); }
266    
267            {if (true) return 0.0;}
268          break;
269        default:
270          jj_la1[10] = jj_gen;
271          jj_consume_token(-1);
272          throw new ParseException();
273        }
274        throw new Error("Missing return statement in function");
275      }
276    
277      final public int Integer() throws ParseException {
278        Token t;
279        t = jj_consume_token(INTEGER);
280            try { {if (true) return Integer.parseInt(t.image);} }
281            catch (Exception e) { e.printStackTrace(); }
282    
283            {if (true) return 0;}
284        throw new Error("Missing return statement in function");
285      }
286    
287      private boolean jj_2_1(int xla) {
288        jj_la = xla; jj_lastpos = jj_scanpos = token;
289        try { return !jj_3_1(); }
290        catch(LookaheadSuccess ls) { return true; }
291        finally { jj_save(0, xla); }
292      }
293    
294      private boolean jj_3R_2() {
295        if (jj_3R_3()) return true;
296        return false;
297      }
298    
299      private boolean jj_3_1() {
300        if (jj_scan_token(15)) return true;
301        if (jj_3R_2()) return true;
302        return false;
303      }
304    
305      private boolean jj_3R_3() {
306        Token xsp;
307        xsp = jj_scanpos;
308        if (jj_3R_4()) {
309        jj_scanpos = xsp;
310        if (jj_3R_5()) {
311        jj_scanpos = xsp;
312        if (jj_3R_6()) {
313        jj_scanpos = xsp;
314        if (jj_3R_7()) return true;
315        }
316        }
317        }
318        return false;
319      }
320    
321      private boolean jj_3R_4() {
322        if (jj_3R_8()) return true;
323        return false;
324      }
325    
326      private boolean jj_3R_11() {
327        Token xsp;
328        xsp = jj_scanpos;
329        if (jj_scan_token(11)) {
330        jj_scanpos = xsp;
331        if (jj_scan_token(12)) return true;
332        }
333        return false;
334      }
335    
336      private boolean jj_3R_14() {
337        if (jj_scan_token(INTEGER)) return true;
338        return false;
339      }
340    
341      private boolean jj_3R_8() {
342        if (jj_scan_token(INDEFINITE)) return true;
343        return false;
344      }
345    
346      private boolean jj_3R_9() {
347        if (jj_3R_12()) return true;
348        return false;
349      }
350    
351      private boolean jj_3R_10() {
352        if (jj_scan_token(IDENTIFIER)) return true;
353        return false;
354      }
355    
356      private boolean jj_3R_13() {
357        if (jj_scan_token(FLOAT)) return true;
358        return false;
359      }
360    
361      private boolean jj_3R_12() {
362        Token xsp;
363        xsp = jj_scanpos;
364        if (jj_3R_13()) {
365        jj_scanpos = xsp;
366        if (jj_3R_14()) return true;
367        }
368        return false;
369      }
370    
371      private boolean jj_3R_7() {
372        if (jj_3R_11()) return true;
373        return false;
374      }
375    
376      private boolean jj_3R_6() {
377        if (jj_3R_10()) return true;
378        return false;
379      }
380    
381      private boolean jj_3R_5() {
382        if (jj_3R_9()) return true;
383        return false;
384      }
385    
386      /** Generated Token Manager. */
387      public AnimTimeParserTokenManager token_source;
388      SimpleCharStream jj_input_stream;
389      /** Current token. */
390      public Token token;
391      /** Next token. */
392      public Token jj_nt;
393      private int jj_ntk;
394      private Token jj_scanpos, jj_lastpos;
395      private int jj_la;
396      private int jj_gen;
397      final private int[] jj_la1 = new int[11];
398      static private int[] jj_la1_0;
399      static {
400          jj_la1_init_0();
401       }
402       private static void jj_la1_init_0() {
403          jj_la1_0 = new int[] {0x5f00,0x8000,0x30000,0x30000,0x5f00,0x1800,0x40000,0x42000,0x42000,0x100000,0x300,};
404       }
405      final private JJCalls[] jj_2_rtns = new JJCalls[1];
406      private boolean jj_rescan = false;
407      private int jj_gc = 0;
408    
409      /** Constructor with InputStream. */
410      public AnimTimeParser(java.io.InputStream stream) {
411         this(stream, null);
412      }
413      /** Constructor with InputStream and supplied encoding */
414      public AnimTimeParser(java.io.InputStream stream, String encoding) {
415        try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
416        token_source = new AnimTimeParserTokenManager(jj_input_stream);
417        token = new Token();
418        jj_ntk = -1;
419        jj_gen = 0;
420        for (int i = 0; i < 11; i++) jj_la1[i] = -1;
421        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
422      }
423    
424      /** Reinitialise. */
425      public void ReInit(java.io.InputStream stream) {
426         ReInit(stream, null);
427      }
428      /** Reinitialise. */
429      public void ReInit(java.io.InputStream stream, String encoding) {
430        try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
431        token_source.ReInit(jj_input_stream);
432        token = new Token();
433        jj_ntk = -1;
434        jj_gen = 0;
435        for (int i = 0; i < 11; i++) jj_la1[i] = -1;
436        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
437      }
438    
439      /** Constructor. */
440      public AnimTimeParser(java.io.Reader stream) {
441        jj_input_stream = new SimpleCharStream(stream, 1, 1);
442        token_source = new AnimTimeParserTokenManager(jj_input_stream);
443        token = new Token();
444        jj_ntk = -1;
445        jj_gen = 0;
446        for (int i = 0; i < 11; i++) jj_la1[i] = -1;
447        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
448      }
449    
450      /** Reinitialise. */
451      public void ReInit(java.io.Reader stream) {
452        jj_input_stream.ReInit(stream, 1, 1);
453        token_source.ReInit(jj_input_stream);
454        token = new Token();
455        jj_ntk = -1;
456        jj_gen = 0;
457        for (int i = 0; i < 11; i++) jj_la1[i] = -1;
458        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
459      }
460    
461      /** Constructor with generated Token Manager. */
462      public AnimTimeParser(AnimTimeParserTokenManager tm) {
463        token_source = tm;
464        token = new Token();
465        jj_ntk = -1;
466        jj_gen = 0;
467        for (int i = 0; i < 11; i++) jj_la1[i] = -1;
468        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
469      }
470    
471      /** Reinitialise. */
472      public void ReInit(AnimTimeParserTokenManager tm) {
473        token_source = tm;
474        token = new Token();
475        jj_ntk = -1;
476        jj_gen = 0;
477        for (int i = 0; i < 11; i++) jj_la1[i] = -1;
478        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
479      }
480    
481      private Token jj_consume_token(int kind) throws ParseException {
482        Token oldToken;
483        if ((oldToken = token).next != null) token = token.next;
484        else token = token.next = token_source.getNextToken();
485        jj_ntk = -1;
486        if (token.kind == kind) {
487          jj_gen++;
488          if (++jj_gc > 100) {
489            jj_gc = 0;
490            for (int i = 0; i < jj_2_rtns.length; i++) {
491              JJCalls c = jj_2_rtns[i];
492              while (c != null) {
493                if (c.gen < jj_gen) c.first = null;
494                c = c.next;
495              }
496            }
497          }
498          return token;
499        }
500        token = oldToken;
501        jj_kind = kind;
502        throw generateParseException();
503      }
504    
505      static private final class LookaheadSuccess extends java.lang.Error { }
506      final private LookaheadSuccess jj_ls = new LookaheadSuccess();
507      private boolean jj_scan_token(int kind) {
508        if (jj_scanpos == jj_lastpos) {
509          jj_la--;
510          if (jj_scanpos.next == null) {
511            jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
512          } else {
513            jj_lastpos = jj_scanpos = jj_scanpos.next;
514          }
515        } else {
516          jj_scanpos = jj_scanpos.next;
517        }
518        if (jj_rescan) {
519          int i = 0; Token tok = token;
520          while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
521          if (tok != null) jj_add_error_token(kind, i);
522        }
523        if (jj_scanpos.kind != kind) return true;
524        if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
525        return false;
526      }
527    
528    
529    /** Get the next Token. */
530      final public Token getNextToken() {
531        if (token.next != null) token = token.next;
532        else token = token.next = token_source.getNextToken();
533        jj_ntk = -1;
534        jj_gen++;
535        return token;
536      }
537    
538    /** Get the specific Token. */
539      final public Token getToken(int index) {
540        Token t = token;
541        for (int i = 0; i < index; i++) {
542          if (t.next != null) t = t.next;
543          else t = t.next = token_source.getNextToken();
544        }
545        return t;
546      }
547    
548      private int jj_ntk() {
549        if ((jj_nt=token.next) == null)
550          return (jj_ntk = (token.next=token_source.getNextToken()).kind);
551        else
552          return (jj_ntk = jj_nt.kind);
553      }
554    
555      private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
556      private int[] jj_expentry;
557      private int jj_kind = -1;
558      private int[] jj_lasttokens = new int[100];
559      private int jj_endpos;
560    
561      private void jj_add_error_token(int kind, int pos) {
562        if (pos >= 100) return;
563        if (pos == jj_endpos + 1) {
564          jj_lasttokens[jj_endpos++] = kind;
565        } else if (jj_endpos != 0) {
566          jj_expentry = new int[jj_endpos];
567          for (int i = 0; i < jj_endpos; i++) {
568            jj_expentry[i] = jj_lasttokens[i];
569          }
570          jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
571            int[] oldentry = (int[])(it.next());
572            if (oldentry.length == jj_expentry.length) {
573              for (int i = 0; i < jj_expentry.length; i++) {
574                if (oldentry[i] != jj_expentry[i]) {
575                  continue jj_entries_loop;
576                }
577              }
578              jj_expentries.add(jj_expentry);
579              break jj_entries_loop;
580            }
581          }
582          if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
583        }
584      }
585    
586      /** Generate ParseException. */
587      public ParseException generateParseException() {
588        jj_expentries.clear();
589        boolean[] la1tokens = new boolean[22];
590        if (jj_kind >= 0) {
591          la1tokens[jj_kind] = true;
592          jj_kind = -1;
593        }
594        for (int i = 0; i < 11; i++) {
595          if (jj_la1[i] == jj_gen) {
596            for (int j = 0; j < 32; j++) {
597              if ((jj_la1_0[i] & (1<<j)) != 0) {
598                la1tokens[j] = true;
599              }
600            }
601          }
602        }
603        for (int i = 0; i < 22; i++) {
604          if (la1tokens[i]) {
605            jj_expentry = new int[1];
606            jj_expentry[0] = i;
607            jj_expentries.add(jj_expentry);
608          }
609        }
610        jj_endpos = 0;
611        jj_rescan_token();
612        jj_add_error_token(0, 0);
613        int[][] exptokseq = new int[jj_expentries.size()][];
614        for (int i = 0; i < jj_expentries.size(); i++) {
615          exptokseq[i] = jj_expentries.get(i);
616        }
617        return new ParseException(token, exptokseq, tokenImage);
618      }
619    
620      /** Enable tracing. */
621      final public void enable_tracing() {
622      }
623    
624      /** Disable tracing. */
625      final public void disable_tracing() {
626      }
627    
628      private void jj_rescan_token() {
629        jj_rescan = true;
630        for (int i = 0; i < 1; i++) {
631        try {
632          JJCalls p = jj_2_rtns[i];
633          do {
634            if (p.gen > jj_gen) {
635              jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
636              switch (i) {
637                case 0: jj_3_1(); break;
638              }
639            }
640            p = p.next;
641          } while (p != null);
642          } catch(LookaheadSuccess ls) { }
643        }
644        jj_rescan = false;
645      }
646    
647      private void jj_save(int index, int xla) {
648        JJCalls p = jj_2_rtns[index];
649        while (p.gen > jj_gen) {
650          if (p.next == null) { p = p.next = new JJCalls(); break; }
651          p = p.next;
652        }
653        p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
654      }
655    
656      static final class JJCalls {
657        int gen;
658        Token first;
659        int arg;
660        JJCalls next;
661      }
662    
663    }