/** * SVG Salamander * Copyright (c) 2004, Mark McKay * All rights reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Mark McKay can be contacted at mark@kitfox.com. Salamander and other * projects can be found at http://www.kitfox.com */ options { MULTI=true; STATIC=false; } PARSER_BEGIN(AnimTimeParser) package com.kitfox.svg.animation.parser; import java.util.*; import java.io.*; import com.kitfox.svg.animation.*; public class AnimTimeParser { /** * Test the parser */ public static void main(String args[]) throws ParseException { // AnimTimeParser parser = new AnimTimeParser(System.in); StringReader reader; reader = new StringReader("1:30 + 5ms"); AnimTimeParser parser = new AnimTimeParser(reader); TimeBase tc; tc = parser.Expr(); System.err.println("AnimTimeParser eval to " + tc.evalTime()); reader = new StringReader("19"); parser.ReInit(reader); tc = parser.Expr(); System.err.println("AnimTimeParser eval to " + tc.evalTime()); } } PARSER_END(AnimTimeParser) /** * Tokens */ SKIP : /* WHITE SPACE */ { " " | "\t" | "\n" | "\r" | "\f" } TOKEN : { < #LETTER: [ "a"-"z", "A"-"Z" ] > | < #DIGIT: [ "0"-"9"] > | < INTEGER: ()+ > | < FLOAT: (["+", "-"])? ((()* "." ()+) | (()+)) (["E", "e"] (["+", "-"])? ()+)? > | < INDEFINITE: "indefinite" > | < MOUSE_OVER: "mouseover" > | < WHEN_NOT_ACTIVE: "whenNotActive" > | < UNITS: "ms" | "s" | "min" | "h" > | < IDENTIFIER: (||"_"|"-")* > } /** * Expression structure */ TimeBase Expr() : { TimeBase term; ArrayList list = new ArrayList(); } { ( term = Sum() { list.add(term); } )? ( LOOKAHEAD(2) ";" term = Sum() { list.add(term); } ) * (";")? { switch (list.size()) { case 0: return new TimeIndefinite(); case 1: return (TimeBase)list.get(0); default: return new TimeCompound(list); } } } TimeBase Sum() : { Token t = null; TimeBase t1; TimeBase t2 = null; } { t1=Term() ( (t="+" | t="-") t2 = Term() )? { if (t2 == null) return t1; if (t.image.equals("-")) { return new TimeSum(t1, t2, false); } else { return new TimeSum(t1, t2, true); } } } TimeBase Term() : { TimeBase base; } { base=IndefiniteTime() { return base; } | base=LiteralTime() { return base; } | base=LookupTime() { return base; } | base=EventTime() { return base; } } TimeIndefinite IndefiniteTime() : {} { { return new TimeIndefinite(); } } TimeDiscrete EventTime() : {} { ( | ) { //For now, map all events to the zero time return new TimeDiscrete(0); } } TimeDiscrete LiteralTime() : { double t1, t2, t3 = Double.NaN, value; Token t; } { t1=Number() { value = t1; } ( (":" t2=Number() (":" t3=Number())? { //Return clock time format (convert to seconds) if (Double.isNaN(t3)) { value = t1 * 60 + t2; } else { value = t1 * 3600 + t2 * 60 + t3; } } ) | (t= { //Return units format (convert to seconds) if (t.image.equals("ms")) value = t1 / 1000; if (t.image.equals("min")) value = t1 * 60; if (t.image.equals("h")) value = t1 * 3600; } ) )? { return new TimeDiscrete(value); } } TimeLookup LookupTime() : { double paramNum = 0.0; Token node, event; } { node= "." event= (paramNum=ParamList())? { return new TimeLookup(null, node.image, event.image, "" + paramNum); } } double ParamList() : { double num; } { "(" num=Number() ")" { return num; } } double Number() : { Token t; } { t= { try { return Double.parseDouble(t.image); } catch (Exception e) { e.printStackTrace(); } return 0.0; } | t= { try { return Double.parseDouble(t.image); } catch (Exception e) { e.printStackTrace(); } return 0.0; } } int Integer() : { Token t; } { t= { try { return Integer.parseInt(t.image); } catch (Exception e) { e.printStackTrace(); } return 0; } }