--- old/src/java.corba/share/classes/com/sun/tools/corba/se/idl/Preprocessor.java 2018-01-30 20:24:46.000000000 -0500 +++ /dev/null 2018-01-30 20:24:46.000000000 -0500 @@ -1,1431 +0,0 @@ -/* - * Copyright (c) 1999, 2000, 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: -// -D57110 Allow ID pragma directive to be applied to modules and update -// feature in accordance to CORBA 2.3. -// -D59165 Enable escaped identifiers when processing pragmas. -// -f60858.1 Support -corba option, level = 2.2: Accept identifiers that -// collide with keywords, in letter but not case, and issue a warning. -// -d62023 support -noWarn option; suppress inappropriate warnings when -// parsing IBM-specific pragmas (#meta abstract). - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.math.BigInteger; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Stack; -import java.util.Vector; - -import com.sun.tools.corba.se.idl.RepositoryID; - -import com.sun.tools.corba.se.idl.constExpr.*; - -/** - * This class should be extended if new pragmas are desired. If the - * preprocessor encounters a pragma name which it doesn't recognize - * (anything other than ID, prefix, or version), it calls the method - * otherPragmas. This is the only method which need be overridden. - * The Preprocessor base class has a number of utility-like methods - * which can be used by the overridden otherPragmas method. - **/ -public class Preprocessor -{ - /** - * Public zero-argument constructor. - **/ - Preprocessor () - { - } // ctor - - /** - * - **/ - void init (Parser p) - { - parser = p; - symbols = p.symbols; - macros = p.macros; - } // init - - /** - * - **/ - protected Object clone () - { - return new Preprocessor (); - } // clone - - /** - * - **/ - Token process (Token t) throws IOException, ParseException - { - token = t; - scanner = parser.scanner; - // Deactivate escaped identifier processing in Scanner while - // preprocessing. - //scanner.underscoreOK = true; - scanner.escapedOK = false; - try - { - switch (token.type) - { - case Token.Include: - include (); - break; - case Token.If: - ifClause (); - break; - case Token.Ifdef: - ifdef (false); - break; - case Token.Ifndef: - ifdef (true); - break; - case Token.Else: - if (alreadyProcessedABranch.empty ()) - throw ParseException.elseNoIf (scanner); - else if (((Boolean)alreadyProcessedABranch.peek ()).booleanValue ()) - skipToEndif (); - else - { - alreadyProcessedABranch.pop (); - alreadyProcessedABranch.push (new Boolean (true)); - token = scanner.getToken (); - } - break; - case Token.Elif: - elif (); - break; - case Token.Endif: - if (alreadyProcessedABranch.empty ()) - throw ParseException.endNoIf (scanner); - else - { - alreadyProcessedABranch.pop (); - token = scanner.getToken (); - break; - } - case Token.Define: - define (); - break; - case Token.Undef: - undefine (); - break; - case Token.Pragma: - pragma (); - break; - case Token.Unknown: - if (!parser.noWarn) - ParseException.warning (scanner, Util.getMessage ("Preprocessor.unknown", token.name)); - case Token.Error: - case Token.Line: - case Token.Null: - // ignore - default: - scanner.skipLineComment (); - token = scanner.getToken (); - } - } - catch (IOException e) - { - // Underscore may now precede any identifier, so underscoreOK - // is vestigal. The Preprocessor must reset escapedOK so that Scanner - // will process escaped identifiers according to specification. - //scanner.underscoreOK = false; - scanner.escapedOK = true; - throw e; - } - catch (ParseException e) - { - // See above. - //scanner.underscoreOK = false; - scanner.escapedOK = true; - throw e; - } - // See above. - //scanner.underscoreOK = false; - scanner.escapedOK = true; - return token; - } // process - - /** - * - **/ - private void include () throws IOException, ParseException - { - match (Token.Include); - IncludeEntry include = parser.stFactory.includeEntry (parser.currentModule); - include.sourceFile (scanner.fileEntry ()); - scanner.fileEntry ().addInclude (include); - if (token.type == Token.StringLiteral) - include2 (include); - else if (token.type == Token.LessThan) - include3 (include); - else - { - int[] expected = {Token.StringLiteral, Token.LessThan}; - throw ParseException.syntaxError (scanner, expected, token.type); - } - if (parser.currentModule instanceof ModuleEntry) - ((ModuleEntry)parser.currentModule).addContained (include); - else if (parser.currentModule instanceof InterfaceEntry) - ((InterfaceEntry)parser.currentModule).addContained (include); - } // include - - /** - * - **/ - private void include2 (IncludeEntry include) throws IOException, ParseException - { - include.name ('"' + token.name + '"'); - include4 (include, token.name); - match (Token.StringLiteral); - } // include2 - - /** - * - **/ - private void include3 (IncludeEntry include) throws IOException, ParseException - { - if (token.type != Token.LessThan) - // match will throw an exception - match (Token.LessThan); - else - { - try - { - String includeFile = getUntil ('>'); - token = scanner.getToken (); - include.name ('<' + includeFile + '>'); - include4 (include, includeFile); - match (Token.GreaterThan); - } - catch (IOException e) - { - throw ParseException.syntaxError (scanner, ">", "EOF"); - } - } - } // include3 - - /** - * - **/ - private void include4 (IncludeEntry include, String filename) throws IOException, ParseException - { - try - { - // If the #include is at the global scope, it is treated as - // an import statement. If it is within some other scope, it - // is treated as a normal #include. - boolean includeIsImport = parser.currentModule == parser.topLevelModule; - //daz - include.absFilename (Util.getAbsolutePath (filename, parser.paths)); - scanner.scanIncludedFile (include, getFilename (filename), includeIsImport); - } - catch (IOException e) - { - ParseException.generic (scanner, e.toString ()); - } - } // include4 - - /** - * - **/ - private void define () throws IOException, ParseException - { - match (Token.Define); - if (token.equals (Token.Identifier)) - { - String symbol = scanner.getStringToEOL (); - symbols.put (token.name, symbol.trim ()); - match (Token.Identifier); - } - else if (token.equals (Token.MacroIdentifier)) - { - symbols.put (token.name, '(' + scanner.getStringToEOL () . trim ()); - macros.addElement (token.name); - match (Token.MacroIdentifier); - } - else - throw ParseException.syntaxError (scanner, Token.Identifier, token.type); - } // define - - /** - * - **/ - private void undefine () throws IOException, ParseException - { - match (Token.Undef); - if (token.equals (Token.Identifier)) - { - symbols.remove (token.name); - macros.removeElement (token.name); - match (Token.Identifier); - } - else - throw ParseException.syntaxError (scanner, Token.Identifier, token.type); - } // undefine - - /** - * - **/ - private void ifClause () throws IOException, ParseException - { - match (Token.If); - constExpr (); - } // ifClause - - /** - * - **/ - private void constExpr () throws IOException, ParseException - { - SymtabEntry dummyEntry = new SymtabEntry (parser.currentModule); - dummyEntry.container (parser.currentModule); - parser.parsingConditionalExpr = true; - Expression boolExpr = booleanConstExpr (dummyEntry); - parser.parsingConditionalExpr = false; - boolean expr; - if (boolExpr.value () instanceof Boolean) - expr = ((Boolean)boolExpr.value ()).booleanValue (); - else - expr = ((Number)boolExpr.value ()).longValue () != 0; - alreadyProcessedABranch.push (new Boolean (expr)); - if (!expr) - skipToEndiforElse (); - } // constExpr - - /** - * - **/ - Expression booleanConstExpr (SymtabEntry entry) throws IOException, ParseException - { - Expression expr = orExpr (null, entry); - try - { - expr.evaluate (); - } - catch (EvaluationException e) - { - ParseException.evaluationError (scanner, e.toString ()); - } - return expr; - } // booleanConstExpr - - /** - * - **/ - private Expression orExpr (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.DoubleBar)) - { - match (token.type); - BooleanOr or = parser.exprFactory.booleanOr (e, null); - or.rep (e.rep () + " || "); - return orExpr (or, entry); - } - else - return e; - } // orExpr - - /** - * - **/ - private Expression andExpr (Expression e, SymtabEntry entry) throws IOException, ParseException - { - if (e == null) - e = notExpr (entry); - else - { - BinaryExpr b = (BinaryExpr)e; - b.right (notExpr (entry)); - e.rep (e.rep () + b.right ().rep ()); - } - if (token.equals (Token.DoubleAmpersand)) - { - match (token.type); - BooleanAnd and = parser.exprFactory.booleanAnd (e, null); - and.rep (e.rep () + " && "); - return andExpr (and, entry); - } - else - return e; - } // andExpr - - /** - * - **/ - private Expression notExpr (/*boolean alreadySawExclamation, */SymtabEntry entry) throws IOException, ParseException - { - Expression e; - if (token.equals (Token.Exclamation)) - { - match (Token.Exclamation); - e = parser.exprFactory.booleanNot (definedExpr (entry)); - e.rep ("!" + ((BooleanNot)e).operand ().rep ()); - } - else - e = definedExpr (entry); - return e; - } // notExpr - - /** - * - **/ - private Expression definedExpr (SymtabEntry entry) throws IOException, ParseException - { - if (token.equals (Token.Identifier) && token.name.equals ("defined")) - match (Token.Identifier); - return equalityExpr (null, entry); - } // definedExpr - - /** - * - **/ - private Expression equalityExpr (Expression e, SymtabEntry entry) throws IOException, ParseException - { - if (e == null) - { - parser.token = token; // Since parser to parse, give it this token - e = parser.constExp (entry); - token = parser.token; // Since parser last parsed, get its token - } - else - { - BinaryExpr b = (BinaryExpr)e; - parser.token = token; // Since parser to parse, give it this token - Expression constExpr = parser.constExp (entry); - token = parser.token; // Since parser last parsed, get its token - b.right (constExpr); - e.rep (e.rep () + b.right ().rep ()); - } - if (token.equals (Token.DoubleEqual)) - { - match (token.type); - Equal eq = parser.exprFactory.equal (e, null); - eq.rep (e.rep () + " == "); - return equalityExpr (eq, entry); - } - else if (token.equals (Token.NotEqual)) - { - match (token.type); - NotEqual n = parser.exprFactory.notEqual (e, null); - n.rep (e.rep () + " != "); - return equalityExpr (n, entry); - } - else if (token.equals (Token.GreaterThan)) - { - match (token.type); - GreaterThan g = parser.exprFactory.greaterThan (e, null); - g.rep (e.rep () + " > "); - return equalityExpr (g, entry); - } - else if (token.equals (Token.GreaterEqual)) - { - match (token.type); - GreaterEqual g = parser.exprFactory.greaterEqual (e, null); - g.rep (e.rep () + " >= "); - return equalityExpr (g, entry); - } - else if (token.equals (Token.LessThan)) - { - match (token.type); - LessThan l = parser.exprFactory.lessThan (e, null); - l.rep (e.rep () + " < "); - return equalityExpr (l, entry); - } - else if (token.equals (Token.LessEqual)) - { - match (token.type); - LessEqual l = parser.exprFactory.lessEqual (e, null); - l.rep (e.rep () + " <= "); - return equalityExpr (l, entry); - } - else - return e; - } // equalityExpr - - /** - * - **/ - Expression primaryExpr (SymtabEntry entry) throws IOException, ParseException - { - Expression primary = null; - switch (token.type) - { - case Token.Identifier: - // If an identifier gets this far, it means that no - // preprocessor variable was defined with that name. - // Generate a FALSE boolean expr. - //daz primary = parser.exprFactory.terminal ("0", new Long (0)); - primary = parser.exprFactory.terminal ("0", BigInteger.valueOf (0)); - token = scanner.getToken (); - break; - case Token.BooleanLiteral: - case Token.CharacterLiteral: - case Token.IntegerLiteral: - case Token.FloatingPointLiteral: - case Token.StringLiteral: - //daz primary = parser.literal (); - primary = parser.literal (entry); - token = parser.token; - break; - case Token.LeftParen: - match (Token.LeftParen); - primary = booleanConstExpr (entry); - match (Token.RightParen); - primary.rep ('(' + primary.rep () + ')'); - break; - default: - int[] expected = {Token.Literal, Token.LeftParen}; - throw ParseException.syntaxError (scanner, expected, token.type); - } - return primary; - } // primaryExpr - - /** - * - **/ - private void ifDefine (boolean inParens, boolean not) throws IOException, ParseException - { - if (token.equals (Token.Identifier)) - if ((not && symbols.containsKey (token.name)) || (!not && !symbols.containsKey (token.name))) - { - alreadyProcessedABranch.push (new Boolean (false)); - skipToEndiforElse (); - } - else - { - alreadyProcessedABranch.push (new Boolean (true)); - match (Token.Identifier); - if (inParens) - match (Token.RightParen); - } - else - throw ParseException.syntaxError (scanner, Token.Identifier, token.type); - } // ifDefine - - /** - * - **/ - private void ifdef (boolean not) throws IOException, ParseException - { - if (not) - match (Token.Ifndef); - else - match (Token.Ifdef); - if (token.equals (Token.Identifier)) - if ((not && symbols.containsKey (token.name)) || (!not && !symbols.containsKey (token.name))) - { - alreadyProcessedABranch.push (new Boolean (false)); - skipToEndiforElse (); - } - else - { - alreadyProcessedABranch.push (new Boolean (true)); - match (Token.Identifier); - } - else - throw ParseException.syntaxError (scanner, Token.Identifier, token.type); - } // ifdef - - /** - * - **/ - private void elif () throws IOException, ParseException - { - if (alreadyProcessedABranch.empty ()) - throw ParseException.elseNoIf (scanner); - else if (((Boolean)alreadyProcessedABranch.peek ()).booleanValue ()) - skipToEndif (); - else - { - match (Token.Elif); - constExpr (); - } - } // elif - - /** - * - **/ - private void skipToEndiforElse () throws IOException, ParseException - { - while (!token.equals (Token.Endif) && !token.equals (Token.Else) && !token.equals (Token.Elif)) - { - if (token.equals (Token.Ifdef) || token.equals (Token.Ifndef)) - { - alreadyProcessedABranch.push (new Boolean (true)); - skipToEndif (); - } - else - token = scanner.skipUntil ('#'); - } - process (token); - } // skipToEndiforElse - - /** - * - **/ - private void skipToEndif () throws IOException, ParseException - { - while (!token.equals (Token.Endif)) - { - token = scanner.skipUntil ('#'); - if (token.equals (Token.Ifdef) || token.equals (Token.Ifndef)) - { - alreadyProcessedABranch.push (new Boolean (true)); - skipToEndif (); - } - } - alreadyProcessedABranch.pop (); - match (Token.Endif); - } // skipToEndif - - /////////////// - // For Pragma - - /** - * - **/ - private void pragma () throws IOException, ParseException - { - match (Token.Pragma); - String pragmaType = token.name; - - // Enable escaped identifiers while processing pragma internals. - // Don't enable until scanning pragma name! - scanner.escapedOK = true; - match (Token.Identifier); - - // Add pragma entry to container - PragmaEntry pragmaEntry = parser.stFactory.pragmaEntry (parser.currentModule); - pragmaEntry.name (pragmaType); - pragmaEntry.sourceFile (scanner.fileEntry ()); - pragmaEntry.data (scanner.currentLine ()); - if (parser.currentModule instanceof ModuleEntry) - ((ModuleEntry)parser.currentModule).addContained (pragmaEntry); - else if (parser.currentModule instanceof InterfaceEntry) - ((InterfaceEntry)parser.currentModule).addContained (pragmaEntry); - - // If the token was an identifier, then pragmaType WILL be non-null. - if (pragmaType.equals ("ID")) - idPragma (); - else if (pragmaType.equals ("prefix")) - prefixPragma (); - else if (pragmaType.equals ("version")) - versionPragma (); - - // we are adding extensions to the Sun's idlj compiler to - // handle correct code generation for local Objects, where - // the OMG is taking a long time to formalize stuff. Good - // example of this is poa.idl. Two proprietory pragmas - // sun_local and sun_localservant are defined. sun_local - // generates only Holder and Helper classes, where read - // and write methods throw marshal exceptions. sun_localservant - // is to generate Helper, Holder, and only Skel with _invoke - // throwing an exception, since it does not make sense for - // local objects. - - else if (pragmaType.equals ("sun_local")) - localPragma(); - else if (pragmaType.equals ("sun_localservant")) - localServantPragma(); - else - { - otherPragmas (pragmaType, tokenToString ()); - token = scanner.getToken (); - } - - scanner.escapedOK = false; // Disable escaped identifiers. - } // pragma - - // Pragma ID can be appiled to modules and it is an error to - // name a type in more than one ID pragma directive. - - private Vector PragmaIDs = new Vector (); - - private void localPragma () throws IOException, ParseException - { - // Before I can use a parser method, I must make sure it has the current token. - parser.token = token; - // this makes sense only for interfaces, if specified for modules, - // parser should throw an error - SymtabEntry anErrorOccurred = new SymtabEntry (); - SymtabEntry entry = parser.scopedName (parser.currentModule, anErrorOccurred); - // Was the indicated type found in the symbol table? - if (entry == anErrorOccurred) - { - System.out.println("Error occured "); - // Don't have to generate an error, scopedName already has. - scanner.skipLineComment (); - token = scanner.getToken (); - } - else - { - // by this time we have already parsed the ModuleName and the - // pragma type, therefore setInterfaceType - if (entry instanceof InterfaceEntry) { - InterfaceEntry ent = (InterfaceEntry) entry; - ent.setInterfaceType (InterfaceEntry.LOCAL_SIGNATURE_ONLY); - } - token = parser.token; - String string = token.name; - match (Token.StringLiteral); - // for non-interfaces it doesn't make sense, so just ignore it - } - } // localPragma - - private void localServantPragma () throws IOException, ParseException - { - // Before I can use a parser method, I must make sure it has the current token. - parser.token = token; - // this makes sense only for interfaces, if specified for modules, - // parser should throw an error - SymtabEntry anErrorOccurred = new SymtabEntry (); - SymtabEntry entry = parser.scopedName (parser.currentModule, anErrorOccurred); - - // Was the indicated type found in the symbol table? - if (entry == anErrorOccurred) - { - // Don't have to generate an error, scopedName already has. - scanner.skipLineComment (); - token = scanner.getToken (); - System.out.println("Error occured "); - } - else - { - // by this time we have already parsed the ModuleName and the - // pragma type, therefore setInterfaceType - if (entry instanceof InterfaceEntry) { - InterfaceEntry ent = (InterfaceEntry) entry; - ent.setInterfaceType (InterfaceEntry.LOCALSERVANT); - } - token = parser.token; - String string = token.name; - match (Token.StringLiteral); - // for non-interfaces it doesn't make sense, so just ignore it - } - } // localServantPragma - - - /** - * - **/ - private void idPragma () throws IOException, ParseException - { - // Before I can use a parser method, I must make sure it has the current token. - parser.token = token; - - // This flag will relax the restriction that the scopedNamed - // in this ID pragma directive cannot resolve to a module. - parser.isModuleLegalType (true); - SymtabEntry anErrorOccurred = new SymtabEntry (); - SymtabEntry entry = parser.scopedName (parser.currentModule, anErrorOccurred); - parser.isModuleLegalType (false); // <57110> - - // Was the indicated type found in the symbol table? - if (entry == anErrorOccurred) - { - // Don't have to generate an error, scopedName already has. - scanner.skipLineComment (); - token = scanner.getToken (); - } - // - //else if (PragmaIDs.contains (entry)) - //{ - // ParseException.badRepIDAlreadyAssigned (scanner, entry.name ()); - // scanner.skipLineComment (); - // token = scanner.getToken (); - //} - else - { - token = parser.token; - String string = token.name; - // Do not match token until after raise exceptions, otherwise - // incorrect messages will be emitted! - if (PragmaIDs.contains (entry)) // - { - ParseException.badRepIDAlreadyAssigned (scanner, entry.name ()); - } - else if (!RepositoryID.hasValidForm (string)) // - { - ParseException.badRepIDForm (scanner, string); - } - else - { - entry.repositoryID (new RepositoryID (string)); - PragmaIDs.addElement (entry); // - } - match (Token.StringLiteral); - } - } // idPragma - - /** - * - **/ - private void prefixPragma () throws IOException, ParseException - { - String string = token.name; - match (Token.StringLiteral); - ((IDLID)parser.repIDStack.peek ()).prefix (string); - ((IDLID)parser.repIDStack.peek ()).name (""); - } // prefixPragma - - /** - * - **/ - private void versionPragma () throws IOException, ParseException - { - // Before I can use a parser method, I must make sure it has the current token. - parser.token = token; - // This flag will relax the restriction that the scopedNamed - // in this Version pragma directive cannot resolve to a module. - parser.isModuleLegalType (true); - SymtabEntry anErrorOccurred = new SymtabEntry (); - SymtabEntry entry = parser.scopedName (parser.currentModule, anErrorOccurred); - // reset the flag to original value - parser.isModuleLegalType (false); - if (entry == anErrorOccurred) - { - // Don't have to generate an error, scopedName already has. - scanner.skipLineComment (); - token = scanner.getToken (); - } - else - { - token = parser.token; - String string = token.name; - match (Token.FloatingPointLiteral); - if (entry.repositoryID () instanceof IDLID) - ((IDLID)entry.repositoryID ()).version (string); - } - } // versionPragma - - private Vector pragmaHandlers = new Vector (); - - /** - * - **/ - void registerPragma (PragmaHandler handler) - { - pragmaHandlers.addElement (handler); - } // registerPragma - - /** - * - **/ - private void otherPragmas (String pragmaType, String currentToken) throws IOException - { - for (int i = pragmaHandlers.size () - 1; i >= 0; --i) - { - PragmaHandler handler = (PragmaHandler)pragmaHandlers.elementAt (i); - if (handler.process (pragmaType, currentToken)) - break; - } - } // otherPragmas - - /* - * These protected methods are used by extenders, by the code - * which implements otherPragma. - */ - - /** - * Get the current token. - **/ - String currentToken () - { - return tokenToString (); - } // currentToken - - /** - * This method, given an entry name, returns the entry with that name. - * It can take fully or partially qualified names and returns the - * appropriate entry defined within the current scope. If no entry - * exists, null is returned. - **/ - SymtabEntry getEntryForName (String string) - { - boolean partialScope = false; - boolean globalScope = false; - - // Change all ::'s to /'s - if (string.startsWith ("::")) - { - globalScope = true; - string = string.substring (2); - } - int index = string.indexOf ("::"); - while (index >= 0) - { - partialScope = true; - string = string.substring (0, index) + '/' + string.substring (index + 2); - index = string.indexOf ("::"); - } - - // Get the entry for that string - SymtabEntry entry = null; - if (globalScope) - entry = parser.recursiveQualifiedEntry (string); - else if (partialScope) - entry = parser.recursivePQEntry (string, parser.currentModule); - else - entry = parser.unqualifiedEntryWMod (string, parser.currentModule); - return entry; - } // getEntryForName - - /** - * This method returns a string of all of the characters from the - * input file from the current position up to, but not including, - * the end-of-line character(s). - **/ - String getStringToEOL () throws IOException - { - return scanner.getStringToEOL (); - } // getStringToEOL - - /** - * This method returns a string of all of the characters from the - * input file from the current position up to, but not including, - * the given character. It encapsulates parenthesis and quoted strings, - * meaning it does not stop if the given character is found within - * parentheses or quotes. For instance, given the input of - * `start(inside)end', getUntil ('n') will return "start(inside)e" - **/ - String getUntil (char c) throws IOException - { - return scanner.getUntil (c); - } // getUntil - - private boolean lastWasMacroID = false; - - /** - * - **/ - private String tokenToString () - { - if (token.equals (Token.MacroIdentifier)) - { - lastWasMacroID = true; - return token.name; - } - else if (token.equals (Token.Identifier)) - return token.name; - else - return token.toString (); - } // tokenToString - - /** - * This method returns the next token String from the input file. - **/ - String nextToken () throws IOException - { - if (lastWasMacroID) - { - lastWasMacroID = false; - return "("; - } - else - { - token = scanner.getToken (); - return tokenToString (); - } - } // nextToken - - /** - * This method assumes that the current token marks the beginning - * of a scoped name. It then parses the subsequent identifier and - * double colon tokens, builds the scoped name, and finds the symbol - * table entry with that name. - **/ - SymtabEntry scopedName () throws IOException - { - boolean globalScope = false; - boolean partialScope = false; - String name = null; - SymtabEntry entry = null; - try - { - if (token.equals (Token.DoubleColon)) - globalScope = true; - else - { - if (token.equals (Token.Object)) - { - name = "Object"; - match (Token.Object); - } - else if (token.type == Token.ValueBase) - { - name = "ValueBase"; - match (Token.ValueBase); - } - else - { - name = token.name; - match (Token.Identifier); - } - } - while (token.equals (Token.DoubleColon)) - { - match (Token.DoubleColon); - partialScope = true; - if (name != null) - name = name + '/' + token.name; - else - name = token.name; - match (Token.Identifier); - } - if (globalScope) - entry = parser.recursiveQualifiedEntry (name); - else if (partialScope) - entry = parser.recursivePQEntry (name, parser.currentModule); - else - entry = parser.unqualifiedEntryWMod (name, parser.currentModule); - } - catch (ParseException e) - { - entry = null; - } - return entry; - } // scopedName - - /** - * Skip to the end of the line. - **/ - void skipToEOL () throws IOException - { - scanner.skipLineComment (); - } // skipToEOL - - /** - * This method skips the data in the input file until the specified - * character is encountered, then it returns the next token. - **/ - String skipUntil (char c) throws IOException - { - if (!(lastWasMacroID && c == '(')) - token = scanner.skipUntil (c); - return tokenToString (); - } // skipUntil - - /** - * This method displays a Parser Exception complete with line number - * and position information with the given message string. - **/ - void parseException (String message) - { - // Suppress warnings - if (!parser.noWarn) - ParseException.warning (scanner, message); - } // parseException - - // For Pragma - /////////////// - // For macro expansion - - /** - * - **/ - String expandMacro (String macroDef, Token t) throws IOException, ParseException - { - token = t; - // Get the parameter values from the macro 'call' - Vector parmValues = getParmValues (); - - // Get the parameter names from the macro definition - // NOTE: a newline character is appended here so that when - // getStringToEOL is called, it stops scanning at the end - // of this string. - scanner.scanString (macroDef + '\n'); - Vector parmNames = new Vector (); - macro (parmNames); - - if (parmValues.size () < parmNames.size ()) - throw ParseException.syntaxError (scanner, Token.Comma, Token.RightParen); - else if (parmValues.size () > parmNames.size ()) - throw ParseException.syntaxError (scanner, Token.RightParen, Token.Comma); - - macroDef = scanner.getStringToEOL (); - for (int i = 0; i < parmNames.size (); ++i) - macroDef = replaceAll (macroDef, (String)parmNames.elementAt (i), (String)parmValues.elementAt (i)); - return removeDoublePound (macroDef); - } // expandMacro - - // This method is only used by the macro expansion methods. - /** - * - **/ - private void miniMatch (int type) throws ParseException - { - // A normal production would now execute: - // match (type); - // But match reads the next token. I don't want to do that now. - // Just make sure the current token is a 'type'. - if (!token.equals (type)) - throw ParseException.syntaxError (scanner, type, token.type); - } // miniMatch - - /** - * - **/ - private Vector getParmValues () throws IOException, ParseException - { - Vector values = new Vector (); - if (token.equals (Token.Identifier)) - { - match (Token.Identifier); - miniMatch (Token.LeftParen); - } - else if (!token.equals (Token.MacroIdentifier)) - throw ParseException.syntaxError (scanner, Token.Identifier, token.type); - - if (!token.equals (Token.RightParen)) - { - values.addElement (scanner.getUntil (',', ')').trim ()); - token = scanner.getToken (); - macroParmValues (values); - } - return values; - } // getParmValues - - /** - * - **/ - private void macroParmValues (Vector values) throws IOException, ParseException - { - while (!token.equals (Token.RightParen)) - { - miniMatch (Token.Comma); - values.addElement (scanner.getUntil (',', ')').trim ()); - token = scanner.getToken (); - } - } // macroParmValues - - /** - * - **/ - private void macro (Vector parmNames) throws IOException, ParseException - { - match (token.type); - match (Token.LeftParen); - macroParms (parmNames); - miniMatch (Token.RightParen); - } // macro - - /** - * - **/ - private void macroParms (Vector parmNames) throws IOException, ParseException - { - if (!token.equals (Token.RightParen)) - { - parmNames.addElement (token.name); - match (Token.Identifier); - macroParms2 (parmNames); - } - } // macroParms - - /** - * - **/ - private void macroParms2 (Vector parmNames) throws IOException, ParseException - { - while (!token.equals (Token.RightParen)) - { - match (Token.Comma); - parmNames.addElement (token.name); - match (Token.Identifier); - } - } // macroParms2 - - /** - * - **/ - private String replaceAll (String string, String from, String to) - { - int index = 0; - while (index != -1) - { - index = string.indexOf (from, index); - if (index != -1) - { - if (!embedded (string, index, index + from.length ())) - if (index > 0 && string.charAt(index) == '#') - string = string.substring (0, index) + '"' + to + '"' + string.substring (index + from.length ()); - else - string = string.substring (0, index) + to + string.substring (index + from.length ()); - index += to.length (); - } - } - return string; - } // replaceAll - - /** - * - **/ - private boolean embedded (String string, int index, int endIndex) - { - // Don't replace if found substring is not an independent id. - // For example, don't replace "thither".indexOf ("it", 0) - boolean ret = false; - char preCh = index == 0 ? ' ' : string.charAt (index - 1); - char postCh = endIndex >= string.length () - 1 ? ' ' : string.charAt (endIndex); - if ((preCh >= 'a' && preCh <= 'z') || (preCh >= 'A' && preCh <= 'Z')) - ret = true; - else if ((postCh >= 'a' && postCh <= 'z') || (postCh >= 'A' && postCh <= 'Z') || (postCh >= '0' && postCh <= '9') || postCh == '_') - ret = true; - else - ret = inQuotes (string, index); - return ret; - } // embedded - - /** - * - **/ - private boolean inQuotes (String string, int index) - { - int quoteCount = 0; - for (int i = 0; i < index; ++i) - if (string.charAt (i) == '"') ++quoteCount; - // If there are an odd number of quotes before this region, - // then this region is within quotes - return quoteCount % 2 != 0; - } // inQuotes - - /** - * Remove any occurrences of ##. - **/ - private String removeDoublePound (String string) - { - int index = 0; - while (index != -1) - { - index = string.indexOf ("##", index); - if (index != -1) - { - int startSkip = index - 1; - int stopSkip = index + 2; - if (startSkip < 0) - startSkip = 0; - if (stopSkip >= string.length ()) - stopSkip = string.length () - 1; - while (startSkip > 0 && - (string.charAt (startSkip) == ' ' || - string.charAt (startSkip) == '\t')) - --startSkip; - while (stopSkip < string.length () - 1 && - (string.charAt (stopSkip) == ' ' || - string.charAt (stopSkip) == '\t')) - ++stopSkip; - string = string.substring (0, startSkip + 1) + string.substring (stopSkip); - } - } - return string; - } // removeDoublePound - - // For macro expansion - /////////////// - - /** - * - **/ - private String getFilename (String name) throws FileNotFoundException - { - String fullName = null; - File file = new File (name); - if (file.canRead ()) - fullName = name; - else - { - Enumeration pathList = parser.paths.elements (); - while (!file.canRead () && pathList.hasMoreElements ()) - { - fullName = (String)pathList.nextElement () + File.separatorChar + name; - file = new File (fullName); - } - if (!file.canRead ()) - throw new FileNotFoundException (name); - } - return fullName; - } // getFilename - - /** - * - **/ - private void match (int type) throws IOException, ParseException - { - if (!token.equals (type)) - throw ParseException.syntaxError (scanner, type, token.type); - token = scanner.getToken (); - - // Added for convenience, but commented-out because there is - // no reason to issue warnings for tokens scanned during preprocessing. - // See issueTokenWarnings(). - //issueTokenWarnings (); - - //System.out.println ("Preprocessor.match token = " + token.type); - //if (token.equals (Token.Identifier) || token.equals (Token.MacroIdentifier)) - // System.out.println ("Preprocessor.match token name = " + token.name); - - // 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 (expandMacro (string, token)); - token = scanner.getToken (); - } - // else this is just a normal define - else - { - scanner.scanString (string); - token = scanner.getToken (); - } - } - } // match - - // - /** - * Issue warnings about tokens scanned during preprocessing. - **/ - private void issueTokenWarnings () - { - if (parser.noWarn) - return; - - // There are no keywords defined for preprocessing (only directives), so: - // - // 1.) Do not issue warnings for identifiers known to be keywords in - // another level of IDL. - // 2.) Do not issue warnings for identifiers that collide with keywords - // in letter, but not case. - // 3.) Do not issue warnings for deprecated keywords. - // - // Should we warn when a macro identifier replaces a keyword? Hmmm. - - // Deprecated directives? None to date. - //if (token.isDirective () && token.isDeprecated ()) - // ParseException.warning (scanner, Util.getMesage ("Deprecated.directive", token.name)); - } // issueTokenWarnings - - /** - * This method is called when the parser encounters a left curly brace. - * An extender of PragmaHandler may find scope information useful. - * For example, the prefix pragma takes effect as soon as it is - * encountered and stays in effect until the current scope is closed. - * If a similar pragma extension is desired, then the openScope and - * closeScope methods are available for overriding. - * @param entry the symbol table entry whose scope has just been opened. - * Be aware that, since the scope has just been entered, this entry is - * incomplete at this point. - **/ - void openScope (SymtabEntry entry) - { - for (int i = pragmaHandlers.size () - 1; i >= 0; --i) - { - PragmaHandler handler = (PragmaHandler)pragmaHandlers.elementAt (i); - handler.openScope (entry); - } - } // openScope - - /** - * This method is called when the parser encounters a right curly brace. - * An extender of PragmaHandler may find scope information useful. - * For example, the prefix pragma takes effect as soon as it is - * encountered and stays in effect until the current scope is closed. - * If a similar pragma extension is desired, then the openScope and - * closeScope methods are available for overriding. - * @param entry the symbol table entry whose scope has just been closed. - **/ - void closeScope (SymtabEntry entry) - { - for (int i = pragmaHandlers.size () - 1; i >= 0; --i) - { - PragmaHandler handler = (PragmaHandler)pragmaHandlers.elementAt (i); - handler.closeScope (entry); - } - } // closeScope - - private Parser parser; - private Scanner scanner; - private Hashtable symbols; - private Vector macros; - - // The logic associated with this stack is scattered above. - // A concise map of the logic is: - // case #if false, #ifdef false, #ifndef true - // push (false); - // skipToEndifOrElse (); - // case #if true, #ifdef true, #ifndef false - // push (true); - // case #elif - // if (top == true) - // skipToEndif (); - // else if (conditional == true) - // pop (); - // push (true); - // else if (conditional == false) - // skipToEndifOrElse (); - // case #else - // if (top == true) - // skipToEndif (); - // else - // pop (); - // push (true); - // case #endif - // pop (); - private Stack alreadyProcessedABranch = new Stack (); - Token token; - - private static String indent = ""; -}