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

org.javacc.parser.Options Maven / Gradle / Ivy

There is a newer version: 4.1.5
Show newest version
// Copyright 2011 Google Inc. All Rights Reserved.
// Author: [email protected] (Sreeni Viswanadha)

/* Copyright (c) 2006, Sun Microsystems, Inc.
 * 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.
 *     * Neither the name of the Sun Microsystems, Inc. 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 OWNER 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 org.javacc.parser;

import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;

import org.javacc.utils.OptionInfo;
import org.javacc.utils.OptionType;

/**
 * A class with static state that stores all option information.
 */
public class Options
{

  /**
   * Limit subclassing to derived classes.
   */
  protected Options ()
  {}

  /**
   * These are options that are not settable by the user themselves, and that
   * are set indirectly via some configuration of user options
   */
  public static final String NONUSER_OPTION__NAMESPACE_CLOSE = "NAMESPACE_CLOSE";
  public static final String NONUSER_OPTION__HAS_NAMESPACE = "HAS_NAMESPACE";
  public static final String NONUSER_OPTION__NAMESPACE_OPEN = "NAMESPACE_OPEN";
  public static final String NONUSER_OPTION__PARSER_NAME = "PARSER_NAME";
  public static final String NONUSER_OPTION__LEGACY_EXCEPTION_HANDLING = "LEGACY_EXCEPTION_HANDLING";

  /**
   * Options that the user can specify from .javacc file
   */

  public static final String USEROPTION__PARSER_SUPER_CLASS = "PARSER_SUPER_CLASS";
  public static final String USEROPTION__JAVA_TEMPLATE_TYPE = "JAVA_TEMPLATE_TYPE";
  public static final String USEROPTION__GENERATE_BOILERPLATE = "GENERATE_BOILERPLATE";
  public static final String USEROPTION__OUTPUT_LANGUAGE = "OUTPUT_LANGUAGE";
  public static final String USEROPTION__STATIC = "STATIC";
  public static final String USEROPTION__TOKEN_MANAGER_SUPER_CLASS = "TOKEN_MANAGER_SUPER_CLASS";
  public static final String USEROPTION__LOOKAHEAD = "LOOKAHEAD";
  public static final String USEROPTION__IGNORE_CASE = "IGNORE_CASE";
  public static final String USEROPTION__UNICODE_INPUT = "UNICODE_INPUT";
  public static final String USEROPTION__JAVA_UNICODE_ESCAPE = "JAVA_UNICODE_ESCAPE";
  public static final String USEROPTION__ERROR_REPORTING = "ERROR_REPORTING";
  public static final String USEROPTION__DEBUG_TOKEN_MANAGER = "DEBUG_TOKEN_MANAGER";
  public static final String USEROPTION__DEBUG_LOOKAHEAD = "DEBUG_LOOKAHEAD";
  public static final String USEROPTION__DEBUG_PARSER = "DEBUG_PARSER";
  public static final String USEROPTION__OTHER_AMBIGUITY_CHECK = "OTHER_AMBIGUITY_CHECK";
  public static final String USEROPTION__CHOICE_AMBIGUITY_CHECK = "CHOICE_AMBIGUITY_CHECK";
  public static final String USEROPTION__CACHE_TOKENS = "CACHE_TOKENS";
  public static final String USEROPTION__COMMON_TOKEN_ACTION = "COMMON_TOKEN_ACTION";
  public static final String USEROPTION__FORCE_LA_CHECK = "FORCE_LA_CHECK";
  public static final String USEROPTION__SANITY_CHECK = "SANITY_CHECK";
  public static final String USEROPTION__TOKEN_MANAGER_USES_PARSER = "TOKEN_MANAGER_USES_PARSER";
  public static final String USEROPTION__BUILD_TOKEN_MANAGER = "BUILD_TOKEN_MANAGER";
  public static final String USEROPTION__BUILD_PARSER = "BUILD_PARSER";
  public static final String USEROPTION__USER_CHAR_STREAM = "USER_CHAR_STREAM";
  public static final String USEROPTION__USER_TOKEN_MANAGER = "USER_TOKEN_MANAGER";
  public static final String USEROPTION__JDK_VERSION = "JDK_VERSION";
  public static final String USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC = "SUPPORT_CLASS_VISIBILITY_PUBLIC";
  public static final String USEROPTION__GENERATE_ANNOTATIONS = "GENERATE_ANNOTATIONS";
  public static final String USEROPTION__GENERATE_STRING_BUILDER = "GENERATE_STRING_BUILDER";
  public static final String USEROPTION__GENERATE_GENERICS = "GENERATE_GENERICS";
  public static final String USEROPTION__GENERATE_CHAINED_EXCEPTION = "GENERATE_CHAINED_EXCEPTION";
  public static final String USEROPTION__OUTPUT_DIRECTORY = "OUTPUT_DIRECTORY";
  public static final String USEROPTION__KEEP_LINE_COLUMN = "KEEP_LINE_COLUMN";
  public static final String USEROPTION__GRAMMAR_ENCODING = "GRAMMAR_ENCODING";
  public static final String USEROPTION__TOKEN_FACTORY = "TOKEN_FACTORY";
  public static final String USEROPTION__TOKEN_EXTENDS = "TOKEN_EXTENDS";

