alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Parser.java)

This example Java source code file (Parser.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

binaryexpr, expression, interfaceentry, ioexception, math, methodentry, moduleentry, parseexception, primitiveentry, string, symtabentry, typedefentry, unionentry, util, valueentry, vector

The Parser.java Java example source code

/*
 * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
/*
 * COMPONENT_NAME: idl.parser
 *
 * ORIGINS: 27
 *
 * Licensed Materials - Property of IBM
 * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
 * RMI-IIOP v1.0
 *
 */

package com.sun.tools.corba.se.idl;

// NOTES:
// -F46082.51<daz> Remove -stateful feature.
// -D52042<daz> Allow floating-point constants to be initialized with
//  integral as well as floating-point literals.  No other variations allowed.
// -D58058<daz> Set index array type to long rather than array element type.
// -D56351<daz> Update computation of RepositoryIDs to CORBA 2.3 (see spec.).
// -D57110<daz> Provide method() to set/clear ability for scoped names to
//  resolve to modules.  Allows rep. ids to be assigned to modules.
// -D46094<daz> Prohibit exceptions from appearing wihtin structs, unions, exceptions.
// -D46094<daz> Prohibit attributes from appearing as operation parameter types,
//  operation return types, attribute types.
// -D59067<daz> Prohibit nested value boxes.
// -D59166<daz> Prohibit collisions between keywords and non-escaped identifiers.
// -D59809<daz> At Pigeonhole(), add map short name of CORBA types to long name
//  (e.g., CORBA/StringValue --> org/omg/CORBA/StringValue), which allows fully-
//  qualified CORBA type names to resolve successfully.
// -F60858.1<daz> Support "-corba" option, level <= 2.2: issue warning for
//  keyowrd collisions;
// -D60942<daz> Prohibit operations from appearing within parameter types.
// -D61643<daz> Repair pigeonhole() to correctly filter bad RepIDs.
// -D62023<daz> Support -noWarn option; Issue warnings when tokens are
//  deprecated keywords or keywords in greater release version.
// -D61919<daz> Emit entries for modules originally opened in #include files
//  appearing at global scope and then reopened in the main IDL file.  Only
//  types appearing in the main IDL source will be emitted.

import java.io.EOFException;
import java.io.IOException;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Stack;
import java.util.Vector;
import java.util.List ;
import java.util.ArrayList ;
import java.util.Iterator ;

import java.math.BigInteger;

import com.sun.tools.corba.se.idl.constExpr.*;

/**
 *
 **/
class Parser
{
  /**
   *
   **/
  Parser (Preprocessor preprocessor, Arguments arguments, Hashtable overrides,
      Hashtable symtab, SymtabFactory stFac, ExprFactory exprFac, String [] genKeywords)
  {
    this.arguments = arguments;
    noWarn         = arguments.noWarn; // <d62023>
    corbaLevel     = arguments.corbaLevel; // <f60858.1>
    paths          = arguments.includePaths;
    symbols        = arguments.definedSymbols;
    verbose        = arguments.verbose;
    emitAll        = arguments.emitAll;
    // <f46082.46.01>
    cppModule      = arguments.cppModule;
    // <f46082.51> Remove -stateful feature.
    //parseStateful  = arguments.parseStateful;
    overrideNames  = (overrides == null) ? new Hashtable () : overrides;
    symbolTable    = (symtab == null) ? new Hashtable () : symtab;
    keywords       = (genKeywords == null) ? new String [0] : genKeywords;
    stFactory      = stFac;
    exprFactory    = exprFac;
    currentModule  = topLevelModule = new ModuleEntry ();
    prep           = preprocessor;
    repIDStack.push (new IDLID ());
    addPrimEntries ();
  } // ctor

  /**
   *
   **/
  void parse (String file) throws IOException
  {
    IncludeEntry fileEntry = stFactory.includeEntry ();
    fileEntry.name ('"' + file + '"');
    try
    {
      // Set absolute file path
      fileEntry.absFilename (Util.getAbsolutePath (file, paths));
    }
    catch (IOException ioe)
    {}

    // <f46082.51> Remove -stateful feature.
    //scanner = new Scanner (fileEntry, keywords, verbose, parseStateful, emitAll);
    // <f60585.1> Support "-corba [level]" option.
    //scanner = new Scanner (fileEntry, keywords, verbose, emitAll);
    scanner = new Scanner (fileEntry, keywords, verbose, emitAll, corbaLevel,
        arguments.scannerDebugFlag );
    topLevelModule.sourceFile (fileEntry);

    // Prime the pump...
    // Match handles preprocessor directives, so use match to
    // call scanner.getToken just in case the first token is
    // such a directive.  But match depends on the token
    // already having a value, so fudge something.
    token = new Token (0);
    tokenHistory.insert (token); // Initialize look back buffer <26jul1997daz>.
    try
    {
      match (0);
      if (token.equals (Token.EOF))
        ParseException.nothing (file);
      else
        specification (topLevelModule);
    }
    catch (ParseException exception)  // Match MIGHT throw this
    {
      // It has already been reported, just end.
    }
    catch (EOFException exception)  // skipToSemicolon MIGHT throw this
    {
      // It has already been reported, just end.
    }
  } // parse

  /**
   *
   **/
  private void addPrimEntries ()
  {
    symbolTable.put ("short", stFactory.primitiveEntry ("short"));
    symbolTable.put ("long", stFactory.primitiveEntry ("long"));
    symbolTable.put ("long long", stFactory.primitiveEntry ("long long"));
    symbolTable.put ("unsigned short", stFactory.primitiveEntry ("unsigned short"));
    symbolTable.put ("unsigned long", stFactory.primitiveEntry ("unsigned long"));
    symbolTable.put ("unsigned long long", stFactory.primitiveEntry ("unsigned long long"));
    symbolTable.put ("char", stFactory.primitiveEntry ("char"));
    symbolTable.put ("wchar", stFactory.primitiveEntry ("wchar"));
    symbolTable.put ("float", stFactory.primitiveEntry ("float"));
    //Support fixed type: symbolTable.put ("fixed", stFactory.primitiveEntry ("fixed"));
    symbolTable.put ("double", stFactory.primitiveEntry ("double"));
    symbolTable.put ("boolean", stFactory.primitiveEntry ("boolean"));
    symbolTable.put ("octet", stFactory.primitiveEntry ("octet"));
    symbolTable.put ("any", stFactory.primitiveEntry ("any"));

    InterfaceEntry object = stFactory.interfaceEntry();
    object.name ("Object");
    symbolTable.put ("Object", object);

    ValueEntry valueBase = stFactory.valueEntry();
    valueBase.name ("ValueBase");
    symbolTable.put ("ValueBase", valueBase);

    // put these same entries in the lowercase symbol table
    lcSymbolTable.put ("short", stFactory.primitiveEntry ("short"));
    lcSymbolTable.put ("long", stFactory.primitiveEntry ("long"));
    lcSymbolTable.put ("long long", stFactory.primitiveEntry ("long long"));
    lcSymbolTable.put ("unsigned short", stFactory.primitiveEntry ("unsigned short"));
    lcSymbolTable.put ("unsigned long", stFactory.primitiveEntry ("unsigned long"));
    lcSymbolTable.put ("unsigned long long", stFactory.primitiveEntry ("unsigned long long"));
    lcSymbolTable.put ("char", stFactory.primitiveEntry ("char"));
    lcSymbolTable.put ("wchar", stFactory.primitiveEntry ("wchar"));
    lcSymbolTable.put ("float", stFactory.primitiveEntry ("float"));
    // Support fixed type: lcSymbolTable.put ("fixed", stFactory.primitiveEntry ("fixed"));
    lcSymbolTable.put ("double", stFactory.primitiveEntry ("double"));
    lcSymbolTable.put ("boolean", stFactory.primitiveEntry ("boolean"));
    lcSymbolTable.put ("octet", stFactory.primitiveEntry ("octet"));
    lcSymbolTable.put ("any", stFactory.primitiveEntry ("any"));
    lcSymbolTable.put ("object", object);
    lcSymbolTable.put ("valuebase", valueBase);
  } // addPrimEntries

  /**
   *
   **/
  private void specification (ModuleEntry entry) throws IOException
  {
    while (!token.equals (Token.EOF))
    {
      definition (entry);
      addToEmitList (entry);
    }
  } // specification

  // ModuleEntry is the topLevelModule; add its contained types to the emit list.
  /**
   *
   **/
  private void addToEmitList (ModuleEntry entry)
  {
    for (Enumeration e = entry.contained ().elements (); e.hasMoreElements();)
    {
      SymtabEntry emitEntry = (SymtabEntry)e.nextElement ();
      if (emitEntry.emit ())
      {
        emitList.addElement (emitEntry);

        // <d61919> I think the absence of the following statement was an
        // oversight.  If module X.Y.Z first appears in an include file, then is
        // reopened in the main IDL source, this statement guarantees that X.Y.Z
        // definitions within the main IDL source are emitted.
        ///---------------------------------------------------------------------
        // If any of this module's elements should be emitted, add
        // this module to the emit list.
        if (emitEntry instanceof ModuleEntry)
          checkContained ((ModuleEntry)emitEntry);
        if (emitEntry instanceof IncludeEntry)
        {
          includes.addElement (emitEntry.name ());
          includeEntries.addElement (emitEntry);
        }
      }
      else
        // If any of this module's elements should be emitted, add
        // this module to the emit list.
        if (emitEntry instanceof ModuleEntry)
          checkContained ((ModuleEntry)emitEntry);
    }
    entry.contained ().removeAllElements ();
  } // addToEmitList

  /**
   *
   **/
  private void checkContained (ModuleEntry entry)
  {
    // If any of this module's elements is to be emitted,
    // then add the module to the emit list.
    for (Enumeration e = entry.contained ().elements (); e.hasMoreElements ();)
    {
      SymtabEntry contained = (SymtabEntry)e.nextElement ();
      if (contained instanceof ModuleEntry)
        checkContained ((ModuleEntry)contained);
      if (contained.emit ())
      {
        if (!emitList.contains (entry))
          emitList.addElement (entry);
        entry.emit (true);
        break;
      }
    }
  } // checkContained

  /**
   *
   **/
  private void definition (ModuleEntry entry) throws IOException
  {
    try
    {
      switch (token.type)
      {
        case Token.Typedef:
        case Token.Struct:
        case Token.Union:
        case Token.Enum:
          typeDcl (entry);
          break;
        case Token.Const:
          constDcl (entry);
          break;
        case Token.Native:
          nativeDcl (entry);
          break;
        case Token.Exception:
          exceptDcl (entry);
          break;
        case Token.Interface:
          interfaceProd (entry, InterfaceEntry.NORMAL);
          break;
        case Token.Local:
          match( Token.Local ) ;
          if (token.type ==  Token.Interface)
              interfaceProd( entry, InterfaceEntry.LOCAL ) ;
          else
              throw ParseException.syntaxError( scanner, new int[] {
                  Token.Interface }, token.type ) ;
          break ;
        case Token.Module:
          module (entry);
          break;
        case Token.Abstract:
          match (Token.Abstract);
          if (token.type == Token.Interface)
            interfaceProd (entry, InterfaceEntry.ABSTRACT);
          else if (token.type == Token.Valuetype)
            valueProd (entry, true);
          else
            throw ParseException.syntaxError (scanner, new int[] {
                Token.Interface, Token.Valuetype }, token.type);
          break;
        case Token.Custom:
        case Token.Valuetype:
          valueProd (entry, false);
          break;
        default:
          throw ParseException.syntaxError (scanner, new int[] {
              Token.Typedef, Token.Struct,    Token.Union,     Token.Enum,
              Token.Const,   Token.Exception, Token.Interface, Token.Valuetype,
              Token.Module }, token.type);
      }
      match (Token.Semicolon);
    }
    catch (ParseException e)
    {
      skipToSemicolon ();
    }
  } // definition

  /**
   *
   **/
  private void module (ModuleEntry entry) throws IOException, ParseException
  {
    match (Token.Module);
    repIDStack.push (((IDLID)repIDStack.peek ()).clone ());
    ModuleEntry newEntry = newModule (entry);
    ((IDLID)repIDStack.peek ()).appendToName (newEntry.name ());
    // comment must immediately precede "module" keyword
    newEntry.comment (tokenHistory.lookBack (1).comment);
    currentModule = newEntry;
    match (Token.Identifier);
    prep.openScope (newEntry);
    match (Token.LeftBrace);
    definition (newEntry);
    while (!token.equals (Token.EOF) && !token.equals (Token.RightBrace))
      definition (newEntry);
    prep.closeScope (newEntry);
    match (Token.RightBrace);
    currentModule = entry;
    repIDStack.pop ();
  } // module

  /**
   *
   **/
  private void interfaceProd (ModuleEntry entry, int interfaceType)
      throws IOException, ParseException
  {
    match (Token.Interface);
    String name = token.name;
    match (Token.Identifier);
    interface2 (entry, name, interfaceType);
  } // interfaceProd

  /**
   *
   **/
  private void interface2 (ModuleEntry module, String name, int interfaceType)
      throws IOException, ParseException
  {
    if (token.type == Token.Colon || token.type == Token.LeftBrace) {
        repIDStack.push (((IDLID)repIDStack.peek ()).clone ());
        InterfaceEntry entry = stFactory.interfaceEntry (module,
            (IDLID)repIDStack.peek ());
        entry.sourceFile (scanner.fileEntry ());
        entry.name (name);
        entry.setInterfaceType(interfaceType);
        // Comment must immediately precede "[local | abstract] interface" keyword
        entry.comment (tokenHistory.lookBack (
            entry.getInterfaceType() == InterfaceEntry.NORMAL ? 2 : 3).comment);

        if (!ForwardEntry.replaceForwardDecl (entry))
            ParseException.badAbstract (scanner, entry.fullName ());
        pigeonhole (module, entry);
        ((IDLID)repIDStack.peek ()).appendToName (name);
        currentModule = entry;
        interfaceDcl (entry);
        currentModule = module;
        repIDStack.pop ();
    } else  { // This is a forward declaration
        ForwardEntry entry = stFactory.forwardEntry (module, (IDLID)repIDStack.peek ());
        entry.sourceFile (scanner.fileEntry ());
        entry.name (name);
        entry.setInterfaceType(interfaceType);
        // comment must immediately precede "interface" keyword.
        entry.comment (tokenHistory.lookBack (
            entry.getInterfaceType() == InterfaceEntry.NORMAL ? 2 : 3).comment);
        pigeonhole (module, entry);
    }
  } // interface2

  /**
   *
   **/
  private void interfaceDcl (InterfaceEntry entry) throws IOException, ParseException
  {
    if (token.type != Token.LeftBrace)
        inheritanceSpec (entry);
    else if (!entry.isAbstract ()) {
        SymtabEntry objectEntry = qualifiedEntry ("Object");
        SymtabEntry realOEntry  = typeOf (objectEntry);
        if (objectEntry == null)
            ;  // qualifiedEntry already generated an error message
        else if (!isInterface(realOEntry))
            ParseException.wrongType (scanner, overrideName ("Object"),
                "interface", objectEntry.typeName ());
        else
            entry.derivedFromAddElement (realOEntry, scanner);
    }

    prep.openScope (entry);
    match (Token.LeftBrace);
    while (token.type != Token.RightBrace)
        export (entry);
    prep.closeScope (entry);
    match (Token.RightBrace);
  } // interfaceDcl

  /**
   *
   **/
  private void export (InterfaceEntry entry) throws IOException
  {
    try
    {
      switch (token.type)
      {
        case Token.Typedef:
        case Token.Struct:
        case Token.Union:
        case Token.Enum:
          typeDcl (entry);
          break;
        case Token.Const:
          constDcl (entry);
          break;
        case Token.Native:
          nativeDcl (entry);
          break;
        case Token.Exception:
          exceptDcl (entry);
          break;
        case Token.Readonly:
        case Token.Attribute:
          attrDcl (entry);
          break;
        case Token.Oneway:
        case Token.Float:
        case Token.Double:
        case Token.Long:
        case Token.Short:
        case Token.Unsigned:
        case Token.Char:
        case Token.Wchar:
        case Token.Boolean:
        case Token.Octet:
        case Token.Any:
        case Token.String:
        case Token.Wstring:
        case Token.Identifier:
        case Token.Object:
        // <f46082.40> Value base type.
        case Token.ValueBase:
        case Token.DoubleColon:
        case Token.Void:
          opDcl (entry);
          break;
        // <f46082.51> Remove -stateful feature.
        //case Token.State:       if (parseStateful) {
        //                          stateDef (entry);
        //                          break; }
        default:
          throw ParseException.syntaxError(scanner, new int [] {
              Token.Typedef,  Token.Struct,      Token.Union,        Token.Enum,
              Token.Const,    Token.Exception,   Token.Readonly,     Token.Attribute,
              Token.Oneway,   Token.Float,       Token.Double,       Token.Long,
              Token.Short,    Token.Unsigned,    Token.Char,         Token.Wchar,
              Token.Boolean,  Token.Octet,       Token.Any,          Token.String,
              Token.Wstring,  Token.Identifier,  Token.DoubleColon,  Token.Void,
              Token.ValueBase }, token.type);
      }
      match (Token.Semicolon);
    }
    catch (ParseException exception)
    {
      skipToSemicolon ();
    }
  } // export

  private void inheritanceSpec (InterfaceEntry entry) throws IOException, ParseException
  {
    for (match (Token.Colon); ; match (Token.Comma)) {
        SymtabEntry parent = scopedName (entry.container (),
            stFactory.interfaceEntry ());
        SymtabEntry realParent = typeOf (parent);

        if (isInterfaceOnly (realParent)) {
            boolean isInterface = (realParent instanceof InterfaceEntry);
            if (entry.derivedFrom ().contains (realParent))
                ParseException.alreadyDerived (scanner, realParent.fullName (), entry.fullName ());
            else if (!entry.isAbstract () ||
                (((InterfaceType)realParent).getInterfaceType() == InterfaceType.ABSTRACT))
                entry.derivedFromAddElement (realParent, scanner);
            else
                ParseException.nonAbstractParent (scanner, entry.fullName (), parent.fullName ());
        } else if (isForward( realParent )) {
            ParseException.illegalForwardInheritance( scanner,
                entry.fullName(), parent.fullName() ) ;
        } else
            ParseException.wrongType (scanner, parent.fullName (), "interface", entryName (parent));

        if ((parent instanceof InterfaceEntry) && (((InterfaceEntry)parent).state () != null))
            if (entry.state () == null)
                entry.initState ();
            else
                throw ParseException.badState (scanner, entry.fullName ());

        if (token.type != Token.Comma)
            break;
    }
  } // inheritanceSpec

  // <57110> Member _moduleIsLegalType may be set by any feature to allow
  // method scopedName() and any of its helper methods -- qualifiedName(),
  // partlyQualifiedName(), and unqualifiedName() -- to return a ModuleEntry
  // rather than a parse error in the event a name resolves to a module.  The
  // flag must be cleared (set to false) to resume normal parsing behavior.
  //
  // Currently, this is used only when preprocessing the ID pragma directive.

  private boolean _isModuleLegalType = false;

  /**
   *
   **/
  public boolean isModuleLegalType ()
  {
    return _isModuleLegalType;
  }; // moduleIsLegaType

  /**
   *
   **/
  public void isModuleLegalType (boolean b)
  {
    _isModuleLegalType = b;
  }; // moduleIsLegalType

  /**
   *
   **/
  SymtabEntry scopedName (SymtabEntry container,
    SymtabEntry expected) throws IOException, ParseException
  {
    return scopedName( container, expected, true ) ;
  }

  SymtabEntry scopedName (SymtabEntry container, SymtabEntry expected,
    boolean mustBeReferencable ) throws IOException, ParseException
  {
    boolean globalScope  = false;
    boolean partialScope = false;
    String  name         = null;
    if (token.type == Token.DoubleColon)
      globalScope = true;
    else
    {
      if (token.type == Token.Object)
      {
        name = "Object";
        match (Token.Object);
      }
      else if (token.type == Token.ValueBase) // <f46082.40>
      {
        name = "ValueBase";
        match (Token.ValueBase);
      }
      else
      {
        name = token.name;
        match (Token.Identifier);
      }
    }
    while (token.type == Token.DoubleColon)
    {
      match (Token.DoubleColon);
      partialScope = true;
      if (name != null)
        name += '/' + token.name;
      else name = token.name;
        match (Token.Identifier);
    }
    SymtabEntry entry = null;
    if (globalScope)
      entry = qualifiedEntry (name);
    else if (partialScope)
      entry = partlyQualifiedEntry (name, container);
    else
      entry = unqualifiedEntry (name, container);

    if (entry == null)
      // Make the entry the expected entry.  The generators will
      // not be called now, since a semantic exception ocurred, but
      // the parse has to finish and something valid has to be
      // returned.
      (entry = expected).name (name);
    else if (!entry.isReferencable() && mustBeReferencable)
      throw ParseException.illegalIncompleteTypeReference( scanner, name ) ;

    return entry;
  } // scopedName

  private void valueProd (ModuleEntry entry, boolean isAbstract) throws IOException, ParseException
  {
    boolean isCustom = (token.type == Token.Custom);
    if (isCustom)
      match (Token.Custom);
    match (Token.Valuetype);
    String name = token.name;
    match (Token.Identifier);

    switch (token.type)
    {
      case Token.LeftBrace:
      case Token.Colon:
      case Token.Supports:
        value2 (entry, name, isAbstract, isCustom);
        return;
      case Token.Semicolon:
        if (isCustom)
          break;
        valueForwardDcl (entry, name, isAbstract);
        return;
    }
    if (isCustom)
      throw ParseException.badCustom (scanner);
    if (isAbstract)
      throw ParseException.abstractValueBox (scanner);
    valueBox (entry, name);
  }  // valueProd

  /**
   *
   **/
  private void value2 (ModuleEntry module, String name, boolean isAbstract,
      boolean isCustom) throws IOException, ParseException
  {
    repIDStack.push (((IDLID)repIDStack.peek ()).clone ());
    // The 'actual' repository ID will be calculated at the end of the
    // parsing phase, since it is based on the entire contents of the
    // declaration, and needs to have all forward references resolved:
    ValueEntry entry = stFactory.valueEntry (module, (IDLID)repIDStack.peek ());
    entry.sourceFile (scanner.fileEntry ());
    entry.name (name);
    entry.setInterfaceType (isAbstract ? InterfaceType.ABSTRACT : InterfaceType.NORMAL);
    entry.setCustom (isCustom);
    // Comment must immediately precede "[abstract | custom] value" keyword
    entry.comment (tokenHistory.lookBack ((isAbstract || isCustom) ? 3 : 2).comment);
    // If this value has been forward declared, there are probably
    // other values which derive from a ForwardValueEntry.  Replace
    // those ForwardValueEntry's with this ValueEntry:
    if (!ForwardEntry.replaceForwardDecl (entry))
      ParseException.badAbstract (scanner, entry.fullName ());
    pigeonhole (module, entry);
    ((IDLID)repIDStack.peek ()).appendToName (name);
    currentModule = entry;
    valueDcl (entry);
    entry.tagMethods ();
    currentModule = module;
    repIDStack.pop ();
  } // value2

  /**
   *
   **/
  private void valueDcl (ValueEntry entry) throws IOException, ParseException
  {
    if (token.type == Token.Colon)
      valueInheritanceSpec (entry);
    else if (!entry.isAbstract ())
    {
      SymtabEntry objectEntry = qualifiedEntry ("ValueBase");
      SymtabEntry realOEntry  = typeOf (objectEntry);
      if (objectEntry == null)
        ; // qualifiedEntry already generated an error message
      else if (!isValue (realOEntry))
        ParseException.wrongType (scanner, overrideName ("ValueBase"), "value", objectEntry.typeName ());
      else
        entry.derivedFromAddElement (realOEntry, false, scanner);
    }
    if (token.type == Token.Supports)
      valueSupportsSpec (entry);
    prep.openScope (entry);
    match (Token.LeftBrace);
    while (token.type != Token.RightBrace)
    {
      valueElement (entry);
    }
    prep.closeScope (entry);
    match (Token.RightBrace);
  } // valueDcl

  /**
   *
   **/
  private void valueInheritanceSpec (ValueEntry entry) throws IOException, ParseException
  {
    match (Token.Colon);
    boolean isTruncatable = (token.type == Token.Truncatable);
    if (isTruncatable)
        match (Token.Truncatable);
    for (; ; match (Token.Comma), isTruncatable = false) {
        SymtabEntry parent = scopedName (entry.container (),
            stFactory.valueEntry ());
        SymtabEntry realParent = typeOf (parent);
        if (isValue (realParent) && !(realParent instanceof ValueBoxEntry))
            entry.derivedFromAddElement (realParent, isTruncatable,
                scanner);
        else if (isForward(realParent))
            ParseException.illegalForwardInheritance( scanner,
                entry.fullName(), parent.fullName() ) ;
        else
            ParseException.wrongType (scanner,
                parent.fullName (), "value", entryName (parent));
        if (token.type != Token.Comma)
            break;
    }
  } // valueInheritanceSpec

  /**
   *
   **/
  private void valueSupportsSpec (ValueEntry entry) throws IOException, ParseException
  {
    match (Token.Supports) ;
    for (; ; match( Token.Comma ) ) {
        SymtabEntry parent = scopedName (entry.container (), stFactory.interfaceEntry ());
        SymtabEntry realParent = typeOf (parent);
        if (isInterface(realParent))
            entry.derivedFromAddElement (realParent, scanner);
        else
            ParseException.wrongType (scanner, parent.fullName (), "interface",
                entryName (parent));

        if (token.type != Token.Comma)
            break;
    }
  }  // valueSupportsSpec

  private void valueElement (ValueEntry entry) throws IOException, ParseException
  {
    if (entry.isAbstract ())
      export (entry);
    else
      switch (token.type)
      {
        case Token.Private:
        case Token.Public:
          valueStateMember (entry);
          break;
        case Token.Init:
        case Token.Factory:  // <d62023> "factory" supplants "init" in 2.4RTF
          initDcl (entry);
          break;
        case Token.Typedef:
        case Token.Struct:
        case Token.Union:
        case Token.Enum:
        case Token.Const:
        case Token.Native:
        case Token.Exception:
        case Token.Readonly:
        case Token.Attribute:
        case Token.Oneway:
        case Token.Float:
        case Token.Double:
        case Token.Long:
        case Token.Short:
        case Token.Unsigned:
        case Token.Char:
        case Token.Wchar:
        case Token.Boolean:
        case Token.Octet:
        case Token.Any:
        case Token.String:
        case Token.Wstring:
        case Token.Identifier:
        case Token.Object:
        case Token.ValueBase:
        case Token.DoubleColon:
        case Token.Void:
          export (entry);
          break;
        default:
          throw ParseException.syntaxError(scanner, new int[] {
              Token.Private,  Token.Public,      Token.Init,         Token.ValueBase,
              Token.Typedef,  Token.Struct,      Token.Union,        Token.Enum,
              Token.Const,    Token.Exception,   Token.Readonly,     Token.Attribute,
              Token.Oneway,   Token.Float,       Token.Double,       Token.Long,
              Token.Short,    Token.Unsigned,    Token.Char,         Token.Wchar,
              Token.Boolean,  Token.Octet,       Token.Any,          Token.String,
              Token.Wstring,  Token.Identifier,  Token.DoubleColon,  Token.Void },
              token.type);
      }  // switch
  }  // valueElement

  // <f46082.40>
  /**
   *
   **/
  private void valueStateMember (ValueEntry entry) throws IOException, ParseException
  {
    TypedefEntry typedefEntry =
        stFactory.typedefEntry (entry, (IDLID)repIDStack.peek ());
    typedefEntry.sourceFile (scanner.fileEntry ());
    // comment must immediately precede "public", "private" keywords
    typedefEntry.comment (token.comment);
    boolean isPublic = (token.type == Token.Public);
    if (isPublic)
      match (Token.Public);
    else
      match (Token.Private);
    // <f46082.40> Add constructed types declared "inline" to the contained
    // vector of this value entry.
    boolean isConstTypeSpec =
        (token.type == Token.Struct || token.type == Token.Union || token.type == Token.Enum);
    // <f46082.40> Make typedefEntry anonymous.  If this line is removed,
    // the entry will be named incorrectly.  See <d50618>.
    typedefEntry.name ("");
    typedefEntry.type (typeSpec (typedefEntry));
    addDeclarators (entry, typedefEntry, isPublic);
    // <f46082.40>
    if (isConstTypeSpec)
      entry.addContained (typedefEntry);
    match (Token.Semicolon);
  }  // valueStateMember


  private void addDeclarators (ValueEntry entry, TypedefEntry typedefEntry,
      boolean isPublic) throws IOException, ParseException
  {
    int modifier = isPublic ? InterfaceState.Public : InterfaceState.Private;
    try
    {
      Vector typedefList = new Vector ();
      declarators (typedefEntry, typedefList);
      for (Enumeration e = typedefList.elements (); e.hasMoreElements ();)
        entry.addStateElement (
            new InterfaceState (modifier, (TypedefEntry)e.nextElement ()), scanner);
    }
    catch (ParseException exception)
    {
      skipToSemicolon ();
    }
  } // addDeclarators

  /**
   *
   **/
  private void initDcl (ValueEntry entry) throws IOException, ParseException
  {
    MethodEntry method = stFactory.methodEntry (entry, (IDLID)repIDStack.peek ());
    method.sourceFile (scanner.fileEntry ());
    // Comment must immediately precede "init" keyword:
    method.comment (token.comment);
    repIDStack.push (((IDLID)repIDStack.peek ()).clone ());
    ((IDLID)repIDStack.peek ()).appendToName (token.name);

    // <d62023> In 2.3 prelim,  ::= "init" "(" ...
    if (token.type == Token.Init)
    {
      method.name ("init");
      match (Token.Init);
      match (Token.LeftParen);
    }
    else // <d62023> In 2.4rtf,  ::= "factory"  "(" ...
    {
      match (Token.Factory);
      method.name (token.name);
      if (token.type == Token.MacroIdentifier)
        match (Token.MacroIdentifier);  // "(" already consumed.
      else
      {
        match (Token.Identifier);
        match (Token.LeftParen);
      }
    }

    if (token.type != Token.RightParen)
      for (;;)
      {
        initParamDcl (method);
        if (token.type == Token.RightParen)
          break;
        match (Token.Comma);
      }
    entry.initializersAddElement (method, scanner);
    match (Token.RightParen);
    match (Token.Semicolon);
    repIDStack.pop ();
  } // initDcl

  /**
   *
   **/
  private void initParamDcl (MethodEntry entry) throws IOException, ParseException
  {
    ParameterEntry parmEntry = stFactory.parameterEntry (entry, (IDLID)repIDStack.peek ());
    parmEntry.sourceFile (scanner.fileEntry());
    // Comment must immediately precede parameter attribute
    parmEntry.comment (token.comment);
    match (Token.In);
    parmEntry.passType (ParameterEntry.In);
    parmEntry.type (paramTypeSpec (entry));
    parmEntry.name (token.name);
    match (Token.Identifier);
    if (isntInList (entry.parameters (), parmEntry.name ()))
      entry.addParameter (parmEntry);
  } // initParamDcl

  /**
   *
   **/
  private void valueBox (ModuleEntry module, String name) throws IOException, ParseException
  {
    repIDStack.push (((IDLID)repIDStack.peek ()).clone ());
    // Note: The 'actual' repository ID will be calculated at the end of
    // the parsing phase, since it is based on the entire contents of the
    // declaration, and needs to have all forward references resolved:
    ValueEntry entry = stFactory.valueBoxEntry (module, (IDLID)repIDStack.peek ());
    entry.sourceFile (scanner.fileEntry ());
    entry.name (name);
    // comment must immediately precede "value" keyword
    entry.comment (tokenHistory.lookBack (2).comment);
    // <f46082.40> Value boxes may not be forwarded.
    // If this value has been forward declared, there are probably
    // other values which derive from a ForwardValueEntry.
    // Replace those ForwardValueEntry's with this ValueEntry:
    //if (!ForwardValueEntry.replaceForwardDecl (entry))
    //   ParseException.badAbstract (scanner, entry.fullName());
    SymtabEntry valueForward = (SymtabEntry)Parser.symbolTable.get (entry.fullName ());
    if (valueForward != null && valueForward instanceof ForwardEntry)
      ParseException.forwardedValueBox (scanner, entry.fullName ());
    pigeonhole (module, entry);
    ((IDLID)repIDStack.peek ()).appendToName (name);
    currentModule = entry;
    TypedefEntry typedefEntry = stFactory.typedefEntry (entry, (IDLID)repIDStack.peek ());
    typedefEntry.sourceFile (scanner.fileEntry ());
    typedefEntry.comment (token.comment);
    // <d50237> Workaround to place typedefEntry in the _contained vector of
    // this value box entry ONLY when <type_spec> is a constructed type declared
    // at this point (i.e., not an identifier that resolves to a constructed
    // type), so that emitters may generate bindings for it. <daz>
    boolean isConstTypeSpec =
        token.type == Token.Struct || token.type == Token.Union || token.type == Token.Enum;
    // <d50618> Make typedefEntry anonymous.  If this line is removed, the
    // entry will be named incorrectly.
    typedefEntry.name ("");
    typedefEntry.type (typeSpec (typedefEntry));
    // <d59067> Value boxes cannot be nested.
    if (typedefEntry.type () instanceof ValueBoxEntry)
      ParseException.nestedValueBox (scanner);
    //typedefEntry.name ("");
    entry.addStateElement (new InterfaceState (InterfaceState.Public, typedefEntry), scanner);
    if (isConstTypeSpec)
      entry.addContained (typedefEntry);
    currentModule = module;
    repIDStack.pop ();
  } // valueBox

  /**
   *
   **/
  private void valueForwardDcl (ModuleEntry module, String name, boolean isAbstract)
      throws IOException, ParseException
  {
    ForwardValueEntry entry = stFactory.forwardValueEntry (module, (IDLID)repIDStack.peek ());
    entry.sourceFile (scanner.fileEntry ());
    entry.name (name);
    entry.setInterfaceType(isAbstract ? InterfaceType.ABSTRACT : InterfaceType.NORMAL );
    // Comment must immediately precede "[abstract] value" keyword[s]
    entry.comment (tokenHistory.lookBack (isAbstract? 3 : 2).comment);
    pigeonhole (module, entry);
  } // valueForwardDcl

  private void nativeDcl (SymtabEntry entry) throws IOException, ParseException
  {
    match (Token.Native);
    NativeEntry nativeEntry = stFactory.nativeEntry (entry, (IDLID)repIDStack.peek ());
    nativeEntry.sourceFile (scanner.fileEntry ());
    // Comment must immediately precede "native" keyword
    nativeEntry.comment (tokenHistory.lookBack (1).comment);
    nativeEntry.name (token.name);
    match (Token.Identifier);
    pigeonhole (entry, nativeEntry);
  } // nativeDcl
  /**
   *
   **/
  private void constDcl (SymtabEntry entry) throws IOException, ParseException
  {
    match (Token.Const);
    ConstEntry constEntry = stFactory.constEntry (entry, (IDLID)repIDStack.peek ());
    constEntry.sourceFile (scanner.fileEntry ());
    // Comment must immediately precede "const" keyword
    constEntry.comment (tokenHistory.lookBack (1).comment);
    constType (constEntry);
    constEntry.name (token.name);
    match (Token.Identifier);
    match (Token.Equal);
    constEntry.value (constExp (constEntry));
    verifyConstType (constEntry.value (), typeOf (constEntry.type ()));
    pigeonhole (entry, constEntry);
  } // constDcl

  /**
   *
   **/
  private void constType (SymtabEntry entry) throws IOException, ParseException
  {
    switch (token.type)
    {
      case Token.Octet:
        entry.type( octetType()) ;
        break ;
      case Token.Long:
      case Token.Short:
      case Token.Unsigned:
        entry.type (integerType (entry));
        break;
      case Token.Char:
      case Token.Wchar:
        entry.type (charType ());
        break;
      case Token.Boolean:
        entry.type (booleanType ());
        break;
      case Token.Float:
      case Token.Double:
        entry.type (floatingPtType ());
        break;
      case Token.String:
      case Token.Wstring:
        entry.type (stringType (entry));
        break;
      case Token.Identifier:
      case Token.DoubleColon:
        entry.type (scopedName (entry.container (), stFactory.primitiveEntry ()));
        if (hasArrayInfo (entry.type ()))
          ParseException.illegalArray (scanner, "const");
        SymtabEntry entryType = typeOf (entry.type ());
        if (!((entryType instanceof PrimitiveEntry) || (entryType instanceof StringEntry)))
        {
          ParseException.wrongType(scanner, entry.fullName (), "primitive or string", entryName (entry.type ()));
          entry.type (qualifiedEntry ("long"));
        }
        else if (entryType instanceof PrimitiveEntry)
        {
          String any = overrideName ("any");
          if (entryType.name().equals (any))
          {
            ParseException.wrongType (scanner, entry.fullName (), "primitive or string (except " + any + ')', any);
            entry.type (qualifiedEntry ("long"));
          }
        }
        break;
      default:
        throw ParseException.syntaxError (scanner, new int [] {
                      Token.Long,   Token.Short,   Token.Unsigned, Token.Char,
                      Token.Wchar,  Token.Boolean, Token.Float,    Token.Double,
                      Token.String, Token.Wstring, Token.Identifier,
                      Token.DoubleColon }, token.type);
    }
  } // constType

  /**
   *
   **/
  private boolean hasArrayInfo (SymtabEntry entry)
  {
    while (entry instanceof TypedefEntry)
    {
      if (((TypedefEntry)entry).arrayInfo ().size () != 0)
        return true;
      entry = entry.type ();
    }
  return false;
  } // hasArrayInfo

  /**
   *
   **/
  public static String overrideName (String string)
  {
    String name = (String)overrideNames.get (string);
    return (name == null) ? string : name;
  } // overrideName

  // If entry is boolean, expression value must be boolean
  // If entry is float/double, expression value must be float/double
  // If entry is integral, expression value must be integral
  // If entry is string, expression value must be string

  /**
   *
   **/
  private void verifyConstType (Expression e, SymtabEntry t)
  {
    Object value = e.value ();
    if (value instanceof BigInteger)
      verifyIntegral ((Number)value, t);
    else if (value instanceof String)
      verifyString (e, t);
    else if (value instanceof Boolean)
      verifyBoolean (t);
    else if (value instanceof Character)
      verifyCharacter (e, t);
    else if (value instanceof Float || value instanceof Double)
      verifyFloat((Number)value, t);
    else if (value instanceof ConstEntry)
      verifyConstType (((ConstEntry)value).value (), t);
    else
      ParseException.wrongExprType (scanner, t.fullName (),
          (value == null) ? "" : value.toString ());
  } // verifyConstType

  private static final int MAX_SHORT  = 32767;
  private static final int MIN_SHORT  = -32768;
  private static final int MAX_USHORT = 65535;

  /**
   *
   **/
  private void verifyIntegral (Number n, SymtabEntry t)
  {
    boolean outOfRange = false;
    //KEEP: Useful for debugging com.sun.tools.corba.se.idl.constExpr package
    //System.out.println ("verifyIntegral, n = " + n.toString ());

    if (t == qualifiedEntry( "octet" )) {
        if ((n.longValue() > 255) || (n.longValue() < 0))
            outOfRange = true ;
    } else if (t == qualifiedEntry ("long")) {
        if (n.longValue () > Integer.MAX_VALUE || n.longValue() < Integer.MIN_VALUE)
            outOfRange = true;
    } else if (t == qualifiedEntry ("short")) {
        if (n.intValue () > Short.MAX_VALUE || n.intValue () < Short.MIN_VALUE)
            outOfRange = true;
    } else if (t == qualifiedEntry ("unsigned long")) {
        if (n.longValue () > (long)Integer.MAX_VALUE*2+1 || n.longValue() < 0)
            outOfRange = true;
    } else if (t == qualifiedEntry ("unsigned short")) {
        if (n.intValue () > (int) Short.MAX_VALUE*2+1 || n.intValue () < 0)
            outOfRange = true;
    } else if (t == qualifiedEntry ("long long")) {
        // BigInteger required because value being compared may exceed
        // java.lang.Long.MAX_VALUE/MIN_VALUE:
        BigInteger llMax = BigInteger.valueOf (Long.MAX_VALUE);
        BigInteger llMin = BigInteger.valueOf (Long.MIN_VALUE);
        if (((BigInteger)n).compareTo (llMax) > 0 ||
            ((BigInteger)n).compareTo (llMin) < 0)
            outOfRange = true;
    } else if (t == qualifiedEntry ("unsigned long long")) {
        BigInteger ullMax = BigInteger.valueOf (Long.MAX_VALUE).
            multiply (BigInteger.valueOf (2)).
            add (BigInteger.valueOf (1));
        BigInteger ullMin = BigInteger.valueOf (0);
        if (((BigInteger)n).compareTo (ullMax) > 0 ||
            ((BigInteger)n).compareTo (ullMin) < 0)
            outOfRange = true;
    } else {
        String got = null;
        // THIS MUST BE CHANGED; BIGINTEGER IS ALWAYS THE CONTAINER
        /*
        if (n instanceof Short)
          got = "short";
        else if (n instanceof Integer)
          got = "long";
        else
          got = "long long";
        */
        got = "long";
        ParseException.wrongExprType (scanner, t.fullName (), got);
    }

    if (outOfRange)
        ParseException.outOfRange (scanner, n.toString (), t.fullName ());
  } // verifyIntegral

  /**
   *
   **/
  private void verifyString (Expression e, SymtabEntry t)
  {
    String string = (String)(e.value()) ;
    if (!(t instanceof StringEntry)) {
        ParseException.wrongExprType (scanner, t.fullName (), e.type() );
    } else if (((StringEntry)t).maxSize () != null) {
        Expression maxExp = ((StringEntry)t).maxSize ();
        try {
            Number max = (Number)maxExp.value ();
            if (string.length () > max.intValue ())
                ParseException.stringTooLong (scanner, string, max.toString ());
        } catch (Exception exception) {
            // If the above statement is not valid and throws an
            // exception, then an error occurred and was reported
            // earlier.  Move on.
        }
    }

    if (!e.type().equals( t.name())) {
        // cannot mix strings and wide strings
        ParseException.wrongExprType (scanner, t.name(), e.type() ) ;
    }
  } // verifyString

  /**
   *
   **/
  private void verifyBoolean (SymtabEntry t)
  {
    if (!t.name ().equals (overrideName ("boolean")))
      ParseException.wrongExprType(scanner, t.name(), "boolean");
  } // verifyBoolean

  /**
   *
   **/
  private void verifyCharacter (Expression e, SymtabEntry t)
  {
    // Bug fix 4382578:  Can't compile a wchar literal.
    // Allow a Character to be either a char or a wchar.
    if (!t.name ().equals (overrideName ("char")) &&
        !t.name ().equals (overrideName ("wchar")) ||
        !t.name().equals(e.type()) )
        ParseException.wrongExprType (scanner, t.fullName(), e.type() ) ;
  } // verifyCharacter

  /**
   *
   **/
  private void verifyFloat (Number f, SymtabEntry t)
  {
    // <d52042> Added range checking for floats.
    //if (!(t.name ().equals (overrideName ("float")) ||
    //    t.name ().equals (overrideName ("double"))))
    //  ParseException.wrongExprType (scanner,
    //      t.fullName (), (f instanceof Float) ? "float" : "double");
    //KEEP: Useful for debugging com.sun.tools.corba.se.idl.constExpr package
    //System.out.println ("verifyFloat, f = " + f.toString ());
    boolean outOfRange = false;
    if (t.name ().equals (overrideName ("float")))
    {
      double absVal = (f.doubleValue () < 0.0) ?
          f.doubleValue () * -1.0 : f.doubleValue ();
      if ((absVal != 0.0) &&
          (absVal > Float.MAX_VALUE || absVal < Float.MIN_VALUE))
        outOfRange = true;
    }
    else if (t.name ().equals (overrideName ("double")))
    {
      // Cannot check range of double until BigDecimal is the basis
      // of all floating-point types.  Currently, it is Double.  The
      // parser will fail when instantiating a Double with an exception.
    }
    else
    {
      ParseException.wrongExprType (scanner, t.fullName (),
        (f instanceof Float) ? "float" : "double");
    }
    if (outOfRange)
      ParseException.outOfRange (scanner, f.toString (), t.fullName ());
  } // verifyFloat

  /**
   *
   **/
  Expression constExp (SymtabEntry entry) throws IOException, ParseException
  {
    // Parse the expression.
    Expression expr = orExpr (null, entry);

    // Set its target type.
    if (expr.type() == null)
      expr.type (entry.typeName ());
    // Compute its value and <d53042> coerce it to the target type.
    try
    {
      expr.evaluate ();

      // <d54042> Coerces integral value to Double if an integer literal
      // was used to initialize a floating-point constant expression.
      if (expr instanceof Terminal &&
          expr.value () instanceof BigInteger &&
          (overrideName (expr.type ()).equals ("float") ||
               overrideName (expr.type ()).indexOf ("double") >= 0))
      {
        expr.value (new Double (((BigInteger)expr.value ()).doubleValue ()));
      }
    }
    catch (EvaluationException exception)
    {
      ParseException.evaluationError (scanner, exception.toString ());
    }
    return expr;
  } // constExp

  /**
   *
   **/
  private Expression orExpr (Expression e, SymtabEntry entry) throws IOException, ParseException
  {
    if (e == null)
      e = xorExpr (null, entry);
    else
    {
      BinaryExpr b = (BinaryExpr)e;
      b.right (xorExpr (null, entry));
      e.rep (e.rep () + b.right ().rep ());
    }
    if (token.equals (Token.Bar))
    {
      match (token.type);
      Or or = exprFactory.or (e, null);
      or.type (entry.typeName ());
      or.rep (e.rep () + " | ");
      return orExpr (or, entry);
    }
    return e;
  } // orExpr

  /**
   *
   **/
  private Expression xorExpr (Expression e, SymtabEntry entry) throws IOException, ParseException
  {
    if (e == null)
      e = andExpr (null, entry);
    else
    {
      BinaryExpr b = (BinaryExpr)e;
      b.right (andExpr (null, entry));
      e.rep (e.rep () + b.right ().rep ());
    }
    if (token.equals (Token.Carat))
    {
      match (token.type);
      Xor xor = exprFactory.xor (e, null);
      xor.rep (e.rep () + " ^ ");
      xor.type (entry.typeName ());
      return xorExpr (xor, entry);
    }
    return e;
  } // xorExpr

  /**
   *
   **/
  private Expression andExpr (Expression e, SymtabEntry entry) throws IOException, ParseException
  {
    if (e == null)
      e = shiftExpr (null, entry);
    else
    {
      BinaryExpr b = (BinaryExpr)e;
      b.right (shiftExpr (null, entry));
      e.rep (e.rep () + b.right ().rep ());
    }
    if (token.equals (Token.Ampersand))
    {
      match (token.type);
      And and = exprFactory.and (e, null);
      and.rep(e.rep () + " & ");
      and.type (entry.typeName ());
      return andExpr (and, entry);
    }
    return e;
  } // andExpr

  /**
   *
   **/
  private Expression shiftExpr (Expression e, SymtabEntry entry) throws IOException, ParseException
  {
    if (e == null)
      e = addExpr (null, entry);
    else
    {
      BinaryExpr b = (BinaryExpr)e;
      b.right (addExpr (null, entry));
      e.rep (e.rep () + b.right ().rep ());
    }
    if (token.equals (Token.ShiftLeft))
    {
      match (token.type);
      ShiftLeft sl = exprFactory.shiftLeft (e, null);
      sl.type (entry.typeName ());
      sl.rep (e.rep () + " << ");
      return shiftExpr (sl, entry);
    }
    if (token.equals (Token.ShiftRight))
    {
      match (token.type);
      ShiftRight sr = exprFactory.shiftRight (e, null);
      sr.type (entry.typeName ());
      sr.rep (e.rep () + " >> ");
      return shiftExpr (sr, entry);
    }
    return e;
  } // shiftExpr

  /**
   *
   **/
  private Expression addExpr (Expression e, SymtabEntry entry) throws IOException, ParseException
  {
    if (e == null)
      e = multExpr (null, entry);
    else
    {
      BinaryExpr b = (BinaryExpr)e;
      b.right (multExpr (null, entry));
      e.rep (e.rep () + b.right ().rep ());
    }
    if (token.equals (Token.Plus))
    {
      match (token.type);
      Plus p = exprFactory.plus (e, null);
      p.type (entry.typeName ());
      p.rep (e.rep () + " + ");
      return addExpr (p, entry);
    }
    if (token.equals (Token.Minus))
    {
      match (token.type);
      Minus m = exprFactory.minus (e, null);
      m.type (entry.typeName ());
      m.rep (e.rep () + " - ");
      return addExpr (m, entry);
    }
    return e;
  } // addExpr

  /**
   *
   **/
  private Expression multExpr (Expression e, SymtabEntry entry) throws IOException, ParseException
  {
    if (e == null)
    e = unaryExpr (entry);
    else
    {
      BinaryExpr b = (BinaryExpr)e;
      b.right (unaryExpr (entry));
      e.rep (e.rep () + b.right ().rep ());
    }
    if (token.equals (Token.Star))
    {
      match (token.type);
      Times t = exprFactory.times (e, null);
      t.type (entry.typeName ());
      t.rep (e.rep () + " * ");
      return multExpr (t, entry);
    }
    if (token.equals (Token.Slash))
    {
      match (token.type);
      Divide d = exprFactory.divide (e, null);
      d.type (entry.typeName ());
      d.rep (e.rep () + " / ");
      return multExpr (d, entry);
    }
    if (token.equals (Token.Percent))
    {
      match (token.type);
      Modulo m = exprFactory.modulo (e, null);
      m.type (entry.typeName ());
      m.rep (e.rep () + " % ");
      return multExpr (m, entry);
    }
    return e;
  } // multExpr

  /**
   *
   **/
  private Expression unaryExpr (SymtabEntry entry) throws IOException, ParseException
  {
    if (token.equals (Token.Plus))
    {
      match (token.type);
      Expression e   = primaryExpr (entry);
      Positive   pos = exprFactory.positive (e);
      pos.type (entry.typeName());
      pos.rep ('+' + e.rep());
      return pos;
    }
    if (token.equals (Token.Minus))
    {
      match (token.type);
      Expression e   = primaryExpr (entry);
      Negative   neg = exprFactory.negative (e);
      neg.type (entry.typeName());
      neg.rep ('-' + e.rep());
      return neg;
    }
    if (token.equals (Token.Tilde))
    {
      match (token.type);
      Expression e   = primaryExpr (entry);
      Not        not = exprFactory.not (e);
      not.type (entry.typeName());
      not.rep ('~' + e.rep());
      return not;
    }
    return primaryExpr (entry);
  } // unaryExpr

  /**
   *
   **/
  private Expression primaryExpr (SymtabEntry entry)
      throws IOException, ParseException
  {
    Expression primary = null;
    if (parsingConditionalExpr)
    {
      prep.token = token; // Give current token to preprocessor
      primary    = prep.primaryExpr (entry);
      token      = prep.token; // Get the current token from preprocessor
    }
    else
      switch (token.type)
      {
        case Token.Identifier:
        case Token.DoubleColon:
          ConstEntry expectedC = stFactory.constEntry ();
          expectedC.value (exprFactory.terminal ("1", BigInteger.valueOf (1)));
          SymtabEntry ref = scopedName (entry.container (), expectedC);
          if (!(ref instanceof ConstEntry))
          {
            ParseException.invalidConst (scanner, ref.fullName ());
            // An error occurred.  Just give it some bogus value. <daz>
            //primary = exprFactory.terminal ("1", new Long (1));
            primary = exprFactory.terminal ("1", BigInteger.valueOf (1));
          }
          else
            primary = exprFactory.terminal ((ConstEntry)ref);
          break;
        case Token.BooleanLiteral:
        case Token.CharacterLiteral:
        case Token.IntegerLiteral:
        case Token.FloatingPointLiteral:
        case Token.StringLiteral:
          primary = literal (entry);
          break;
        case Token.LeftParen:
          match (Token.LeftParen);
          primary = constExp (entry);
          match (Token.RightParen);
          primary.rep ('(' + primary.rep () + ')');
          break;
        default:
          throw ParseException.syntaxError (scanner, new int [] {
              Token.Identifier, Token.DoubleColon, Token.Literal, Token.LeftParen},
              token.type);
      }
    return primary;
  } // primaryExpr

  /**
   *
   **/
  Expression literal (SymtabEntry entry) throws IOException, ParseException
  {
    String     string  = token.name;
    Expression literal = null;
    switch (token.type)
    {
      case Token.IntegerLiteral:
        match (Token.IntegerLiteral);
        try
        {
          literal = exprFactory.terminal (string, parseString (string));
          literal.type (entry.typeName ());
        }
        catch (NumberFormatException exception)
        {
          ParseException.notANumber (scanner, string);
          literal = exprFactory.terminal ("0", BigInteger.valueOf (0));
        }
        break;
      case Token.CharacterLiteral:
        boolean isWide = token.isWide();
        match (Token.CharacterLiteral);
        literal = exprFactory.terminal ("'" + string.substring (1) + "'",
            new Character (string.charAt (0)), isWide );
        break;
      case Token.FloatingPointLiteral:
        match (Token.FloatingPointLiteral);
        try
        {
          literal = exprFactory.terminal (string, new Double (string));
          literal.type (entry.typeName ());
        }
        catch (NumberFormatException e)
        {
          ParseException.notANumber (scanner, string);
        }
        break;
      case Token.BooleanLiteral:
        literal = booleanLiteral ();
        break;
      case Token.StringLiteral:
        literal = stringLiteral ();
        break;
      default:
        throw ParseException.syntaxError (scanner, Token.Literal,token.type);
    }
    return literal;
  } // literal

  /**
   *
   **/
  private BigInteger parseString (String string) throws NumberFormatException
  {
    int radix = 10;
    if (string.length() > 1)
      if (string.charAt (0) == '0')
        if (string.charAt (1) == 'x' || string.charAt (1) == 'X')
        {
          string = string.substring (2);
          radix = 16;
        }
        else
          radix = 8;
    return new BigInteger (string, radix);
  } // parseString

  /**
   *
   **/
  private Terminal booleanLiteral () throws IOException, ParseException
  {
    Boolean bool = null;
    if (token.name.equals ("TRUE"))
      bool = new Boolean (true);
    else if (token.name.equals ("FALSE"))
      bool = new Boolean (false);
    else
    {
      ParseException.invalidConst (scanner, token.name);
      bool = new Boolean (false);
    }
    String name = token.name;
    match (Token.BooleanLiteral);
    return exprFactory.terminal (name, bool);
  } // booleanLiteral

  /**
   *
   **/
  private Expression stringLiteral () throws IOException, ParseException
  {
    // If string literals appear together, concatenate them.  Ie:
    // "Twas " "brillig " "and " "the " "slithy " "toves"
    // becomes
    // "Twas brillig and the slithy toves"
    boolean isWide = token.isWide() ;
    String literal = "";
    do
    {
      literal += token.name;
      match (Token.StringLiteral);
    } while (token.equals (Token.StringLiteral));
    Expression stringExpr = exprFactory.terminal (literal, isWide );
    stringExpr.rep ('"' + literal + '"');
    return stringExpr;
  } // stringLiteral

  /**
   *
   **/
  private Expression positiveIntConst (SymtabEntry entry) throws IOException, ParseException
  {
    Expression e     = constExp (entry);
    Object     value = e.value ();
    while (value instanceof ConstEntry)
      value = ((ConstEntry)value).value ().value ();
    if (!(value instanceof Number) || value instanceof Float || value instanceof Double)
    {
      ParseException.notPositiveInt (scanner, e.rep ());
      //e = exprFactory.terminal ("1", new Long (1));
      e = exprFactory.terminal ("1", BigInteger.valueOf (1));
    }
    //else if (((Number)value).longValue () <= 0) {
    //   ParseException.notPositiveInt (scanner, value.toString ());
    //   e = exprFactory.terminal ("1", new Long (1)); }
    else if (((BigInteger)value).compareTo (BigInteger.valueOf (0)) <= 0)
    {
      ParseException.notPositiveInt (scanner, value.toString ());
      //e = exprFactory.terminal ("1", new Long (1)); <daz>
      e = exprFactory.terminal ("1", BigInteger.valueOf (1));
    }
    return e;
  } // positiveIntConst

  /**
   *
   **/
  private SymtabEntry typeDcl (SymtabEntry entry) throws IOException, ParseException
  {
    switch (token.type)
    {
      case Token.Typedef:
        match (Token.Typedef);
        return typeDeclarator (entry);
      case Token.Struct:
        return structType (entry);
      case Token.Union:
        return unionType (entry);
      case Token.Enum:
        return enumType (entry);
      default:
        throw ParseException.syntaxError (scanner, new int [] {
            Token.Typedef, Token.Struct, Token.Union, Token.Enum}, token.type);
    }
  } // typeDcl

  /**
   *
   **/
  private TypedefEntry typeDeclarator (SymtabEntry entry) throws IOException, ParseException
  {
    TypedefEntry typedefEntry = stFactory.typedefEntry (entry, (IDLID)repIDStack.peek ());
    typedefEntry.sourceFile (scanner.fileEntry ());
    // Comment must immediately precede "typedef" keyword
    typedefEntry.comment (tokenHistory.lookBack (1).comment);
    typedefEntry.type (typeSpec (entry));
    Vector typedefList = new Vector ();
    declarators (typedefEntry, typedefList);
    for (Enumeration e = typedefList.elements(); e.hasMoreElements();)
      pigeonhole (entry, (SymtabEntry)e.nextElement ());
    return typedefEntry;
  } // typeDeclarator

  /**
   *
   **/
  private SymtabEntry typeSpec (SymtabEntry entry) throws IOException, ParseException
  {
    return ((token.type == Token.Struct) ||
            (token.type == Token.Union)  ||
            (token.type == Token.Enum))
        ? constrTypeSpec (entry)
        : simpleTypeSpec (entry, true);
  } // typeSpec

  /**
   *
   **/
  private SymtabEntry simpleTypeSpec (SymtabEntry entry,
    boolean mustBeReferencable ) throws IOException, ParseException
  {
    // <f46082.40>
    //if ((token.type == Token.Identifier)  ||
    //    (token.type == Token.DoubleColon) ||
    //    (token.type == Token.Object)) {
    if ((token.type == Token.Identifier)  ||
        (token.type == Token.DoubleColon) ||
        (token.type == Token.Object)      ||
        (token.type == Token.ValueBase))
    {
      SymtabEntry container = ((entry instanceof InterfaceEntry) ||
                               (entry instanceof ModuleEntry)    ||
                               (entry instanceof StructEntry)    ||
                               (entry instanceof UnionEntry))
          ? entry
          : entry.container ();
      return scopedName (container, stFactory.primitiveEntry (),
        mustBeReferencable);
    }
    return ((token.type == Token.Sequence) ||
            (token.type == Token.String)   ||
            (token.type == Token.Wstring))
        ? templateTypeSpec (entry)
        : baseTypeSpec (entry);
  } // simpleTypeSpec

  /**
   *
   **/
  private SymtabEntry baseTypeSpec (SymtabEntry entry) throws IOException, ParseException
  {
    switch (token.type)
    {
      case Token.Float:
      case Token.Double:
        return floatingPtType ();
      case Token.Long:
      case Token.Short:
     case Token.Unsigned:
        return integerType (entry);
      case Token.Char:
      case Token.Wchar:
        return charType ();
      case Token.Boolean:
        return booleanType ();
     case Token.Octet:
        return octetType ();
      case Token.Any:
        return anyType ();
      // NOTE: Object and ValueBase are <base_type_spec>s, but both
      // are processed at simpleTypeSpec(), not here.  parmTypeSpec()
      // directly checks for these types.  Could make baseTypeSpec() do
      // the same
      default:
        throw ParseException.syntaxError (scanner, new int [] {
            Token.Float,    Token.Double, Token.Long,  Token.Short,
            Token.Unsigned, Token.Char,   Token.Wchar, Token.Boolean,
            Token.Octet,    Token.Any}, token.type);
    }
  } // baseTypeSpec

  /**
   *
   **/
  private SymtabEntry templateTypeSpec (SymtabEntry entry) throws IOException, ParseException
  {
    switch (token.type)
    {
      case Token.Sequence:
        return sequenceType (entry);
      case Token.String:
      case Token.Wstring:
        return stringType (entry);
    }
    throw ParseException.syntaxError (scanner, new int [] {Token.Sequence, Token.String, Token.Wstring}, token.type);
  } // templateTypeSpec

  /**
   *
   **/
  private SymtabEntry constrTypeSpec (SymtabEntry entry) throws IOException, ParseException
  {
    switch (token.type)
    {
      case Token.Struct:
        return structType (entry);
      case Token.Union:
        return unionType (entry);
      case Token.Enum:
        return enumType (entry);
    }
    throw ParseException.syntaxError (scanner, new int [] {Token.Struct, Token.Union, Token.Enum}, token.type);
  } // constrTypeSpec

  /**
   *
   **/
  private void declarators (TypedefEntry entry, Vector list) throws IOException, ParseException
  {
    for (; ; match (Token.Comma))
    {
      TypedefEntry newEntry = (TypedefEntry)entry.clone ();
      declarator (newEntry);
      if (isntInList (list, newEntry.name ()))
        list.addElement (newEntry);
      if (token.type != Token.Comma)
        break;
    }
  } // declarators

  /**
   *
   **/
  private void declarator (TypedefEntry entry) throws IOException, ParseException
  {
    entry.name (token.name);
    // If the declarator is commented then override the comment cloned from the parent
    // entry. <08aug1997daz>
    if (!token.comment.text ().equals (""))
      entry.comment (token.comment);
    match (Token.Identifier);
    while (token.type == Token.LeftBracket)
      fixedArraySize (entry);
  } // declarator

  /**
   *
   **/
  private PrimitiveEntry floatingPtType () throws IOException, ParseException
  {
    String name = "double";
    if (token.type == Token.Float)
    {
      match (Token.Float);
      name = "float";
    }
    else if (token.type == Token.Double)
      match (Token.Double);
    else
    {
      int [] expected = {Token.Float, Token.Double};
      ParseException.syntaxError (scanner, new int [] {Token.Float, Token.Double }, token.type);
    }
    PrimitiveEntry ret = null;
    try
    {
      ret = (PrimitiveEntry)qualifiedEntry (name);
    }
    catch (ClassCastException exception)
    {
      ParseException.undeclaredType (scanner, name);
    }
    return ret;
  } // floatingPtType

  /**
   *
   **/
  private PrimitiveEntry integerType (SymtabEntry entry) throws IOException, ParseException
  {
    String name = "";
    if (token.type == Token.Unsigned)
    {
      match (Token.Unsigned);
      name = "unsigned ";
    }
    name += signedInt();
    PrimitiveEntry ret = null;
    try
    {
      ret = (PrimitiveEntry) qualifiedEntry (name);
    }
    catch (ClassCastException exception)
    {
      ParseException.undeclaredType (scanner, name);
    }
    return ret;
  } // integerType

  /**
   *
   **/
  private String signedInt () throws IOException, ParseException
  {
    String ret = "long";
    if (token.type == Token.Long)
    {
      match (Token.Long);
      // <signedInt'> ::= "long" | e
      if (token.type == Token.Long)
      {
        ret = "long long";
        match (Token.Long);
      }
    }
    else if (token.type == Token.Short)
    {
      ret = "short";
      match (Token.Short);
    }
    else
      ParseException.syntaxError (scanner, new int [] {Token.Long, Token.Short}, token.type);
    return ret;
  } // signedInt

  /**
   *
   **/
  private PrimitiveEntry charType () throws IOException, ParseException
  {
    String tokenName;
    if (token.type == Token.Char)
    {
      match (Token.Char);
      tokenName = "char";
    }
    else
    {
      match (Token.Wchar);
      tokenName = "wchar";
    }
    PrimitiveEntry ret = null;
    try
    {
      ret = (PrimitiveEntry) qualifiedEntry (tokenName);
    }
    catch (ClassCastException exception)
    {
      ParseException.undeclaredType (scanner, overrideName (tokenName));
    }
    return ret;
  } // charType

  /**
   *
   **/
  private PrimitiveEntry booleanType () throws IOException, ParseException
  {
    PrimitiveEntry ret = null;
    match (Token.Boolean);
    try
    {
      ret = (PrimitiveEntry) qualifiedEntry ("boolean");
    }
    catch (ClassCastException exception)
    {
      ParseException.undeclaredType (scanner, overrideName ("boolean"));
    }
    return ret;
  } // booleanType

  /**
   *
   **/
  private PrimitiveEntry octetType () throws IOException, ParseException
  {
    PrimitiveEntry ret = null;
    match (Token.Octet);
    try
    {
      ret = (PrimitiveEntry) qualifiedEntry ("octet");
    }
    catch (ClassCastException exception)
    {
      ParseException.undeclaredType (scanner, overrideName ("octet"));
    }
    return ret;
  } // octetType

  /**
   *
   **/
  private SymtabEntry anyType () throws IOException, ParseException
  {
    match (Token.Any);
    try
    {
      return qualifiedEntry ("any");
    }
    catch (ClassCastException exception)
    {
      ParseException.undeclaredType (scanner, overrideName ("any"));
      return null;
    }
  } // anyType

  /**
   *
   **/
  private StructEntry structType (SymtabEntry entry) throws IOException,
    ParseException
  {
    match (Token.Struct);
    String name = token.name;
    match (Token.Identifier);
    StructEntry structEntry = null ;

    if (token.type == Token.LeftBrace) {
      repIDStack.push(((IDLID)repIDStack.peek ()).clone ()) ;
      structEntry = makeStructEntry( name, entry, false ) ;
      ((IDLID)repIDStack.peek ()).appendToName (name);
      prep.openScope (structEntry);
      match (Token.LeftBrace) ;
      member (structEntry) ;
      memberList2 (structEntry) ;
      prep.closeScope (structEntry);
      match (Token.RightBrace) ;
      repIDStack.pop() ;
    } else if (token.equals( Token.Semicolon )) {
      structEntry = makeStructEntry( name, entry, true ) ;
    } else {
      throw ParseException.syntaxError (scanner,
        new int[] { Token.Semicolon, Token.LeftBrace }, token.type);
    }
    return structEntry;
  } // structType

  private StructEntry makeStructEntry( String name, SymtabEntry entry,
    boolean isForward )
  {
    StructEntry structEntry = stFactory.structEntry (entry,
      (IDLID)repIDStack.peek () );
    structEntry.isReferencable( !isForward ) ;
    structEntry.sourceFile (scanner.fileEntry ());
    structEntry.name (name);
    // Comment must immediately preceed "struct" keyword
    structEntry.comment (tokenHistory.lookBack (1).comment);
    pigeonhole( entry, structEntry ) ;
    return structEntry ;
  }

  /**
   *
   **/
  private void memberList2 (StructEntry entry) throws IOException
  {
    while (token.type != Token.RightBrace)
      member (entry);
  } // memberList2

  /**
   *
   **/
  private void member (StructEntry entry) throws IOException
  {
    TypedefEntry newEntry = stFactory.typedefEntry(entry, (IDLID)repIDStack.peek());
    newEntry.sourceFile (scanner.fileEntry ());
    // comment must immediately precede <type_spec> lexeme
    newEntry.comment (token.comment);
    try
    {
      newEntry.type (typeSpec (entry));
      if (newEntry.type () == entry)
        throw ParseException.recursive (scanner, entry.fullName (),
            (token.name == null) ? "" : token.name);
      // <d46094> Exception cannot appear within a struct, union, or exception
      if (typeOf (newEntry) instanceof ExceptionEntry)
        throw ParseException.illegalException (scanner, entryName (entry));
      declarators (newEntry, entry.members ());
      match (Token.Semicolon);
    }
    catch (ParseException exception)
    {
      skipToSemicolon ();
    }
  } // member

  /**
   *
   **/
  private final boolean isConstTypeSpec (Token t)
  {
    return (t.type == Token.Struct || t.type == Token.Union || t.type == Token.Enum);
  } // isConstTypeSpec

  /**
   *
   **/
  private UnionEntry unionType (SymtabEntry entry) throws IOException, ParseException
  {
    match (Token.Union) ;
    String name = token.name ;
    match (Token.Identifier) ;
    UnionEntry unionEntry = null ;

    if (token.type == Token.Switch) {
      repIDStack.push (((IDLID)repIDStack.peek ()).clone ());
      unionEntry = makeUnionEntry( name, entry, false ) ;
      ((IDLID)repIDStack.peek ()).appendToName (name);
      match (Token.Switch);
      match (Token.LeftParen);
      unionEntry.type (switchTypeSpec (unionEntry));
      match (Token.RightParen);
      prep.openScope (unionEntry);
      match (Token.LeftBrace);
      switchBody (unionEntry);
      verifyUnion (unionEntry);
      prep.closeScope (unionEntry);
      match (Token.RightBrace);
      repIDStack.pop ();
    } else if (token.equals( Token.Semicolon )) {
      unionEntry = makeUnionEntry( name, entry, true ) ;
    } else {
      throw ParseException.syntaxError (scanner,
        new int[] { Token.Semicolon, Token.Switch }, token.type);
    }

    return unionEntry ;
  } // unionType

  private UnionEntry makeUnionEntry( String name, SymtabEntry entry,
    boolean isForward )
  {
    UnionEntry unionEntry = stFactory.unionEntry (entry,
      (IDLID)repIDStack.peek () );
    unionEntry.isReferencable( !isForward ) ;
    unionEntry.sourceFile (scanner.fileEntry ());
    unionEntry.name (name);
    // Comment must immediately preceed "union" keyword
    unionEntry.comment (tokenHistory.lookBack (1).comment);
    pigeonhole( entry, unionEntry ) ;
    return unionEntry ;
  }

  /**
   *
   **/
  private void verifyUnion (UnionEntry u)
  {
    if (u.typeName ().equals (overrideName ("boolean")))
    {
      if (caseCount (u) > 2)
        ParseException.noDefault (scanner);
    }
    else if (u.type () instanceof EnumEntry)
    {
      if (caseCount (u) > ((EnumEntry)u.type ()).elements ().size ())
        ParseException.noDefault (scanner);
    }
  } // verifyUnion

  /**
   *
   **/
  private long caseCount (UnionEntry u)
  {
    long cases = 0;
    Enumeration branches = u.branches ().elements ();
    while (branches.hasMoreElements ())
    {
      UnionBranch branch = (UnionBranch)branches.nextElement ();
      cases += branch.labels.size ();
      if (branch.isDefault)
        ++cases;
    }
    return cases;
  } // caseCount

  /**
   *
   **/
  private SymtabEntry switchTypeSpec (UnionEntry entry) throws IOException, ParseException
  {
    SymtabEntry ret = null;
    switch (token.type)
    {
       case Token.Long:
       case Token.Short:
       case Token.Unsigned:
         return integerType (entry);
       case Token.Char:
       case Token.Wchar:
         return charType();
       case Token.Boolean:
         return booleanType();
       case Token.Enum:
         return enumType (entry);
       case Token.Identifier:
       case Token.DoubleColon:
         ret = scopedName (entry, stFactory.primitiveEntry ());
         if (hasArrayInfo (entry.type ()))
           ParseException.illegalArray (scanner, "switch");
         SymtabEntry retType = typeOf (ret);
         if (!(retType instanceof EnumEntry || retType instanceof PrimitiveEntry))
           ParseException.wrongType (scanner, ret.fullName (),
               "long, unsigned long, short, unsigned short, char, boolean, enum",
               entryName (ret.type ()));
         else if (ret instanceof PrimitiveEntry)
         {
           SymtabEntry octet = qualifiedEntry ("octet");
           SymtabEntry flt   = qualifiedEntry ("float");
           SymtabEntry dbl   = qualifiedEntry ("double");
           if (retType == octet || retType == flt || retType == dbl)
             ParseException.wrongType (scanner, ret.fullName(),
                 "long, unsigned long, short, unsigned short, char, boolean, enum",
                 entryName(ret.type ()));
         }
         break;
       default:
         throw ParseException.syntaxError (scanner, new int [] {
             Token.Long,    Token.Short, Token.Unsigned, Token.Char,
             Token.Boolean, Token.Enum,  Token.Identifier,
             Token.DoubleColon }, token.type);
    }
    return ret;
  } // switchTypeSpec

  // This is only used by the union methods
  UnionBranch defaultBranch = null;

  /**
   *
   **/
  private void switchBody (UnionEntry entry) throws IOException, ParseException
  {
    caseProd (entry);
    while (!token.equals (Token.RightBrace))
      caseProd (entry);
    entry.defaultBranch ((defaultBranch == null) ? null : defaultBranch.typedef);
    defaultBranch = null;
  } // switchBody

  /**
   *
   **/
  private void caseProd (UnionEntry entry) throws IOException, ParseException
  {
    UnionBranch branch = new UnionBranch ();
    entry.addBranch (branch);
    caseLabel (entry, branch);
    while (token.equals (Token.Case) || token.equals (Token.Default))
      caseLabel (entry, branch);
    elementSpec (entry, branch);
    match (Token.Semicolon);
  } // caseProd

  /**
   *
   **/
  private void caseLabel (UnionEntry entry, UnionBranch branch) throws IOException, ParseException
  {
    if (token.type == Token.Case)
    {
      match (Token.Case);
      ConstEntry tmpEntry = stFactory.constEntry (entry, (IDLID)repIDStack.peek ());
      tmpEntry.sourceFile (scanner.fileEntry ());
      tmpEntry.type (entry);

      Expression  label;
      SymtabEntry type = typeOf (entry.type ());
      if (type instanceof EnumEntry)
        label = matchEnum ((EnumEntry)type);
      else
      {
        label = constExp (tmpEntry);
        verifyConstType (label, type);
      }
      if (entry.has (label))
        ParseException.branchLabel (scanner, label.rep ());
      branch.labels.addElement (label);
      match (Token.Colon);
    }
    else if (token.type == Token.Default)
    {
      match (Token.Default);
      match (Token.Colon);
      if (entry.defaultBranch () != null)
        ParseException.alreadyDefaulted (scanner);
      branch.isDefault = true;
      defaultBranch    = branch;
    }
    else
      throw ParseException.syntaxError (scanner, new int [] { Token.Case, Token.Default }, token.type);
  } // caselabel

  /**
   *
   **/
  private Expression matchEnum (EnumEntry entry) throws IOException, ParseException
  {
    // Get the symbol table entry for the case label based on the
    // scope of the EnumEntry, NOT the UnionEntry (the union could be
    // in a different scope than the enum).  Given
    // module M { enum E {A, B, C, D}; };
    // a case label for A could be one of the following:
    // case A:
    // case M::A:
    // case ::M::A:
    SymtabEntry label = scopedName (entry.container(), new SymtabEntry ());
    return exprFactory.terminal (label.name (), false);
  } // matchEnum

  /**
   *
   **/
  private void elementSpec (UnionEntry entry, UnionBranch branch) throws IOException, ParseException
  {
    TypedefEntry typedef = stFactory.typedefEntry (entry, (IDLID)repIDStack.peek ());
    typedef.sourceFile (scanner.fileEntry ());
    // Comment must immediately precede <type_spec> lexeme
    typedef.comment (token.comment);
    typedef.type (typeSpec (entry));
    if (typedef.type () == entry)
      throw ParseException.recursive (scanner, entry.fullName (), (token.name == null)? "" : token.name);
    // <d46094> Exception cannot appear within a struct, union, or exception
    if (typeOf (typedef) instanceof ExceptionEntry)
      throw ParseException.illegalException (scanner, entryName (entry));
    declarator (typedef);
    branch.typedef = typedef;
    // Ensure a branch with the same name doesn't already exist.
    if (entry.has (typedef))
      ParseException.branchName (scanner, typedef.name ());
  } // elementSpec

  /**
   *
   **/
  private EnumEntry enumType (SymtabEntry entry) throws IOException, ParseException
  {
    match (Token.Enum);
    EnumEntry enumEntry = newEnumEntry (entry);
    // comment must immediately precede "enum" keyword
    enumEntry.comment (tokenHistory.lookBack (1).comment);
    enumEntry.name (token.name);
    match (Token.Identifier);
    prep.openScope (enumEntry);
    match (Token.LeftBrace);
    if (isntInStringList (enumEntry.elements (), token.name))
    {
      enumEntry.addElement (token.name);
      SymtabEntry element = new SymtabEntry (entry, (IDLID)repIDStack.peek ());
      // if block taken from EnumEntry ctor
      if (element.module ().equals (""))
        element.module (element.name ());
      else if (!element.name ().equals (""))
        element.module (element.module () + "/" + element.name ());
      element.name (token.name);
      // <d50237> Place the SymtabEntry representing this enumeration
      // contant into the SymtabEntry defining its scope (e.g., InterfaceEntry,
      // ValueEntry, etc.) rather than the SymtabEntry passed in, which
      // may not define the contant's scope (e.g., TypedefEntry).
      //pigeonhole (entry, element); } <daz>
      pigeonhole (enumEntry.container (), element);
    }
    match (Token.Identifier);
    enumType2 (enumEntry);
    prep.closeScope (enumEntry);
    match (Token.RightBrace);
    return enumEntry;
  } // enumType

  /**
   *
   **/
  private void enumType2 (EnumEntry entry) throws IOException, ParseException
  {
    while (token.type == Token.Comma)
    {
      match (Token.Comma);
      String name = token.name;
      match (Token.Identifier);
      if (isntInStringList (entry.elements (), name))
      {
        entry.addElement (name);
        SymtabEntry element = new SymtabEntry (entry.container (), (IDLID)repIDStack.peek ());
        // if block taken from EnumEntry ctor:
        if (element.module ().equals (""))
          element.module (element.name ());
        else if (!element.name().equals (""))
          element.module (element.module () + "/" + element.name ());
        element.name (name);
        pigeonhole (entry.container  (), element);
      }
    }
  } // enumType2

  /**
   *
   **/
  private SequenceEntry sequenceType (SymtabEntry entry) throws IOException, ParseException
  {
    match (Token.Sequence);
    match (Token.LessThan);

    SequenceEntry newEntry = newSequenceEntry (entry);
    SymtabEntry tsentry = simpleTypeSpec (newEntry, false );
    newEntry.type (tsentry);
    if (!tsentry.isReferencable()) {
        // This is a sequence type that is referencing an
        // incomplete forward declaration of a struct or
        // union.  Save the sequence in a list for later
        // backpatching.
        try {
            List fwdTypes = (List)tsentry.dynamicVariable( ftlKey ) ;
            if (fwdTypes == null) {
                fwdTypes = new ArrayList() ;
                tsentry.dynamicVariable( ftlKey, fwdTypes ) ;
            }
            fwdTypes.add( newEntry ) ;
        } catch (NoSuchFieldException exc) {
            throw new IllegalStateException() ;
        }
    }

    if (token.type == Token.Comma)
    {
      match (Token.Comma);
      ConstEntry tmpEntry = stFactory.constEntry (newEntry, (IDLID)repIDStack.peek ());
      tmpEntry.sourceFile (scanner.fileEntry ());
      tmpEntry.type (qualifiedEntry ("long"));
      newEntry.maxSize (positiveIntConst (tmpEntry));
      verifyConstType (newEntry.maxSize(), qualifiedEntry ("long"));
    }
    match (Token.GreaterThan);
    return newEntry;
  } // sequenceType

  /**
   *
   **/
  private StringEntry stringType (SymtabEntry entry) throws IOException, ParseException
  {
    StringEntry string = stFactory.stringEntry ();
    if (token.type == Token.String)
    {
      string.name (overrideName ("string"));
      match (Token.String);
    }
    else
    {
      string.name (overrideName ("wstring"));
      match (Token.Wstring);
    }
    string.maxSize (stringType2 (entry));
    return string;
  } // stringType

  /**
   *
   **/
  private Expression stringType2 (SymtabEntry entry) throws IOException, ParseException
  {
    if (token.type == Token.LessThan)
    {
      match (Token.LessThan);

      // START IBM.11417 failure in the IDL compiler
      //Expression maxSize = positiveIntConst (entry);   IBM.11417

      ConstEntry tmpEntry = stFactory.constEntry (entry, (IDLID)repIDStack.peek
());
      tmpEntry.sourceFile (scanner.fileEntry ());
      tmpEntry.type (qualifiedEntry ("long"));
      Expression maxSize = positiveIntConst (tmpEntry);

      // END IBM.11417

      verifyConstType (maxSize, qualifiedEntry ("long"));
      match (Token.GreaterThan);
      return maxSize;
    }
    return null;
  } // stringType2

  /**
   *
   **/
  private void fixedArraySize (TypedefEntry entry) throws IOException, ParseException
  {
    match (Token.LeftBracket);
    ConstEntry tmpEntry = stFactory.constEntry (entry, (IDLID)repIDStack.peek ());
    tmpEntry.sourceFile (scanner.fileEntry ());
    // <d58058> Set type of tmpExpr to "long", which is the array index type.
    // Previously, this type was erroneously set to the array element type.
    //tmpEntry.type (entry.type ());
    tmpEntry.type (qualifiedEntry ("long"));
    Expression expr = positiveIntConst (tmpEntry);
    entry.addArrayInfo (expr);
    verifyConstType (expr, qualifiedEntry ("long"));
    match (Token.RightBracket);
  } // fixedArraySize

  /**
   *
   **/
  private void attrDcl (InterfaceEntry entry) throws IOException, ParseException
  {
    AttributeEntry attribute = stFactory.attributeEntry (entry, (IDLID)repIDStack.peek ());
    attribute.sourceFile (scanner.fileEntry ());
    // Comment must immediately precede the "attribute" keyword.  Save the
    // comment preceding the declaration for use below.
    attribute.comment (token.comment);
    Comment dclComment = attribute.comment ();

    if (token.type == Token.Readonly)
    {
      match (Token.Readonly);
      attribute.readOnly (true);
    }
    match (Token.Attribute);
    attribute.type (paramTypeSpec (attribute));
    attribute.name (token.name);
    // Override declaration comment if attribute identifier is commented
    if (!token.comment.text ().equals (""))
      attribute.comment (token.comment);
    entry.methodsAddElement (attribute, scanner);
    pigeonholeMethod (entry, attribute);
    // Declaration comment was overriden:
    if (!token.comment.text ().equals (""))
    {
      // Create a temporary attribute with declaration comment so cloning in
      // attrdcl2() can use declaration comment as default.
      AttributeEntry attributeClone = (AttributeEntry) attribute.clone ();
      attributeClone.comment (dclComment);

      match (Token.Identifier);
      attrDcl2 (entry, attributeClone);
    }
    else
    {
      match (Token.Identifier);
      attrDcl2 (entry, attribute);
    }
    //match (Token.Identifier);
    //attrDcl2 (entry, attribute);
  } // attrDcl

  /**
   *
   **/
  private void attrDcl2 (InterfaceEntry entry, AttributeEntry clone)
          throws IOException, ParseException
  {
    while (token.type == Token.Comma)
    {
      match (Token.Comma);
      AttributeEntry attribute = (AttributeEntry)clone.clone ();
      attribute.name (token.name);
      // Override the declaration comment (i.e., that preceding the
      // "attribute" keyword) if the attribute identifier is commented.
      if (!token.comment.text ().equals (""))
        attribute.comment (token.comment);
      entry.methodsAddElement (attribute, scanner);
      pigeonholeMethod (entry, attribute);
      match (Token.Identifier);
    }
  } // attrDcl2

  /**
   *
   **/
  private void exceptDcl (SymtabEntry entry) throws IOException, ParseException
  {
    match (Token.Exception);
    repIDStack.push (((IDLID)repIDStack.peek ()).clone ());
    ExceptionEntry exceptEntry = stFactory.exceptionEntry (entry, (IDLID)repIDStack.peek ());
    ((IDLID)repIDStack.peek ()).appendToName (token.name);
    exceptEntry.sourceFile (scanner.fileEntry ());
    // Comment must immediately precede "exception" keyword
    exceptEntry.comment (tokenHistory.lookBack (1).comment);
    exceptEntry.name (token.name);
    match (Token.Identifier);
    pigeonhole (entry, exceptEntry);
    if (token.equals (Token.LeftBrace))
    {
      prep.openScope (exceptEntry);
      match (Token.LeftBrace);
      memberList2 (exceptEntry);
      prep.closeScope (exceptEntry);
      match (Token.RightBrace);
      repIDStack.pop ();
    }
    else
      throw ParseException.syntaxError (scanner, Token.LeftBrace,token.type);
  } // exceptDcl

  /**
   *
   **/
  private void opDcl (InterfaceEntry entry) throws IOException, ParseException
  {
    MethodEntry method = stFactory.methodEntry (entry, (IDLID)repIDStack.peek ());
    method.sourceFile (scanner.fileEntry ());
    // Comment must immediately precede "oneway" keyword or <return_type_spec>
    method.comment (token.comment);
    if (token.type == Token.Oneway)
    {
      match (Token.Oneway);
      method.oneway (true);
    }
    method.type (opTypeSpec (method));
    repIDStack.push (((IDLID)repIDStack.peek ()).clone ());
    ((IDLID)repIDStack.peek ()).appendToName (token.name);
    method.name (token.name);
    entry.methodsAddElement (method, scanner);
    pigeonholeMethod (entry, method);
    opDcl2 (method);
    if (method.oneway ())
      checkIfOpLegalForOneway (method);
    repIDStack.pop ();
  } // opDcl

  /**
   *
   **/
  private void checkIfOpLegalForOneway (MethodEntry method)
  {
    boolean notLegal = false;
    if ((method.type() != null) ||
         (method.exceptions().size() != 0)) notLegal = true;
    else
    {
      for (Enumeration e = method.parameters().elements(); e.hasMoreElements();)
      {
        if (((ParameterEntry)e.nextElement ()).passType () != ParameterEntry.In)
        {
          notLegal = true;
          break;
        }
      }
    }
    if (notLegal)
      ParseException.oneway (scanner, method.name ());
  } // checkifOpLegalForOneway

  /**
   *
   **/
  private void opDcl2 (MethodEntry method) throws IOException, ParseException
  {
    if (token.equals (Token.MacroIdentifier))
    {
      match (Token.MacroIdentifier);
      parameterDcls2 (method);
    }
    else
    {
      match (Token.Identifier);
      parameterDcls (method);
     }
    opDcl3 (method);
  } // opDcl2

  /**
   *
   **/
  private void opDcl3 (MethodEntry entry) throws IOException, ParseException
  {
    if (token.type != Token.Semicolon)
    {
      if (!token.equals (Token.Raises) && !token.equals (Token.Context))
        throw ParseException.syntaxError (scanner, new int [] {
            Token.Raises, Token.Context, Token.Semicolon }, token.type);
      if (token.type == Token.Raises)
        raisesExpr (entry);
      if (token.type == Token.Context)
        contextExpr (entry);
    }
  } // opDcl3

  /**
   *
   **/
  private SymtabEntry opTypeSpec (SymtabEntry entry) throws IOException, ParseException
  {
    SymtabEntry ret = null;
    if (token.type == Token.Void)
      match (Token.Void);
    else
      ret = paramTypeSpec (entry);
    return ret;
  } // opTypeSpec

  /**
   *
   **/
  private void parameterDcls (MethodEntry entry) throws IOException, ParseException
  {
    match (Token.LeftParen);
    parameterDcls2 (entry);
  } // parameterDcls

  /**
   *
   **/
  private void parameterDcls2 (MethodEntry entry) throws IOException, ParseException
  {
    if (token.type == Token.RightParen)
      match (Token.RightParen);
    else
    {
      paramDcl (entry);
      while (token.type == Token.Comma)
      {
        match (Token.Comma);
        paramDcl (entry);
      }
      match (Token.RightParen);
    }
  } // paraneterDcls2

  /**
   *
   **/
  private void paramDcl (MethodEntry entry) throws IOException, ParseException
  {
    ParameterEntry parmEntry = stFactory.parameterEntry (entry, (IDLID)repIDStack.peek ());
    parmEntry.sourceFile (scanner.fileEntry ());
    // Comment must immeiately precede the parameter attribute
    parmEntry.comment (token.comment);
    paramAttribute (parmEntry);
    parmEntry.type (paramTypeSpec (entry));
    parmEntry.name (token.name);
    match (Token.Identifier);
    if (isntInList (entry.parameters (), parmEntry.name ()))
      entry.addParameter (parmEntry);
  } // paramDcl

  /**
   *
   **/
  private void paramAttribute (ParameterEntry entry) throws IOException, ParseException
  {
    if (token.type == Token.In)
    {
      entry.passType (ParameterEntry.In);
      match (Token.In);
    }
    else if (token.type == Token.Out)
    {
      entry.passType (ParameterEntry.Out);
      match (Token.Out);
    }
    else if (token.type == Token.Inout)
    {
      entry.passType (ParameterEntry.Inout);
      match (Token.Inout);
    }
    else
      throw ParseException.syntaxError (scanner, new int [] {
          Token.In, Token.Out, Token.Inout }, token.type);
  } // paramAttribute

  /**
   *
   **/
  private void raisesExpr (MethodEntry entry) throws IOException, ParseException
  {
    match (Token.Raises);
    match (Token.LeftParen);
    // Comment must immediately precede <scoped_name> for exception
    Comment tempComment = token.comment;
    SymtabEntry exception = scopedName(entry.container (), stFactory.exceptionEntry ());
    if (typeOf (exception) instanceof ExceptionEntry)
    {
      // Comment must immediately precede <scoped_name> for exception
      exception.comment (tempComment);
      if (isntInList (entry.exceptions (), exception))
        entry.exceptionsAddElement ((ExceptionEntry) exception);
    }
    else
      ParseException.wrongType (scanner, exception.fullName(),
          "exception", entryName (exception.type ()));
    raisesExpr2 (entry);
    match (Token.RightParen);
  } // raisesExpr

  /**
   *
   **/
  private void raisesExpr2 (MethodEntry entry) throws IOException, ParseException
  {
    while (token.type == Token.Comma)
    {
      match (Token.Comma);
      // Comment must immediately precede <scoped_name> of exception
      Comment tempComment = token.comment;
      SymtabEntry exception = scopedName (entry.container (), stFactory.exceptionEntry ());
      if (typeOf (exception) instanceof ExceptionEntry)
      {
        // Comment must immediately precede <scoped_name> of exception
        exception.comment (tempComment);
        if (isntInList (entry.exceptions (), exception))
          entry.addException ((ExceptionEntry)exception);
      }
      else
        ParseException.wrongType (scanner, exception.fullName (),
            "exception", entryName (exception.type ()));
    }
  } // raisesExpr2

  /**
   *
   **/
  private void contextExpr (MethodEntry entry) throws IOException, ParseException
  {
    match (Token.Context);
    match (Token.LeftParen);
    String stringLit = (String)stringLiteral ().value ();
    if (isntInStringList (entry.contexts (), stringLit))
      entry.addContext (stringLit);
    contextExpr2 (entry);
    match (Token.RightParen);
  } // contextExpr


  private void contextExpr2 (MethodEntry entry) throws IOException, ParseException
  {
    while (token.type == Token.Comma)
    {
      match (Token.Comma);
      String stringLit = (String)stringLiteral ().value ();
      if (isntInStringList (entry.contexts (), stringLit))
        entry.addContext (stringLit);
    }
  } // contextExpr2

  /**
   *
   **/
  private SymtabEntry paramTypeSpec (SymtabEntry entry) throws IOException, ParseException
  {
    SymtabEntry ret = null;
    switch (token.type)
    {
      case Token.Float:
      case Token.Double:
      case Token.Long:
      case Token.Short:
      case Token.Unsigned:
      case Token.Char:
      case Token.Wchar:
      case Token.Boolean:
      case Token.Octet:
      case Token.Any:
        return baseTypeSpec (entry);
      case Token.String:
      case Token.Wstring:
        return stringType (entry);
      case Token.Identifier:
      case Token.Object:
      // <f46082.40>
      case Token.ValueBase:
      case Token.DoubleColon:
        ret = scopedName (entry.container (), stFactory.primitiveEntry ());
        if (typeOf (ret) instanceof AttributeEntry)
          //ParseException.attributeParamType (scanner);
          ParseException.attributeNotType (scanner, ret.name ());
        else // <d60942>
          if (typeOf (ret) instanceof MethodEntry)
            ParseException.operationNotType (scanner, ret.name ());

        //if (!(returnType instanceof PrimitiveEntry ||
        //     returnType instanceof StringEntry))
        //ParseException.wrongType (scanner, ret.fullName(),
        //                          "primitive or string", entryName (ret.type()));
        break;
      default:
        throw ParseException.syntaxError (scanner, new int [] {
            Token.Float,      Token.Double,      Token.Long,    Token.Short,
            Token.Unsigned,   Token.Char,        Token.Wchar,   Token.Boolean,
            Token.Octet,      Token.Any,         Token.String,  Token.Wstring,
            Token.Identifier, Token.DoubleColon, Token.ValueBase }, token.type);
    }
    return ret;
  } // paramTypeSpec

  /**
   *
   **/
  private void match (int type) throws IOException, ParseException
  {
    ParseException exception = null;
    if (!token.equals (type))
    {
      exception = ParseException.syntaxError (scanner, type, token.type);
      // Missing a semicolon is a common error.  If a semicolon was expected,
      // assume it exists and keep the current token (don't get the next one).
      // BEWARE!!! THIS HAS THE POTENTIAL FOR AN INFINITE LOOP!
      if (type == Token.Semicolon)
        return;
    }
    // <f46082.40> Unecessary due to new valueElement() algorithm.
    //if (!tokenStack.empty())
    //{
    //  token = (Token)tokenStack.pop ();
    //  return;
    //}

    // Fetch the next token.
    token = scanner.getToken ();

    // <d62023> Issue warnings about tokens.
    issueTokenWarnings ();

    // Maintain history of most recent tokens.
    tokenHistory.insert (token);

    // <d59166> Identifiers that collide with keywords are illegal.  Note
    // that escaped identifers never collide!
    /*
    if (token.collidesWithKeyword ())
    {
      // <f60858.1> Issue a warning only
      if (corbaLevel <= 2.2f)
        ParseException.keywordCollisionWarning (scanner, token.name);
      else
        exception = ParseException.keywordCollision (scanner, token.name);
    }
    */

    while (token.isDirective ())
      token = prep.process (token);

    // If the token is a defined thingy, scan the defined string
    // instead of the input stream for a while.
    if (token.equals (Token.Identifier) || token.equals (Token.MacroIdentifier))
    {
      String string = (String)symbols.get (token.name);
      if (string != null && !string.equals (""))
      {
        // If this is a macro, parse the macro
        if (macros.contains (token.name))
        {
          scanner.scanString (prep.expandMacro (string, token));
          match (token.type);
        }
        else // This is just a normal define.
        {
          scanner.scanString (string);
          match (token.type);
        }
      }
    }
    if (exception != null)
      throw exception;
  } // match

  // <d62023>
  /**
   * Issue warnings according to attributes of current Token.
   **/
  private void issueTokenWarnings ()
  {
    if (noWarn)
      return;

    if ((token.equals (Token.Identifier) || token.equals (Token.MacroIdentifier))
        && !token.isEscaped ())
    {
      // Identifier collision with keyword in another release.
      // Identifier collision with keyword in letter, but not in case.
      if (token.collidesWithKeyword ())
        ParseException.warning (scanner, Util.getMessage ("Migration.keywordCollision", token.name));
    }
    // Deprecated keyword.
    if (token.isKeyword () && token.isDeprecated ())
      ParseException.warning (scanner, Util.getMessage ("Deprecated.keyword", token.toString ()));
  } // issueTokenWarnings

  /**
   *
   **/
  private ModuleEntry newModule (ModuleEntry oldEntry)
  {
    ModuleEntry entry = stFactory.moduleEntry (oldEntry, (IDLID)repIDStack.peek ());
    entry.sourceFile (scanner.fileEntry ());
    entry.name (token.name);
    // If this named module already exists, just reopen it.
    /* <46082.46.01> if cppModule, always create new module entry */
    SymtabEntry prevEntry = (SymtabEntry) symbolTable.get (entry.fullName ());
    if (!cppModule && prevEntry != null && prevEntry instanceof ModuleEntry)
    {
      // A module has been reopened, return that ModuleEntry.
      entry = (ModuleEntry) prevEntry;
      if (oldEntry == topLevelModule)
      {
        // Do a little checking:
        if (!entry.emit ())
          // The entry module is being reopened to put new stuff into it.
          // The module itself is not marked as "emit", but the new stuff
          // may be, so put the module on the emitList (add it to topLevelModule).
          addToContainer (oldEntry, entry);
        else if (!oldEntry.contained().contains (entry))
          // <d50767> The entry module being reopened is to be emitted, but
          // will not be placed on the emitList! I.E., it was not added to
          // topLevelModule.  Occurs when a generator manually inserts
          // ModuleEntrys into the symbol table (e.g., org; see preParse()
          // in ...idl.toJava.Compile). <daz>
          addToContainer (oldEntry, entry);
      }
    }
    else
      pigeonhole (oldEntry, entry);
    return entry;
  } // newModule

  /**
   *
   **/
  private EnumEntry newEnumEntry (SymtabEntry oldEntry)
  {
    EnumEntry entry = stFactory.enumEntry (oldEntry, (IDLID)repIDStack.peek ());
    entry.sourceFile (scanner.fileEntry ());
    entry.name (token.name);
    pigeonhole (oldEntry, entry);
    return entry;
  } // newEnumEntry

  /**
   *
   **/
  private SequenceEntry newSequenceEntry (SymtabEntry oldEntry)
  {
    SequenceEntry entry = stFactory.sequenceEntry (oldEntry, (IDLID)repIDStack.peek ());
     entry.sourceFile (scanner.fileEntry ());
     entry.name ("");
     pigeonhole (oldEntry, entry);
     return entry;
  } // newSequenceEntry

    private void updateSymbolTable( String fullName, SymtabEntry entry, boolean lcCheck )
    {
        // Check for case-insensitive collision (IDL error).
        String lcFullName = fullName.toLowerCase();
        if (lcCheck)
            if (lcSymbolTable.get (lcFullName) != null) {
                ParseException.alreadyDeclared (scanner, fullName);
            }
        symbolTable.put (fullName, entry);
        lcSymbolTable.put (lcFullName, entry);
        // <d59809> Allow fully-qualified CORBA types to be resolved by mapping
        // short name (e.g., CORBA/StringValue) to long name, actual name.
        String omgPrefix = "org/omg/CORBA" ;
        if (fullName.startsWith (omgPrefix)) {
            overrideNames.put (
                "CORBA" + fullName.substring (omgPrefix.length()), fullName);
        }
    }

    private void pigeonhole (SymtabEntry container, SymtabEntry entry)
    {
        if (entry.name().equals (""))
            entry.name (unknownNamePrefix + ++sequence);

        // If this object is not in the overrides list, then it is
        // ok to put it in the table (if it IS in the overrides list,
        // it is already in the table under a different name).
        String fullName = entry.fullName();
        if (overrideNames.get (fullName) == null) {
            addToContainer (container, entry);

            // It is an error is this name already exists in the symbol
            // table, unless this is a redefinition of a forward decl.
            // Re-opening a module is also legal, but not handled here.
            SymtabEntry oldEntry = (SymtabEntry) symbolTable.get (fullName);

            if (oldEntry == null) {
                updateSymbolTable( fullName, entry, true ) ;
            } else if (oldEntry instanceof ForwardEntry &&
                entry instanceof InterfaceEntry) {

                String repIDPrefix = ((IDLID)entry.repositoryID ()).prefix ();
                String oldRepIDPrefix = ((IDLID)oldEntry.repositoryID ()).prefix ();
                if (repIDPrefix.equals (oldRepIDPrefix)) {
                    updateSymbolTable( fullName, entry, false ) ;
                } else {
                    ParseException.badRepIDPrefix (scanner, fullName,
                        oldRepIDPrefix, repIDPrefix);
                }
            } else if (entry instanceof ForwardEntry &&
                       (oldEntry instanceof InterfaceEntry ||
                        oldEntry instanceof ForwardEntry)) {
                if (oldEntry instanceof ForwardEntry &&
                    entry.repositoryID () instanceof IDLID &&
                    oldEntry.repositoryID () instanceof IDLID) {

                    String repIDPrefix =
                        ((IDLID)entry.repositoryID ()).prefix ();
                    String oldRepIDPrefix =
                        ((IDLID)oldEntry.repositoryID ()).prefix ();

                    if (!(repIDPrefix.equals (oldRepIDPrefix))) {
                        // Disallow multiple ForwardEntry's having same Repository
                        // ID prefixes (CORBA 2.3).
                        ParseException.badRepIDPrefix (scanner, fullName,
                            oldRepIDPrefix, repIDPrefix);
                    }
                }
            } else if (cppModule && entry instanceof ModuleEntry &&
                oldEntry instanceof ModuleEntry) {
                // Allow multiple ModuleEntrys when user submits
                // the -cppModule flag.
            } else if (fullName.startsWith ("org/omg/CORBA") ||
                fullName.startsWith ("CORBA")) {
                // Ignore CORBA PIDL types entered at preParse() by generator.
            } else if (isForwardable( oldEntry, entry )) {
                // Both oldEntry and entry are structs or unions.
                // Legality depends on isReferencable on the two entries:
                // oldEntry     Entry
                //      T           T       ERROR alreadyDeclared
                //      T           F       legal fwd decl
                //      F           T       if defined in same file legal,
                //                          otherwise ERROR
                //      F           F       legal fwd decl
                if (oldEntry.isReferencable() && entry.isReferencable())
                    ParseException.alreadyDeclared (scanner, fullName);

                if (entry.isReferencable()) {
                    String firstFile =
                        oldEntry.sourceFile().absFilename() ;
                    String defFile =
                        entry.sourceFile().absFilename() ;
                    if (!firstFile.equals( defFile ))
                        ParseException.declNotInSameFile( scanner,
                            fullName, firstFile ) ;
                    else {
                        updateSymbolTable( fullName, entry, false ) ;

                        List oldRefList ;

                        try {
                            oldRefList = (List)oldEntry.dynamicVariable(
                                ftlKey ) ;
                        } catch (NoSuchFieldException exc) {
                            throw new IllegalStateException() ;
                        }

                        if (oldRefList != null) {
                            // Update entries in backpatch list
                            Iterator iter = oldRefList.iterator() ;
                            while (iter.hasNext()) {
                                SymtabEntry elem = (SymtabEntry)iter.next() ;
                                elem.type( entry ) ;
                            }
                        }
                    }
                }
            } else {
                ParseException.alreadyDeclared (scanner, fullName);
            }
        }
    } // pigeonhole

    private boolean isForwardable( SymtabEntry oldEntry,
        SymtabEntry entry )
    {
        return ((oldEntry instanceof StructEntry) &&
            (entry instanceof StructEntry)) ||
           ((oldEntry instanceof UnionEntry) &&
            (entry instanceof UnionEntry)) ;
    }

  // pigeonhole checks to see if this entry is already in the symbol
  // table and generates an error if it is.  Methods must be checked
  // not only against the symbol table but also against their
  // interface's parent's methods.  This is done in InterfaceEntry.
  // verifyMethod, so no checking need be done here.

  /**
   *
   **/
  private void pigeonholeMethod (InterfaceEntry container, MethodEntry entry)
  {
    if (entry.name ().equals (""))
       entry.name (unknownNamePrefix + ++sequence);

    // If this object is not in the overrides list, then it is
    // ok to put it in the table (if it IS in the overrides list,
    // it is already in the table under a different name).
    String fullName = entry.fullName ();
    if (overrideNames.get (fullName) == null)
    {
      addToContainer (container, entry);
      String lcFullName = fullName.toLowerCase ();
      symbolTable.put (fullName, entry);
      lcSymbolTable.put (lcFullName, entry);
      // <d59809> Allow fully-qualified CORBA types to be resolved by mapping
      // short name (e.g., CORBA/StringValue) to long name, actual name.
      if (fullName.startsWith ("org/omg/CORBA"))
        overrideNames.put ("CORBA" + fullName.substring (13), fullName);
    }
  } // pigeonholeMethod

  /**
   *
   **/
  private void addToContainer (SymtabEntry container, SymtabEntry contained)
  {
    if (container instanceof ModuleEntry)
      ((ModuleEntry)container).addContained (contained);
    else if (container instanceof InterfaceEntry)
      ((InterfaceEntry)container).addContained (contained);
    else if (container instanceof StructEntry)
      ((StructEntry)container).addContained (contained);
    else if (container instanceof UnionEntry)
      ((UnionEntry)container).addContained (contained);
    else if (container instanceof SequenceEntry)
      ((SequenceEntry)container).addContained (contained);
  } // addToContainer

  // NOTE: qualifiedEntry/partlyQualifiedEntry/unqualifiedEntry and
  // their court could probably use some performance improvements,
  // but I'm scared to touch anything.  It's the most complex bit of
  // code in this parser.

  // The qualified named type is searched for in the following order:
  // 1.  OverrideNames
  // 2.  Global scope
  // 3.  Inheritance scope (if container is an interface)
  // A qualified name is one which begins with :: or is assumed to be
  // in the global scope (like long, short, etc).

  /**
   *
   **/
  SymtabEntry qualifiedEntry (String typeName)
  {
    SymtabEntry type = recursiveQualifiedEntry (typeName);
    if (type == null)
      // Then it's not anywhere, report the error.
      ParseException.undeclaredType (scanner, typeName);

    // <d57110> Relax this retriction when parsing ID pragma directive, e.g..
    //else if (type instanceof ModuleEntry) {
    else if (type instanceof ModuleEntry && !_isModuleLegalType)
    {
      // Module's are not valid types.
      ParseException.moduleNotType (scanner, typeName);
      type = null;
    }
    return type;
  } // qualifiedEntry

  /**
   *
   **/
  SymtabEntry recursiveQualifiedEntry (String typeName)
  {
    SymtabEntry type = null;
    if (typeName != null && !typeName.equals ("void"))
    {
      int index = typeName.lastIndexOf ('/');
      if (index >= 0)
      {
        // Figure out if the container of this thing exists, converting any typedefs to interfaces if necessary.
        type = recursiveQualifiedEntry (typeName.substring (0, index));
        if (type == null)
          return null;
        else if (type instanceof TypedefEntry)
          typeName = typeOf (type).fullName () + typeName.substring (index);
      }

      // If we got this far, a container exists, start over looking
      // for the thing itself (this is the meat of the method):
      type = searchOverrideNames (typeName);
      if (type == null)
        type = (SymtabEntry) symbolTable.get (typeName); // search global scope:
      if (type == null)
        type = searchGlobalInheritanceScope (typeName);
    }
    return type;
  } // recursiveQualifiedEntry

  // A partially qualified name is of the form <scope>::.
  // First the scope is defined (meaning it is fully qualified);
  // Then the name is searched for in the scope.

  /**
   *
   **/
  SymtabEntry partlyQualifiedEntry (String typeName, SymtabEntry container)
  {
    // This is the simple logic of this method:
    // type = searchModuleScope (typeName.substring (0, typeName.lastIndexOf ('/')), container);
    // type = qualifiedEntry (type.fullName () + typeName.substring (typeName.lastIndexOf ('/')));
    // But searchModuleScope only finds the first module that fits.
    // The name might not be in that module but in one further out
    // in the module scope.  Should others be searched?
    SymtabEntry type = null;
    if (typeName != null)
    {
      int index = typeName.lastIndexOf ('/');

      // Figure out if the container of this thing exists, converting any
      // typedefs to interfaces if necessary:
      type = recursivePQEntry (typeName.substring (0, index), container);
      if (type instanceof TypedefEntry)
        typeName = typeOf (type).fullName () + typeName.substring (index);

      // If we got this far, a container exists, start over looking
      // for the thing itself.

      if (container != null)
        type = searchModuleScope (typeName.substring (0, typeName.lastIndexOf ('/')), container);
      if (type == null)
        type = qualifiedEntry (typeName);
      else
        type = qualifiedEntry (type.fullName () + typeName.substring (typeName.lastIndexOf ('/')));
    }
    return type;
  } // partlyQualifiedEntry

  // partlyQualifiedEntry and recursivePQEntry are almost identical.
  // They are different because when the recursive one is looking for
  // the existence of containers, the error check for a module type
  // must not occur (this check is done in qualifiedEntry).  Only
  // when the full partly qualified name is being processed must this
  // check be performed.

  /**
   *
   **/
  SymtabEntry recursivePQEntry (String typeName, SymtabEntry container)
  {
    SymtabEntry type = null;
    if (typeName != null)
    {
      int index = typeName.lastIndexOf ('/');
      if (index < 0)
        type = searchModuleScope (typeName, container);
      else
      {
        // Figure out if the container of this thing exists, converting any
        // typedefs to interfaces if necessary:
        type = recursivePQEntry (typeName.substring (0, index), container);
        if (type == null)
          return null;
        else if (type instanceof TypedefEntry)
          typeName = typeOf (type).fullName () + typeName.substring (index);

        // If we got this far, a container exists, start over, looking
        // for the thing itself (This is the meat of the method):
        if (container != null)
          type = searchModuleScope (typeName.substring (0, typeName.lastIndexOf ('/')), container);
          if (type == null)
            recursiveQualifiedEntry (typeName);
          else
            type = recursiveQualifiedEntry (type.fullName () + typeName.substring (typeName.lastIndexOf ('/')));
      }
    }
    return type;
  } // recursivePQEntry

  // The named type is searched for in the following order:
  // 1.  Local scope
  // 2.  Inheritance scope
  // 3.  OverrideNames
  // 4.  Module scope

  /**
   *
   **/
  SymtabEntry unqualifiedEntry (String typeName, SymtabEntry container)
  {
    SymtabEntry type = unqualifiedEntryWMod (typeName, container);

    // <d57110> Relax this retriction in special cases, e.g., when
    // parsing a ID pragma directive.
    //if (type instanceof ModuleEntry) {
    if (type instanceof ModuleEntry && !_isModuleLegalType)
    {
      // Module's are not valid types:
      ParseException.moduleNotType (scanner, typeName);
      type = null;
    }
    return type;
  } // unqualifiedEntry

  /**
   *
   **/
  SymtabEntry unqualifiedEntryWMod (String typeName, SymtabEntry container)
  {
    SymtabEntry type = null;
    if ((typeName != null) && !typeName.equals ("void"))
    {
      // Search local scope:
      type = (SymtabEntry)symbolTable.get (container.fullName () + '/' + typeName);
      if (type == null)
        type = searchLocalInheritanceScope (typeName, container);
      if (type == null)
        type = searchOverrideNames (typeName);
      if ((type == null) && (container != null))
        type = searchModuleScope (typeName, container);
      if (type == null)
        type = searchParentInheritanceScope (typeName, container);
    }
    if (type == null)
      // Then it's not anywhere, report the error:
      ParseException.undeclaredType (scanner, typeName);
    return type;
  } // unqualifiedEntryWMod

  /**
   * Walks up the enclosing scopes until it finds an interface type. Then,
   * searches up that interface inheritance tree for the type definition.
   *
   * @param name type name to be searched for.
   * @param ptype parent type entry.
   **/
  SymtabEntry searchParentInheritanceScope(String name, SymtabEntry ptype) {

    String cname = ptype.fullName();

    while ((ptype != null) && !(cname.equals ("")) &&
           !(ptype instanceof InterfaceEntry)) {
        int index = cname.lastIndexOf ('/');
        if (index < 0) {
            cname = "";
        } else {
            cname = cname.substring (0, index);
            ptype = (SymtabEntry) symbolTable.get(cname);
        }
    }

    if ((ptype == null) || !(ptype instanceof InterfaceEntry)) {
        return null; // could not find an enclosing interface type - give up.
    }

    // check if the enclosing interface supports the type definition.
    String fullName = ptype.fullName () + '/' + name;
    SymtabEntry type = (SymtabEntry) symbolTable.get (fullName);
    if (type != null) {
        return type; // found type definition.
    }

    // search up the interface inheritance tree.
    return searchLocalInheritanceScope(name, ptype);
  }

  /**
   *
   **/
  SymtabEntry searchGlobalInheritanceScope (String name)
  {
    // See if the container of this named object is an interface:
    int         index = name.lastIndexOf ('/');
    SymtabEntry entry = null;
    if (index >= 0)
    {
      String containerName = name.substring (0, index);
      entry = (SymtabEntry)symbolTable.get (containerName);
      entry = (entry instanceof InterfaceEntry)
          // It's an interface, now look in its inheritance scope:
          ? searchLocalInheritanceScope (name.substring (index + 1), entry)
          : null;
    }
    return entry;
  } // searchGlobalInheritanceScope

  /**
   *
   **/
  SymtabEntry searchLocalInheritanceScope (String name, SymtabEntry container)
  {
    return (container instanceof InterfaceEntry)
        ? searchDerivedFrom (name, (InterfaceEntry) container)
        : null;
  } // searchLocalInheritanceScope

  /**
   *
   **/
  SymtabEntry searchOverrideNames (String name)
  {
    String overrideName = (String)overrideNames.get (name);
    return (overrideName != null)
        ? (SymtabEntry)symbolTable.get (overrideName)
        : null;
  } // searchOverrideNames

  /**
   *
   **/
  SymtabEntry searchModuleScope (String name, SymtabEntry container)
  {
    String      module   = container.fullName ();
    String      fullName = module + '/' + name;
    SymtabEntry type     = (SymtabEntry)symbolTable.get (fullName);
    while ((type == null) && !module.equals (""))
    {
      int index = module.lastIndexOf ('/');
      if (index < 0)
        module = "";
      else
      {
        module   = module.substring (0, index);
        fullName = module + '/' + name;
        type     = (SymtabEntry)symbolTable.get (fullName);
      }
    }
    return (type == null) ? (SymtabEntry)symbolTable.get (name) : type;
  } // searchModuleScope

  /**
   *
   **/
  SymtabEntry searchDerivedFrom (String name, InterfaceEntry i)
  {
    for (Enumeration e = i.derivedFrom ().elements (); e.hasMoreElements ();)
    {
      SymtabEntry tmp = (SymtabEntry)e.nextElement ();
      if (tmp instanceof InterfaceEntry)
      {
        InterfaceEntry parent = (InterfaceEntry)tmp;
        String fullName = parent.fullName () + '/' + name;
        SymtabEntry type = (SymtabEntry)symbolTable.get (fullName);
        if (type != null)
          return type;
        type = searchDerivedFrom (name, parent);
        if (type != null)
          return type;
      }
      // else it is a ForwardEntry and nothing can be done at this point.
    }
    return null;
  } // searchDerivedFrom

  /**
   *
   **/
  String entryName (SymtabEntry entry)
  {
    if (entry instanceof AttributeEntry)
      return "attribute";
    if (entry instanceof ConstEntry)
      return "constant";
    if (entry instanceof EnumEntry)
      return "enumeration";
    if (entry instanceof ExceptionEntry)
      return "exception";
    if (entry instanceof ValueBoxEntry)
      return "value box";
    if (entry instanceof ForwardValueEntry || entry instanceof ValueEntry)
      return "value";
    if (entry instanceof ForwardEntry || entry instanceof InterfaceEntry)
      return "interface";
    if (entry instanceof MethodEntry)
      return "method";
    if (entry instanceof ModuleEntry)
      return "module";
    if (entry instanceof ParameterEntry)
      return "parameter";
    if (entry instanceof PrimitiveEntry)
      return "primitive";
    if (entry instanceof SequenceEntry)
      return "sequence";
    if (entry instanceof StringEntry)
      return "string";
    if (entry instanceof StructEntry)
      return "struct";
    if (entry instanceof TypedefEntry)
      return "typedef";
    if (entry instanceof UnionEntry)
      return "union";
    return "void";
  } // entryName

  /**
   *
   **/
  private boolean isInterface (SymtabEntry entry)
  {
    return entry instanceof InterfaceEntry || (entry instanceof ForwardEntry
        && !(entry instanceof ForwardValueEntry)) ;
  }

  private boolean isValue (SymtabEntry entry)
  {
    return entry instanceof ValueEntry ; // || entry instanceof ForwardValueEntry;
  }

  private boolean isInterfaceOnly (SymtabEntry entry)
  {
    return entry instanceof InterfaceEntry ;
  }

  private boolean isForward(SymtabEntry entry)
  {
      return entry instanceof ForwardEntry ;
  }

  // list must be a vector of Strings.
  /**
   *
   **/
  private boolean isntInStringList (Vector list, String name)
  {
    boolean isnt = true;
    Enumeration e = list.elements ();
    while (e.hasMoreElements ())
      if (name.equals ((String)e.nextElement ()))
      {
        ParseException.alreadyDeclared (scanner, name);
        isnt = false;
        break;
      }
    return isnt;
  } // isntInStringList

  // list must be a vector of SymtabEntry's.
  /**
   *
   **/
  private boolean isntInList (Vector list, String name)
  {
    boolean isnt = true;
    for (Enumeration e = list.elements (); e.hasMoreElements ();)
      if (name.equals (((SymtabEntry)e.nextElement ()).name ()))
      {
        ParseException.alreadyDeclared (scanner, name);
        isnt = false;
        break;
      }
    return isnt;
  } // isntInList

  // list must be a vector of SymtabEntry's.
  /**
   *
   **/
  private boolean isntInList (Vector list, SymtabEntry entry)
  {
    boolean isnt = true;
    for (Enumeration e = list.elements (); e.hasMoreElements ();)
    {
      SymtabEntry eEntry = (SymtabEntry)e.nextElement ();
      if (entry == eEntry)  // && entry.fullName().equals (eEntry.fullName()))
      {
        ParseException.alreadyDeclared (scanner, entry.fullName ());
        isnt = false;
        break;
      }
     }
     return isnt;
  } // isntInList

  /**
   *
   **/
  public static SymtabEntry typeOf (SymtabEntry entry)
  {
    while (entry instanceof TypedefEntry)
      entry = entry.type ();
    return entry;
  } // typeOf

  /**
   *
   **/
  void forwardEntryCheck ()
  {
    for (Enumeration e = symbolTable.elements (); e.hasMoreElements ();)
    {
      SymtabEntry entry = (SymtabEntry)e.nextElement ();
      if (entry instanceof ForwardEntry)
        ParseException.forwardEntry (scanner, entry.fullName ());
    }
  } // forwardEntryCheck

  // <46082.03> Revert to "IDL:"-style (i.e., regular) repository ID.
  /*
  void updateRepositoryIds () {
     for (Enumeration e = symbolTable.elements(); e.hasMoreElements();) {
         SymtabEntry entry = (SymtabEntry) e.nextElement();
         if (entry instanceof ValueEntry)
           ((ValueEntry) entry).calcRepId();
     }
  } // updateRepositoryIds
  */

  ////////////////////
  // Error Handling Methods

  // A syntax error occurred.  Skip until a semicolon is encountered.
  // Ignore semicolons within {...} blocks
  /**
   *
   **/
  private void skipToSemicolon () throws IOException
  {
    while (!token.equals (Token.EOF) && !token.equals (Token.Semicolon))
    {
      if (token.equals (Token.LeftBrace))
        skipToRightBrace();
      try
      {
        match (token.type);
      }
      catch (ParseException exception)
      {
        // The error has already been reported...
      }
    }
    if (token.equals (Token.EOF))
      throw new EOFException ();
    try
    {
      match (Token.Semicolon);
    }
    catch (Exception exception)
    {
    }
  } // skipToSemicolon

  /**
   *
   **/
  private void skipToRightBrace () throws IOException
  {
    boolean firstTime = true;
    while (!token.equals (Token.EOF) && !token.equals (Token.RightBrace))
    {
      if (firstTime)
        firstTime = false;
      else if (token.equals (Token.LeftBrace))
        skipToRightBrace ();
      try
      {
        match (token.type);
      }
      catch (ParseException exception)
      {
        // The error has already been reported...
      }
    }
    if (token.equals (Token.EOF))
      throw new EOFException();
  } // skipToRightBrace

  // Error Handling Methods
  ////////////////////

  // <d56351> In CORBA 2.3, an IDL file provides a new scope for Repository IDs.
  // The following methods provide a means for other classes in the framework
  // to manage this scoping (see Preprocessor and Scanner).

  // public static int nPush = 0;
  // public static int nPop = 0;

  /**
   *
   **/
  public static void enteringInclude ()
  {
    repIDStack.push (new IDLID ());
  } // enteringInclude

  /**
   *
   **/
  public static void exitingInclude ()
  {
    repIDStack.pop ();
  } // exitingInclude


  public static final String unknownNamePrefix = "uN__";

       static Hashtable   symbolTable;
              Hashtable   lcSymbolTable  = new Hashtable ();
       static Hashtable   overrideNames;
              Vector      emitList       = new Vector ();
              boolean     emitAll;
  // <f46082.46.01>
              boolean     cppModule;
  // <d62023>
              boolean     noWarn;
              Scanner     scanner;
  // <f46082.40> No longer necessary due to new valueElement() algorithm.
  //          Stack       tokenStack     = new Stack();
              Hashtable   symbols;
              Vector      macros         = new Vector ();
              Vector      paths;

  // Only needed for the pragma directive
              SymtabEntry currentModule  = null;

  // <d56351> Static field necessary to allow Scanner access to enterind/exiting
  // Include() methods. Must reset in Compile class, too!
  //          Stack       repIDStack     = new Stack ();
       static Stack       repIDStack     = new Stack ();

  // Dynamic variable key used for forward type lists.
  // A struct or union X entry may have this attached,
  // which always contains a List<SymtabEntry>.
  // The elements are entries E such that E.type() == X.
  // This list must be resolved in pigeonhole when the
  // type is finally defined.  This is similar to
  // ForwardEntry.replaceForwardDecl.
  private static int ftlKey = SymtabEntry.getVariableKey() ;

              int         sequence       = 0;
              Vector      includes;
              Vector      includeEntries;

  // Only needed in primaryExpr.  Set in Preprocessor.booleanConstExpr.
              boolean     parsingConditionalExpr = false;

              Token         token;
              ModuleEntry   topLevelModule;
  private     Preprocessor  prep;
  private     boolean       verbose;
              SymtabFactory stFactory;
              ExprFactory   exprFactory;
  private     String[]      keywords;
  // <f46082.51> Remove -stateful feature.
  //private     boolean       parseStateful = false;

  // Circular buffer containing most recent tokens, including the current token.
  private     TokenBuffer tokenHistory = new TokenBuffer ();
  protected   float       corbaLevel; // <f60858.1>
  private     Arguments   arguments;

} // class Parser

Other Java examples (source code examples)

Here is a short list of links related to this Java Parser.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.