/***************************************************************************** * Copyright (C) Codehaus.org * * ------------------------------------------------------------------------- * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * *****************************************************************************/ package net.ion.rosetta; /** * Provides common token values. * * @author Ben Yu */ public final class Tokens { private Tokens() { } /** * Returns a {@link Fragment} tagged with {@code tag}. * * @param text * the fragment text. * @param tag * the tag representing the fragment's semantics. * @return the TypedToken object. */ public static Fragment fragment(String text, Object tag) { return new Fragment(text, tag); } /** * Returns a {@link Fragment} tagged as {@link Tag#RESERVED}. * * @param name * the reserved word. * @return the token value. */ public static Fragment reserved(String name) { return fragment(name, Tag.RESERVED); } /** * Returns a {@link Fragment} tagged as {@link Tag#IDENTIFIER}. * * @param name * the identifier. * @return the token value. */ public static Fragment identifier(String name) { return fragment(name, Tag.IDENTIFIER); } /** * Returns a {@link Fragment} tagged as {@link Tag#DECIMAL}. * * @param s * the decimal string representation. * @return the token value. */ public static Fragment decimalLiteral(String s) { return fragment(s, Tag.DECIMAL); } /** * Returns a {@link Fragment} tagged as {@link Tag#INTEGER}. * * @param s * the integer string representation. * @return the token value. */ public static Fragment integerLiteral(String s) { return fragment(s, Tag.INTEGER); } /** * Returns a {@link ScientificNotation} with {@code significand} before the 'e' or 'E' and {@code exponent} after. */ public static ScientificNotation scientificNotation(String significand, String exponent) { return new ScientificNotation(significand, exponent); } /** Represents a fragment tagged according to its semantics. */ public static final class Fragment { private final String text; private final Object tag; public Fragment(String text, Object tag) { this.text = text; this.tag = tag; } /** Returns the text of the token value. */ public String text() { return text; } /** Returns the tag of the token value. */ public Object tag() { return tag; } boolean equalFragment(Fragment that) { return tag.equals(that.tag) && text.equals(that.text); } @Override public boolean equals(Object obj) { if (obj instanceof Fragment) { return equalFragment((Fragment) obj); } else return false; } @Override public int hashCode() { return tag.hashCode() * 31 + text.hashCode(); } @Override public String toString() { return text; } } /** * Represents a scientific notation with a significand (mantissa) and an exponent. Both are represented with a {@link String} to avoid number range issue. */ public static final class ScientificNotation { /** The significand (mantissa) before the "E". */ public final String significand; /** The exponent after the "E". */ public final String exponent; // we leave the range check to the // semantics analysis public ScientificNotation(String mantissa, String exp) { this.significand = mantissa; this.exponent = exp; } @Override public String toString() { return significand + "E" + exponent; } @Override public boolean equals(Object obj) { if (obj instanceof ScientificNotation) { ScientificNotation that = (ScientificNotation) obj; return significand.equals(that.significand) && exponent.equals(that.exponent); } return false; } @Override public int hashCode() { return significand.hashCode() * 31 + exponent.hashCode(); } } /** Pre-built {@link Fragment} token tags. */ public enum Tag { /** Reserved word */ RESERVED, /** Regular identifier */ IDENTIFIER, /** Integral number literal */ INTEGER, /** Decimal number literal */ DECIMAL } }