  public static final String USEROPTION_CPP_NAMESPACE = "NAMESPACE";
  public static final String USEROPTION__CPP_TOKEN_INCLUDES = "TOKEN_INCLUDES";
  public static final String USEROPTION__CPP_PARSER_INCLUDES = "PARSER_INCLUDES";
  public static final String USEROPTION__CPP_IGNORE_ACTIONS = "IGNORE_ACTIONS";
  public static final String USEROPTION__CPP_TOKEN_MANAGER_INCLUDES = "TOKEN_MANAGER_INCLUDES";
  public static final String USEROPTION__CPP_TOKEN_MANAGER_SUPERCLASS = "TOKEN_MANAGER_SUPERCLASS";
  public static final String USEROPTION__CPP_STOP_ON_FIRST_ERROR = "STOP_ON_FIRST_ERROR";

  /**
   * Various constants relating to possible values for certain options
   */

  public static final String OUTPUT_LANGUAGE__CPP = "c++";
  public static final String OUTPUT_LANGUAGE__JAVA = "java";

  /**
   * 2013/07/22 -- GWT Compliant Output -- no external dependencies on GWT, but
   * generated code adds loose coupling to IO, for 6.1 release, this is opt-in,
   * moving forward to 7.0, after thorough testing, this will likely become the
   * default option with classic being deprecated
   */
  public static final String JAVA_TEMPLATE_TYPE_MODERN = "modern";

  /**
   * The old style of Java code generation (tight coupling of code to Java IO
   * classes - not GWT compatible)
   */
  public static final String JAVA_TEMPLATE_TYPE_CLASSIC = "classic";

  static final Set  userOptions;

