All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tec.uom.se.format.EBNFUnitFormat Maven / Gradle / Ivy

/*
 * Units of Measurement Implementation for Java SE
 * Copyright (c) 2005-2018, Jean-Marie Dautelle, Werner Keil, Otavio Santana.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of JSR-363 nor the names of its contributors may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * 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.
 */
package tec.uom.se.format;

import tec.uom.se.AbstractUnit;
import tec.uom.se.internal.format.TokenException;
import tec.uom.se.internal.format.TokenMgrError;
import tec.uom.se.internal.format.UnitFormatParser;
import tec.uom.se.unit.AnnotatedUnit;

import javax.measure.Quantity;
import javax.measure.Unit;
import javax.measure.format.ParserException;

import java.io.IOException;
import java.io.StringReader;
import java.text.ParsePosition;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 * 

* This class represents the local neutral format. *

* *

Here is the grammar for Units in Extended Backus-Naur Form (EBNF)

*

* Note that the grammar has been left-factored to be suitable for use by a top-down parser generator such as JavaCC *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Lexical Entities:
<sign>:="+" | "-"
<digit>:="0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<superscript_digit>:="⁰" | "¹" | "²" | "³" | "⁴" | "⁵" | "⁶" | "⁷" | "⁸" | "⁹"
<integer>:=(<digit>)+
<number>:=(<sign>)? (<digit>)* (".")? (<digit>)+ (("e" | "E") (<sign>)? (<digit>)+)?
<exponent>:=( "^" ( <sign> )? <integer> )
* | ( "^(" (<sign>)? <integer> ( "/" (<sign>)? <integer> )? ")" )
* | ( <superscript_digit> )+
<initial_char>:=? Any Unicode character excluding the following: ASCII control & whitespace (\u0000 - \u0020), decimal digits '0'-'9', '(' * (\u0028), ')' (\u0029), '*' (\u002A), '+' (\u002B), '-' (\u002D), '.' (\u002E), '/' (\u005C), ':' (\u003A), '^' * (\u005E), '²' (\u00B2), '³' (\u00B3), '·' (\u00B7), '¹' (\u00B9), '⁰' (\u2070), '⁴' (\u2074), '⁵' (\u2075), '⁶' * (\u2076), '⁷' (\u2077), '⁸' (\u2078), '⁹' (\u2079) ?
<unit_identifier>:=<initial_char> ( <initial_char> | <digit> )*
Non-Terminals:
<unit_expr>:=<compound_expr>
<compound_expr>:=<add_expr> ( ":" <add_expr> )*
<add_expr>:=( <number> <sign> )? <mul_expr> ( <sign> <number> )?
<mul_expr>:=<exponent_expr> ( ( ( "*" | "·" ) <exponent_expr> ) | ( "/" <exponent_expr> ) )*
<exponent_expr>:=( <atomic_expr> ( <exponent> )? )
* | (<integer> "^" <atomic_expr>)
* | ( ( "log" ( <integer> )? ) | "ln" ) "(" <add_expr> ")" )
<atomic_expr>:=<number>
* | <unit_identifier>
* | ( "(" <add_expr> ")" )
* * @author Eric Russell * @author Werner Keil * @version 1.0.3, $Date: 2017-03-18 $ * @since 1.0 */ public class EBNFUnitFormat extends AbstractUnitFormat { // //////////////////////////////////////////////////// // Class variables // // //////////////////////////////////////////////////// /** * */ // private static final long serialVersionUID = 8968559300292910840L; /** * Name of the resource bundle */ private static final String BUNDLE_NAME = "tec.uom.se.format.messages"; //$NON-NLS-1$ /** * Default locale instance. If the default locale is changed after the class is initialized, this instance will no longer be used. */ private static final EBNFUnitFormat DEFAULT_INSTANCE = new EBNFUnitFormat(); /** * Returns the instance for the current default locale (non-ascii characters are allowed) */ public static EBNFUnitFormat getInstance() { return DEFAULT_INSTANCE; } /** Returns an instance for the given symbol map. */ public static EBNFUnitFormat getInstance(SymbolMap symbols) { return new EBNFUnitFormat(symbols); } // ////////////////////// // Instance variables // // ////////////////////// /** * The symbol map used by this instance to map between {@link org.unitsofmeasure.Unit Unit}s and Strings, etc... */ private final transient SymbolMap symbolMap; // //////////////// // Constructors // // //////////////// /** * Base constructor. * */ EBNFUnitFormat() { this(SymbolMap.of(ResourceBundle.getBundle(BUNDLE_NAME, Locale.ROOT))); } /** * Private constructor. * * @param symbols * the symbol mapping. */ private EBNFUnitFormat(SymbolMap symbols) { symbolMap = symbols; } // ////////////////////// // Instance methods // // ////////////////////// /** * Get the symbol map used by this instance to map between {@link org.unitsofmeasure.Unit Unit}s and Strings, etc... * * @return SymbolMap the current symbol map */ protected SymbolMap getSymbols() { return symbolMap; } // ////////////// // Formatting // // ////////////// public Appendable format(Unit unit, Appendable appendable) throws IOException { EBNFHelper.formatInternal(unit, appendable, symbolMap); if (unit instanceof AnnotatedUnit) { AnnotatedUnit annotatedUnit = (AnnotatedUnit) unit; if (annotatedUnit.getAnnotation() != null) { appendable.append('{'); appendable.append(annotatedUnit.getAnnotation()); appendable.append('}'); } } return appendable; } public boolean isLocaleSensitive() { return false; } @Override protected Unit> parse(CharSequence csq, ParsePosition cursor) throws ParserException { // Parsing reads the whole character sequence from the parse position. int start = cursor != null ? cursor.getIndex() : 0; int end = csq.length(); if (end <= start) { return AbstractUnit.ONE; } String source = csq.subSequence(start, end).toString().trim(); if (source.length() == 0) { return AbstractUnit.ONE; } try { UnitFormatParser parser = new UnitFormatParser(symbolMap, new StringReader(source)); Unit result = parser.parseUnit(); if (cursor != null) cursor.setIndex(end); return result; } catch (TokenException e) { if (e.currentToken != null) { cursor.setErrorIndex(start + e.currentToken.endColumn); } else { cursor.setErrorIndex(start); } throw new ParserException(e); } catch (TokenMgrError e) { cursor.setErrorIndex(start); throw new IllegalArgumentException(e.getMessage()); } } @Override protected Unit parse(CharSequence csq, int index) throws IllegalArgumentException { return parse(csq, new ParsePosition(index)); } public Unit parse(CharSequence csq) throws ParserException { return parse(csq, 0); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy