/* * Copyright 1998, University Corporation for Atmospheric Research * See file LICENSE for copying and redistribution conditions. * * $Id: Parser.java,v 1.5 2009-09-28 19:25:58 donm Exp $ */ package visad.data.units; import java.io.ByteArrayInputStream; import visad.Unit; import visad.UnitException; /** * Class for parsing unit specifications. */ public class Parser { /** * The unit parser. */ protected static final UnitParser unitParser = new UnitParser(System.in); /** * The singleton instance of this class. */ protected static final Parser parser = new Parser(); /** * Default constructor. Protected to ensure use of singleton. */ protected Parser() { } /** * Obtain the singleton instance of this class. Strictly speaking, this * isn't necessary since <code>parse()</code> is a class method. */ public static Parser instance() { return parser; } /** * Parse a string unit-specification. * * @param spec * The string unit-specification. * @precondition The specification is non-null. * @exception ParseException * An error occurred while parsing the specification. * @throws UnitException * if {@code spec} requires an unsupported operation. */ public static synchronized Unit parse(final String spec) throws ParseException, NoSuchUnitException { unitParser.ReInit(new ByteArrayInputStream(spec.trim().getBytes())); try { return unitParser.unitSpec(); } catch (final TokenMgrError e) { throw new ParseException(e.getMessage()); } catch (final UnitException e) { throw new ParseException(e.getMessage()); } } /** * Test this class. */ public static void main(final String[] args) throws ParseException, UnitException { final Unit m = Parser.parse("m"); final Unit s = Parser.parse("s"); class Test { String spec; Unit unit; Test(final String spec, final Unit unit) { this.spec = spec; this.unit = unit; } } final Test[] tests = { new Test("m", m), new Test("2 m s", m.multiply(s).scale(2)), new Test("3.14 m.s", m.multiply(s).scale(3.14)), new Test("1e9 (m)", m.scale(1e9)), new Test("(m s)2", m.multiply(s).pow(2)), new Test("m2.s-1", m.pow(2).divide(s)), new Test("m2 s^-1", m.pow(2).divide(s)), new Test("(m/s)2", m.divide(s).pow(2)), new Test("m2/s-1", m.pow(2).divide(s.pow(-1))), new Test("m2/s^-1", m.pow(2).divide(s.pow(-1))), new Test(".5 m/(.25 s)2", m.scale(.5).divide( s.scale(.25).pow(2))), new Test("m.m-1.m", m.multiply(m.pow(-1)).multiply(m)), new Test("2.0 m 1/2 s-1*(m/s^1)^-1 (1e9 m-1)(1e9 s-1)-1.m/s", m .scale(2).scale(1. / 2.).multiply(s.pow(-1)).multiply( m.divide(s.pow(1)).pow(-1)).multiply( m.pow(-1).scale(1e9)).multiply( s.pow(-1).scale(1e9).pow(-1)).multiply(m) .divide(s)), new Test("m/km", m.divide(m.scale(1e3))) }; for (int i = 0; i < tests.length; ++i) { final Test test = tests[i]; final String spec = test.spec; final Unit unit = test.unit; if (!Parser.parse(spec).equals(unit)) { throw new AssertionError(spec + " != " + unit); } } try { Parser.parse("unknown unit"); throw new AssertionError(); } catch (final ParseException e) { } System.out.println("Done"); } }