  static
  {
    final TreeSet  temp = new TreeSet  ();

    temp.add (new OptionInfo (USEROPTION__PARSER_SUPER_CLASS, OptionType.STRING, null));
    temp.add (new OptionInfo (USEROPTION__TOKEN_MANAGER_SUPER_CLASS, OptionType.STRING, null));
    temp.add (new OptionInfo (USEROPTION__LOOKAHEAD, OptionType.INTEGER, new Integer (1)));

    temp.add (new OptionInfo (USEROPTION__CHOICE_AMBIGUITY_CHECK, OptionType.INTEGER, new Integer (2)));
    temp.add (new OptionInfo (USEROPTION__OTHER_AMBIGUITY_CHECK, OptionType.INTEGER, new Integer (1)));
    temp.add (new OptionInfo (USEROPTION__STATIC, OptionType.BOOLEAN, Boolean.TRUE));
    temp.add (new OptionInfo (USEROPTION__DEBUG_PARSER, OptionType.BOOLEAN, Boolean.FALSE));

    temp.add (new OptionInfo (USEROPTION__DEBUG_LOOKAHEAD, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__DEBUG_TOKEN_MANAGER, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__ERROR_REPORTING, OptionType.BOOLEAN, Boolean.TRUE));
    temp.add (new OptionInfo (USEROPTION__JAVA_UNICODE_ESCAPE, OptionType.BOOLEAN, Boolean.FALSE));

    temp.add (new OptionInfo (USEROPTION__UNICODE_INPUT, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__IGNORE_CASE, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__USER_TOKEN_MANAGER, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__USER_CHAR_STREAM, OptionType.BOOLEAN, Boolean.FALSE));

    temp.add (new OptionInfo (USEROPTION__BUILD_PARSER, OptionType.BOOLEAN, Boolean.TRUE));
    temp.add (new OptionInfo (USEROPTION__BUILD_TOKEN_MANAGER, OptionType.BOOLEAN, Boolean.TRUE));
    temp.add (new OptionInfo (USEROPTION__TOKEN_MANAGER_USES_PARSER, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__SANITY_CHECK, OptionType.BOOLEAN, Boolean.TRUE));

    temp.add (new OptionInfo (USEROPTION__FORCE_LA_CHECK, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__COMMON_TOKEN_ACTION, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__CACHE_TOKENS, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__KEEP_LINE_COLUMN, OptionType.BOOLEAN, Boolean.TRUE));

    temp.add (new OptionInfo (USEROPTION__GENERATE_CHAINED_EXCEPTION, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__GENERATE_GENERICS, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__GENERATE_BOILERPLATE, OptionType.BOOLEAN, Boolean.TRUE));
    temp.add (new OptionInfo (USEROPTION__GENERATE_STRING_BUILDER, OptionType.BOOLEAN, Boolean.FALSE));

    temp.add (new OptionInfo (USEROPTION__GENERATE_ANNOTATIONS, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC, OptionType.BOOLEAN, Boolean.TRUE));
    temp.add (new OptionInfo (USEROPTION__OUTPUT_DIRECTORY, OptionType.STRING, "."));
    temp.add (new OptionInfo (USEROPTION__JDK_VERSION, OptionType.STRING, "1.5"));

    temp.add (new OptionInfo (USEROPTION__TOKEN_EXTENDS, OptionType.STRING, ""));
    temp.add (new OptionInfo (USEROPTION__TOKEN_FACTORY, OptionType.STRING, ""));
    temp.add (new OptionInfo (USEROPTION__GRAMMAR_ENCODING, OptionType.STRING, ""));
    temp.add (new OptionInfo (USEROPTION__OUTPUT_LANGUAGE, OptionType.STRING, OUTPUT_LANGUAGE__JAVA));

    temp.add (new OptionInfo (USEROPTION__JAVA_TEMPLATE_TYPE, OptionType.STRING, JAVA_TEMPLATE_TYPE_CLASSIC));
    temp.add (new OptionInfo (USEROPTION_CPP_NAMESPACE, OptionType.STRING, ""));
    temp.add (new OptionInfo (USEROPTION__CPP_TOKEN_INCLUDES, OptionType.STRING, ""));
    temp.add (new OptionInfo (USEROPTION__CPP_PARSER_INCLUDES, OptionType.STRING, ""));

    temp.add (new OptionInfo (USEROPTION__CPP_TOKEN_MANAGER_INCLUDES, OptionType.STRING, ""));
    temp.add (new OptionInfo (USEROPTION__CPP_IGNORE_ACTIONS, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__CPP_STOP_ON_FIRST_ERROR, OptionType.BOOLEAN, Boolean.FALSE));
    temp.add (new OptionInfo (USEROPTION__CPP_TOKEN_MANAGER_SUPERCLASS, OptionType.STRING, ""));

    userOptions = Collections.unmodifiableSet (temp);
  }

  /**
   * A mapping of option names (Strings) to values (Integer, Boolean, String).
   * This table is initialized by the main program. Its contents defines the set
   * of legal options. Its initial values define the default option values, and
   * the option types can be determined from these values too.
   */
  protected static Map  optionValues = null;

  /**
   * Initialize for JavaCC
   */
  public static void init ()
  {
    optionValues = new HashMap  ();
    cmdLineSetting = new HashSet  ();
    inputFileSetting = new HashSet  ();

    for (final OptionInfo t : userOptions)
    {
      optionValues.put (t.getName (), t.getDefault ());
    }

    {
      final Object object = optionValues.get (USEROPTION__JAVA_TEMPLATE_TYPE);
      final boolean isLegacy = JAVA_TEMPLATE_TYPE_CLASSIC.equals (object);
      optionValues.put (NONUSER_OPTION__LEGACY_EXCEPTION_HANDLING, isLegacy);
    }

  }

  /**
   * Convenience method to retrieve integer options.
   */
  public static int intValue (final String option)
  {
    return ((Integer) optionValues.get (option)).intValue ();
  }

  /**
   * Convenience method to retrieve boolean options.
   */
  public static boolean booleanValue (final String option)
  {
    return ((Boolean) optionValues.get (option)).booleanValue ();
  }

  /**
   * Convenience method to retrieve string options.
   */
  public static String stringValue (final String option)
  {
    return (String) optionValues.get (option);
  }

  public static Map  getOptions ()
  {
    final HashMap  ret = new HashMap  (optionValues);
    return ret;
  }

  /**
   * Keep track of what options were set as a command line argument. We use this
   * to see if the options set from the command line and the ones set in the
   * input files clash in any way.
   */
  private static Set  cmdLineSetting = null;

  /**
   * Keep track of what options were set from the grammar file. We use this to
   * see if the options set from the command line and the ones set in the input
   * files clash in any way.
   */
  private static Set  inputFileSetting = null;

