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