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