  /**
   * Returns a string representation of the specified options of interest. Used
   * when, for example, generating Token.java to record the JavaCC options that
   * were used to generate the file. All of the options must be boolean values.
   * 
   * @param interestingOptions
   *        the options of interest, eg {Options.USEROPTION__STATIC,
   *        Options.USEROPTION__CACHE_TOKENS}
   * @return the string representation of the options, eg
   *         "STATIC=true,CACHE_TOKENS=false"
   */
  public static String getOptionsString (final String [] interestingOptions)
  {
    final StringBuffer sb = new StringBuffer ();

    for (int i = 0; i < interestingOptions.length; i++)
    {
      final String key = interestingOptions[i];
      sb.append (key);
      sb.append ('=');
      sb.append (optionValues.get (key));
      if (i != interestingOptions.length - 1)
      {
        sb.append (',');
      }
    }

    return sb.toString ();
  }

  public static String getTokenMgrErrorClass ()
  {
    return isOutputLanguageJava () ? (isLegacyExceptionHandling () ? "TokenMgrError" : "TokenMgrException")
                                  : "TokenMgrError";
  }

  /**
   * Determine if a given command line argument might be an option flag. Command
   * line options start with a dash (-).
   * 
   * @param opt
   *        The command line argument to examine.
   * @return True when the argument looks like an option flag.
   */
  public static boolean isOption (final String opt)
  {
    return opt != null && opt.length () > 1 && opt.charAt (0) == '-';
  }

  /**
   * Help function to handle cases where the meaning of an option has changed
   * over time. If the user has supplied an option in the old format, it will be
   * converted to the new format.
   * 
   * @param name
   *        The name of the option being checked.
   * @param value
   *        The option's value.
   * @return The upgraded value.
   */
  public static Object upgradeValue (final String name, Object value)
  {
    if (name.equalsIgnoreCase ("NODE_FACTORY") && value.getClass () == Boolean.class)
    {
      if (((Boolean) value).booleanValue ())
      {
        value = "*";
      }
      else
      {
        value = "";
      }
    }

    return value;
  }

  public static void setInputFileOption (final Object nameloc, final Object valueloc, final String name, Object value)
  {
    final String s = name.toUpperCase ();
    if (!optionValues.containsKey (s))
    {
      JavaCCErrors.warning (nameloc, "Bad option name \"" + name + "\".  Option setting will be ignored.");
      return;
    }
    final Object existingValue = optionValues.get (s);

    value = upgradeValue (name, value);

    if (existingValue != null)
    {

      final boolean isIndirectProperty = s.equalsIgnoreCase (NONUSER_OPTION__LEGACY_EXCEPTION_HANDLING);

      if (isIndirectProperty ||
          ((existingValue.getClass () != value.getClass ()) || (value instanceof Integer && ((Integer) value).intValue () <= 0)))
      {
        JavaCCErrors.warning (valueloc, "Bad option value \"" +
                                        value +
                                        "\" for \"" +
                                        name +
                                        "\".  Option setting will be ignored.");
        return;
      }

      if (inputFileSetting.contains (s))
      {
        JavaCCErrors.warning (nameloc, "Duplicate option setting for \"" + name + "\" will be ignored.");
        return;
      }

      if (cmdLineSetting.contains (s))
      {
        if (!existingValue.equals (value))
        {
          JavaCCErrors.warning (nameloc, "Command line setting of \"" + name + "\" modifies option value in file.");
        }
        return;
      }
    }

    optionValues.put (s, value);
    inputFileSetting.add (s);

    // Special case logic block here for setting indirect flags

    if (s.equalsIgnoreCase (USEROPTION__JAVA_TEMPLATE_TYPE))
    {
      final String templateType = (String) value;
      if (!isValidJavaTemplateType (templateType))
      {
        JavaCCErrors.warning (valueloc, "Bad option value \"" +
                                        value +
                                        "\" for \"" +
                                        name +
                                        "\".  Option setting will be ignored. Valid options : " +
                                        getAllValidJavaTemplateTypes ());
        return;
      }

      final boolean isLegacy = JAVA_TEMPLATE_TYPE_CLASSIC.equals (templateType);
      optionValues.put (NONUSER_OPTION__LEGACY_EXCEPTION_HANDLING, isLegacy);
    }
    else
      if (s.equalsIgnoreCase (USEROPTION__OUTPUT_LANGUAGE))
      {
        final String templateType = (String) value;
        if (!isValidOutputLanguage (templateType))
        {
          JavaCCErrors.warning (valueloc, "Bad option value \"" +
                                          value +
                                          "\" for \"" +
                                          name +
                                          "\".  Option setting will be ignored. Valid options : " +
                                          getAllValidLanguages ());
          return;
        }

      }
      else
        if (s.equalsIgnoreCase (USEROPTION_CPP_NAMESPACE))
        {
          processCPPNamespaceOption ((String) value);
        }
  }

  private static String getAllValidJavaTemplateTypes ()
  {
    return Arrays.toString (supportedJavaTemplateTypes.toArray (new String [supportedJavaTemplateTypes.size ()]));
  }

  private static String getAllValidLanguages ()
  {
    return Arrays.toString (supportedLanguages.toArray (new String [supportedLanguages.size ()]));
  }

  /**
   * Process a single command-line option. The option is parsed and stored in
   * the optionValues map.
   * 
   * @param arg
   */
  public static void setCmdLineOption (final String arg)
  {
    final String s;

    if (arg.charAt (0) == '-')
    {
      s = arg.substring (1);
    }
    else
    {
      s = arg;
    }

    String name;
    Object Val;

    // Look for the first ":" or "=", which will separate the option name
    // from its value (if any).
    final int index1 = s.indexOf ('=');
    final int index2 = s.indexOf (':');
    final int index;

    if (index1 < 0)
      index = index2;
    else
      if (index2 < 0)
        index = index1;
      else
        if (index1 < index2)
          index = index1;
        else
          index = index2;

    if (index < 0)
    {
      name = s.toUpperCase ();
      if (optionValues.containsKey (name))
      {
        Val = Boolean.TRUE;
      }
      else
        if (name.length () > 2 && name.charAt (0) == 'N' && name.charAt (1) == 'O')
        {
          Val = Boolean.FALSE;
          name = name.substring (2);
        }
        else
        {
          System.out.println ("Warning: Bad option \"" + arg + "\" will be ignored.");
          return;
        }
    }
    else
    {
      name = s.substring (0, index).toUpperCase ();
      if (s.substring (index + 1).equalsIgnoreCase ("TRUE"))
      {
        Val = Boolean.TRUE;
      }
      else
        if (s.substring (index + 1).equalsIgnoreCase ("FALSE"))
        {
          Val = Boolean.FALSE;
        }
        else
        {
          try
          {
            final int i = Integer.parseInt (s.substring (index + 1));
            if (i <= 0)
            {
              System.out.println ("Warning: Bad option value in \"" + arg + "\" will be ignored.");
              return;
            }
            Val = new Integer (i);
          }
          catch (final NumberFormatException e)
          {
            Val = s.substring (index + 1);
            if (s.length () > index + 2)
            {
              // i.e., there is space for two '"'s in value
              if (s.charAt (index + 1) == '"' && s.charAt (s.length () - 1) == '"')
              {
                // remove the two '"'s.
                Val = s.substring (index + 2, s.length () - 1);
              }
            }
          }
        }
    }

    if (!optionValues.containsKey (name))
    {
      System.out.println ("Warning: Bad option \"" + arg + "\" will be ignored.");
      return;
    }
    final Object valOrig = optionValues.get (name);
    if (Val.getClass () != valOrig.getClass ())
    {
      System.out.println ("Warning: Bad option value in \"" + arg + "\" will be ignored.");
      return;
    }
    if (cmdLineSetting.contains (name))
    {
      System.out.println ("Warning: Duplicate option setting \"" + arg + "\" will be ignored.");
      return;
    }

    Val = upgradeValue (name, Val);

    optionValues.put (name, Val);
    cmdLineSetting.add (name);
    if (name.equalsIgnoreCase (USEROPTION_CPP_NAMESPACE))
    {
      processCPPNamespaceOption ((String) Val);
    }
  }

  public static void normalize ()
  {
    if (getDebugLookahead () && !getDebugParser ())
    {
      if (cmdLineSetting.contains (USEROPTION__DEBUG_PARSER) || inputFileSetting.contains (USEROPTION__DEBUG_PARSER))
      {
        JavaCCErrors.warning ("True setting of option DEBUG_LOOKAHEAD overrides "
                              + "false setting of option DEBUG_PARSER.");
      }
      optionValues.put (USEROPTION__DEBUG_PARSER, Boolean.TRUE);
    }

    // Now set the "GENERATE" options from the supplied (or default) JDK
    // version.

    optionValues.put (USEROPTION__GENERATE_CHAINED_EXCEPTION, Boolean.valueOf (jdkVersionAtLeast (1.4)));
    optionValues.put (USEROPTION__GENERATE_GENERICS, Boolean.valueOf (jdkVersionAtLeast (1.5)));
    optionValues.put (USEROPTION__GENERATE_STRING_BUILDER, Boolean.valueOf (jdkVersionAtLeast (1.5)));
    optionValues.put (USEROPTION__GENERATE_ANNOTATIONS, Boolean.valueOf (jdkVersionAtLeast (1.5)));
  }

  /**
   * Find the lookahead setting.
   * 
   * @return The requested lookahead value.
   */
  public static int getLookahead ()
  {
    return intValue (USEROPTION__LOOKAHEAD);
  }

  /**
   * Find the choice ambiguity check value.
   * 
   * @return The requested choice ambiguity check value.
   */
  public static int getChoiceAmbiguityCheck ()
  {
    return intValue (USEROPTION__CHOICE_AMBIGUITY_CHECK);
  }

  /**
   * Find the other ambiguity check value.
   * 
   * @return The requested other ambiguity check value.
   */
  public static int getOtherAmbiguityCheck ()
  {
    return intValue (USEROPTION__OTHER_AMBIGUITY_CHECK);
  }

  /**
   * Find the static value.
   * 
   * @return The requested static value.
   */
  public static boolean getStatic ()
  {
    return booleanValue (USEROPTION__STATIC);
  }

  /**
   * Find the debug parser value.
   * 
   * @return The requested debug parser value.
   */
  public static boolean getDebugParser ()
  {
    return booleanValue (USEROPTION__DEBUG_PARSER);
  }

  /**
   * Find the debug lookahead value.
   * 
   * @return The requested debug lookahead value.
   */
  public static boolean getDebugLookahead ()
  {
    return booleanValue (USEROPTION__DEBUG_LOOKAHEAD);
  }

  /**
   * Find the debug tokenmanager value.
   * 
   * @return The requested debug tokenmanager value.
   */
  public static boolean getDebugTokenManager ()
  {
    return booleanValue (USEROPTION__DEBUG_TOKEN_MANAGER);
  }

  /**
   * Find the error reporting value.
   * 
   * @return The requested error reporting value.
   */
  public static boolean getErrorReporting ()
  {
    return booleanValue (USEROPTION__ERROR_REPORTING);
  }

  /**
   * Find the Java unicode escape value.
   * 
   * @return The requested Java unicode escape value.
   */
  public static boolean getJavaUnicodeEscape ()
  {
    return booleanValue (USEROPTION__JAVA_UNICODE_ESCAPE);
  }

  /**
   * Find the unicode input value.
   * 
   * @return The requested unicode input value.
   */
  public static boolean getUnicodeInput ()
  {
    return booleanValue (USEROPTION__UNICODE_INPUT);
  }

  /**
   * Find the ignore case value.
   * 
   * @return The requested ignore case value.
   */
  public static boolean getIgnoreCase ()
  {
    return booleanValue (USEROPTION__IGNORE_CASE);
  }

  /**
   * Find the user tokenmanager value.
   * 
   * @return The requested user tokenmanager value.
   */
  public static boolean getUserTokenManager ()
  {
    return booleanValue (USEROPTION__USER_TOKEN_MANAGER);
  }

  /**
   * Find the user charstream value.
   * 
   * @return The requested user charstream value.
   */
  public static boolean getUserCharStream ()
  {
    return booleanValue (USEROPTION__USER_CHAR_STREAM);
  }

  /**
   * Find the build parser value.
   * 
   * @return The requested build parser value.
   */
  public static boolean getBuildParser ()
  {
    return booleanValue (USEROPTION__BUILD_PARSER);
  }

  /**
   * Find the build token manager value.
   * 
   * @return The requested build token manager value.
   */
  public static boolean getBuildTokenManager ()
  {
    return booleanValue (USEROPTION__BUILD_TOKEN_MANAGER);
  }

  /**
   * Find the token manager uses parser value.
   * 
   * @return The requested token manager uses parser value;
   */
  public static boolean getTokenManagerUsesParser ()
  {
    return booleanValue (USEROPTION__TOKEN_MANAGER_USES_PARSER);
  }

  /**
   * Find the sanity check value.
   * 
   * @return The requested sanity check value.
   */
  public static boolean getSanityCheck ()
  {
    return booleanValue (USEROPTION__SANITY_CHECK);
  }

  /**
   * Find the force lookahead check value.
   * 
   * @return The requested force lookahead value.
   */
  public static boolean getForceLaCheck ()
  {
    return booleanValue (USEROPTION__FORCE_LA_CHECK);
  }

  /**
   * Find the common token action value.
   * 
   * @return The requested common token action value.
   */

  public static boolean getCommonTokenAction ()
  {
    return booleanValue (USEROPTION__COMMON_TOKEN_ACTION);
  }

  /**
   * Find the cache tokens value.
   * 
   * @return The requested cache tokens value.
   */
  public static boolean getCacheTokens ()
  {
    return booleanValue (USEROPTION__CACHE_TOKENS);
  }

  /**
   * Find the keep line column value.
   * 
   * @return The requested keep line column value.
   */
  public static boolean getKeepLineColumn ()
  {
    return booleanValue (USEROPTION__KEEP_LINE_COLUMN);
  }

  /**
   * Find the JDK version.
   * 
   * @return The requested jdk version.
   */
  public static String getJdkVersion ()
  {
    return stringValue (USEROPTION__JDK_VERSION);
  }

  /**
   * Should the generated code create Exceptions using a constructor taking a
   * nested exception?
   * 
   * @return
   */
  public static boolean getGenerateChainedException ()
  {
    return booleanValue (USEROPTION__GENERATE_CHAINED_EXCEPTION);
  }

  public static boolean isGenerateBoilerplateCode ()
  {
    return booleanValue (USEROPTION__GENERATE_BOILERPLATE);
  }

  /**
   * As of 6.1 JavaCC now throws subclasses of {@link RuntimeException} rather
   * than {@link Error} s (by default), as {@link Error} s typically lead to the
   * closing down of the parent VM and are only to be used in extreme
   * circumstances (failure of parsing is generally not regarded as such). If
   * this value is set to true, then then {@link Error}s will be thrown (for
   * compatibility with older .jj files)
   * 
   * @return true if throws errors (legacy), false if use
   *         {@link RuntimeException} s (better approach)
   */
  public static boolean isLegacyExceptionHandling ()
  {
    final boolean booleanValue = booleanValue (NONUSER_OPTION__LEGACY_EXCEPTION_HANDLING);
    return booleanValue;
  }

  /**
   * Should the generated code contain Generics?
   * 
   * @return
   */
  public static boolean getGenerateGenerics ()
  {
    return booleanValue (USEROPTION__GENERATE_GENERICS);
  }

  /**
   * Should the generated code use StringBuilder rather than StringBuffer?
   * 
   * @return
   */
  public static boolean getGenerateStringBuilder ()
  {
    return booleanValue (USEROPTION__GENERATE_STRING_BUILDER);
  }

  /**
   * Should the generated code contain Annotations?
   * 
   * @return
   */
  public static boolean getGenerateAnnotations ()
  {
    return booleanValue (USEROPTION__GENERATE_ANNOTATIONS);
  }

  /**
   * Should the generated code class visibility public?
   * 
   * @return
   */
  public static boolean getSupportClassVisibilityPublic ()
  {
    return booleanValue (USEROPTION__SUPPORT_CLASS_VISIBILITY_PUBLIC);
  }

  /**
   * Determine if the output language is at least the specified version.
   * 
   * @param version
   *        the version to check against. E.g. 1.5
   * @return true if the output version is at least the specified version.
   */
  public static boolean jdkVersionAtLeast (final double version)
  {
    final double jdkVersion = Double.parseDouble (getJdkVersion ());

    // Comparing doubles is safe here, as it is two simple assignments.
    return jdkVersion >= version;
  }

  /**
   * Return the Token's superclass.
   * 
   * @return The required base class for Token.
   */
  public static String getTokenExtends ()
  {
    return stringValue (USEROPTION__TOKEN_EXTENDS);
  }

  // public static String getBoilerplatePackage()
  // {
  // return stringValue(BOILERPLATE_PACKAGE);
  // }

  /**
   * Return the Token's factory class.
   * 
   * @return The required factory class for Token.
   */
  public static String getTokenFactory ()
  {
    return stringValue (USEROPTION__TOKEN_FACTORY);
  }

  /**
   * Return the file encoding; this will return the file.encoding system
   * property if no value was explicitly set
   * 
   * @return The file encoding (e.g., UTF-8, ISO_8859-1, MacRoman)
   */
  public static String getGrammarEncoding ()
  {
    if (stringValue (USEROPTION__GRAMMAR_ENCODING).equals (""))
    {
      return System.getProperties ().getProperty ("file.encoding");
    }
    else
    {
      return stringValue (USEROPTION__GRAMMAR_ENCODING);
    }
  }

  /**
   * Find the output directory.
   * 
   * @return The requested output directory.
   */
  public static File getOutputDirectory ()
  {
    return new File (stringValue (USEROPTION__OUTPUT_DIRECTORY));
  }

  public static String stringBufOrBuild ()
  {
    // TODO :: CBA -- Require Unification of output language specific
    // processing into a single Enum class
    if (isOutputLanguageJava () && getGenerateStringBuilder ())
    {
      return getGenerateStringBuilder () ? "StringBuilder" : "StringBuffer";
    }
    else
      if (getOutputLanguage ().equals (OUTPUT_LANGUAGE__CPP))
      {
        return "StringBuffer";
      }
      else
      {
        throw new RuntimeException ("Output language type not fully implemented : " + getOutputLanguage ());
      }
  }

  private static final Set  supportedJavaTemplateTypes = new HashSet  ();
  static
  {
    supportedJavaTemplateTypes.add (JAVA_TEMPLATE_TYPE_CLASSIC);
    supportedJavaTemplateTypes.add (JAVA_TEMPLATE_TYPE_MODERN);
  }

  private static final Set  supportedLanguages = new HashSet  ();
  static
  {
    supportedLanguages.add (OUTPUT_LANGUAGE__JAVA);
    supportedLanguages.add (OUTPUT_LANGUAGE__CPP);
  }

  public static boolean isValidOutputLanguage (final String language)
  {
    return language == null ? false : supportedLanguages.contains (language.toLowerCase ());
  }

  public static boolean isValidJavaTemplateType (final String type)
  {
    return type == null ? false : supportedJavaTemplateTypes.contains (type.toLowerCase ());
  }

  /**
   * @return the output language. default java
   */
  public static String getOutputLanguage ()
  {
    return stringValue (USEROPTION__OUTPUT_LANGUAGE);
  }

  public static String getJavaTemplateType ()
  {
    return stringValue (USEROPTION__JAVA_TEMPLATE_TYPE);
  }

  public static void setStringOption (final String optionName, final String optionValue)
  {
    optionValues.put (optionName, optionValue);
    if (optionName.equalsIgnoreCase (USEROPTION_CPP_NAMESPACE))
    {
      processCPPNamespaceOption (optionValue);
    }
  }

  public static void processCPPNamespaceOption (final String optionValue)
  {
    final String ns = optionValue;
    if (ns.length () > 0)
    {
      // We also need to split it.
      final StringTokenizer st = new StringTokenizer (ns, "::");
      String expanded_ns = st.nextToken () + " {";
      String ns_close = "}";
      while (st.hasMoreTokens ())
      {
        expanded_ns = expanded_ns + "\nnamespace " + st.nextToken () + " {";
        ns_close = ns_close + "\n}";
      }
      optionValues.put (NONUSER_OPTION__NAMESPACE_OPEN, expanded_ns);
      optionValues.put (NONUSER_OPTION__HAS_NAMESPACE, Boolean.TRUE);
      optionValues.put (NONUSER_OPTION__NAMESPACE_CLOSE, ns_close);
    }
  }

  public static String getLongType ()
  {
    // TODO :: CBA -- Require Unification of output language specific
    // processing into a single Enum class
    if (isOutputLanguageJava ())
    {
      return "long";
    }
    else
      if (getOutputLanguage ().equals (OUTPUT_LANGUAGE__CPP))
      {
        return "unsigned long long";
      }
      else
      {
        throw new RuntimeException ("Language type not fully supported : " + getOutputLanguage ());
      }
  }

  public static String getBooleanType ()
  {
    // TODO :: CBA -- Require Unification of output language specific
    // processing into a single Enum class
    if (isOutputLanguageJava ())
    {
      return "boolean";
    }
    else
      if (getOutputLanguage ().equals (OUTPUT_LANGUAGE__CPP))
      {
        return "bool";
      }
      else
      {
        throw new RuntimeException ("Language type not fully supported : " + getOutputLanguage ());
      }
  }

  public static boolean isOutputLanguageJava ()
  {
    return getOutputLanguage ().equalsIgnoreCase (OUTPUT_LANGUAGE__JAVA);
  }

  public static boolean isOutputLanguageCPP ()
  {
    return getOutputLanguage ().equalsIgnoreCase (OUTPUT_LANGUAGE__CPP);
  }

  public static boolean isTokenManagerRequiresParserAccess ()
  {
    return getTokenManagerUsesParser ();
  }

  /**
   * Gets all the user options (in order)
   * 
   * @return
   */
  public static Set  getUserOptions ()
  {
    return userOptions;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy