Support.cc
Go to the documentation of this file.
00001 /*
00002  * PUBLIC DOMAIN PCCTS-BASED C++ GRAMMAR (cplusplus.g, stat.g, expr.g)
00003  *
00004  * Authors: Sumana Srinivasan, NeXT Inc.;            sumana_srinivasan@next.com
00005  *          Terence Parr, Parr Research Corporation; parrt@parr-research.com
00006  *          Russell Quong, Purdue University;        quong@ecn.purdue.edu
00007  *
00008  * VERSION 1.1
00009  *
00010  * SOFTWARE RIGHTS
00011  *
00012  * This file is a part of the ANTLR-based C++ grammar and is free
00013  * software.  We do not reserve any LEGAL rights to its use or
00014  * distribution, but you may NOT claim ownership or authorship of this
00015  * grammar or support code.  An individual or company may otherwise do
00016  * whatever they wish with the grammar distributed herewith including the
00017  * incorporation of the grammar or the output generated by ANTLR into
00018  * commerical software.  You may redistribute in source or binary form
00019  * without payment of royalties to us as long as this header remains
00020  * in all source distributions.
00021  *
00022  * We encourage users to develop parsers/tools using this grammar.
00023  * In return, we ask that credit is given to us for developing this
00024  * grammar.  By "credit", we mean that if you incorporate our grammar or
00025  * the generated code into one of your programs (commercial product,
00026  * research project, or otherwise) that you acknowledge this fact in the
00027  * documentation, research report, etc....  In addition, you should say nice
00028  * things about us at every opportunity.
00029  *
00030  * As long as these guidelines are kept, we expect to continue enhancing
00031  * this grammar.  Feel free to send us enhancements, fixes, bug reports,
00032  * suggestions, or general words of encouragement at parrt@parr-research.com.
00033  * 
00034  * NeXT Computer Inc.
00035  * 900 Chesapeake Dr.
00036  * Redwood City, CA 94555
00037  * 12/02/1994
00038  * 
00039  * Restructured for public consumption by Terence Parr late February, 1995.
00040  *
00041  * DISCLAIMER: we make no guarantees that this grammar works, makes sense,
00042  *             or can be used to do anything useful.
00043  */
00044 /*
00045  * 2001-2003 Version 2.0 September 2003
00046  *
00047  * Some modifications were made to this file to support a project by
00048  * Jianguo Zuo and David Wigg at
00049  * The Centre for Systems and Software Engineering
00050  * South Bank University
00051  * London, UK.
00052  * wiggjd@bcs.ac.uk
00053  * blackse@lsbu.ac.uk
00054  */
00055 /* 2003-2004 Version 3.0 July 2004
00056  * Modified by David Wigg at London South Bank University for CPP_parser.g
00057  *
00058  * See MyReadMe.txt for further information
00059  *
00060  * This file is best viewed in courier font with tabs set to 4 spaces
00061  */
00062 
00063 #include <iostream>
00064 #include "CPPParser.hpp"
00065 #include "CPPSymbol.hh"
00066 
00067 using namespace std;
00068 
00069 void CPPParser::init()
00070 {
00071     //antlrTrace(false);        // This is a dynamic trace facility for use with -traceParser etc.
00072     // It requires modification in LLkParser.cpp and LLkParser.hpp
00073     //  otherwise it should be commented out (see MyReadMe.txt)
00074     // true shows antlr trace (can be set and reset during parsing)
00075     // false stops showing antlr trace 
00076     // Provided the parser is always generated with -traceParser this
00077     //  facility allows trace output to be turned on or off by changing
00078     //  the setting here from false to true or vice versa and then
00079     //  recompiling and linking CPPParser only thus avoiding the need
00080     //  to use antlr.Tool to re-generate the lexer and parser again. 
00081 
00082     // Creates a dictionary to hold symbols with 4001 buckets, 200 scopes and 800,000 characters
00083     // These can be changed to suit the size of program(s) being parsed
00084     symbols = new CPPDictionary(4001, 200, 800000);
00085 
00086     symbols->saveScope();       // Advance currentScope from 0 to 1
00087     externalScope = symbols->getCurrentScopeIndex();    // Set external scope to 1
00088 
00089     // Global flags to allow for nested declarations
00090     _td = false;                // For typedef
00091     _sc = scInvalid;    // For StorageClass
00092     _tq = tqInvalid;    // For TypeQualifier
00093     _ts = tsInvalid;    // For TypeSpecifier
00094     _ds = dsInvalid;    // For DeclSpecifier
00095 
00096     functionDefinition = 0;
00097     assign_stmt_RHS_found = 0;
00098     in_parameter_list = false;
00099     in_return = false;
00100 }
00101 
00102 CPPParser::~CPPParser()
00103 {
00104     delete symbols;
00105 }
00106 
00107 /*
00108  * Return true if 's' can pose as a type name
00109  */
00110 int CPPParser::isTypeName(const std::string& s)
00111 {
00112     CPPSymbol *cs = (CPPSymbol *) symbols->lookup(s);
00113 
00114     if (cs==NULL)
00115     {
00116         //printf("support.cpp isTypeName %s not found\n",s);
00117         return 0;
00118     }
00119 
00120     if (cs->getType()==CPPSymbol::otTypedef||
00121             cs->getType()==CPPSymbol::otEnum||
00122             cs->getType()==CPPSymbol::otClass||
00123             cs->getType()==CPPSymbol::otStruct||
00124             cs->getType()==CPPSymbol::otUnion)
00125     {
00126 
00127         // DW 13/06/03 Check that scope level found is not greater 
00128         //  than the current scope i.e. lower level
00129         //              if (cs->this_scope > symbols->getCurrentScopeIndex() )
00130         //                      {
00131         //                      return 0;
00132         //                      }
00133         //
00134         //              if (cs->getInScope()==false)
00135         //                      {
00136         //                      return 1;
00137         //                      }
00138         return 1;
00139     }
00140 
00141     return 0;
00142 }
00143 
00144 void CPPParser::beginDeclaration() { }
00145 
00146 void CPPParser::endDeclaration() { }
00147 
00148 void CPPParser::beginFunctionDefinition()
00149 {
00150     functionDefinition = 1;
00151 }
00152 
00153 void CPPParser::endFunctionDefinition()
00154 {
00155     // Remove parameter scope
00156     symbols->dumpScope(stdout);
00157     //fprintf(stdout, "endFunctionDefinition remove parameter scope(%d):\n",symbols->getCurrentScopeIndex());
00158     symbols->removeScope();
00159     symbols->restoreScope();
00160     //printf("endFunctionDefinition restoreScope() now %d\n",symbols->getCurrentScopeIndex());
00161     functionDefinition = 0;
00162 }
00163 
00164 void CPPParser::beginParameterDeclaration()
00165 { }
00166 
00167 void CPPParser::beginFieldDeclaration()
00168 { }
00169 
00170 void CPPParser::declarationSpecifier(bool td, StorageClass sc, TypeQualifier tq,
00171         TypeSpecifier ts, DeclSpecifier ds)
00172 {
00173     //printf("support.cpp declarationSpecifier td %d, fd %d, sc %d, tq, %d, ts %d, ds %d, qi %d\n",
00174     //  td,fd,sc,tq,ts,ds,qi);
00175     _td = td;   // For typedef
00176     _sc = sc;
00177     _tq = tq;
00178     _ts = ts;
00179     _ds = ds;
00180     //  _qi = qi;
00181 }
00182 
00183 /* Symbols from declarators are added to the symbol table here. 
00184  * The symbol is added to whatever the current scope is in the symbol table. 
00185  * See list of object types below.
00186  */
00187 void CPPParser::declaratorID(const std::string& id, QualifiedItem qi)
00188 {
00189     CPPSymbol *c;
00190     if (qi==qiType || _td)      // Check for type declaration
00191     {
00192         if (!(qi==qiType && _td))
00193         {
00194             std::cerr << LT(1) -> getLine()
00195                 << "support.cpp declaratorID warning qi " << qi << ", _td " << _td 
00196                 << " inconsistent for " << id << std::endl;
00197         }
00198 
00199         c = new CPPSymbol(id, CPPSymbol::otTypedef);
00200         symbols->defineInScope(id, c, externalScope);
00201     }
00202     else if (qi==qiFun) // For function declaration
00203     {
00204         c = new CPPSymbol(id, CPPSymbol::otFunction);
00205         symbols->define(id, c); // Add to current scope
00206     }
00207     else           
00208     {
00209         if (qi!=qiVar)
00210         {
00211             std::cerr << LT(1) -> getLine()
00212                 << "support.cpp declaratorID warning qi " << qi << "not qiVar _td " << qiVar
00213                 << " inconsistent for " << id << std::endl;
00214         }
00215 
00216         c = new CPPSymbol(id, CPPSymbol::otVariable);   // Used to leave otInvalid DW 02/07/03 Think this should be otVariable
00217         symbols->define(id, c); // Add to current scope
00218     }
00219 }
00220 
00221 void CPPParser::enterNamespace(std::string const& name) { }
00222 void CPPParser::exitNamespace() { }
00223 
00224 /* These are the object types
00225    0 = otInvalid
00226    1 = otFunction
00227    2 = otVariable
00228    3 = otTypedef        Note. 3-7 are type names
00229    4 = otStruct Note. 4, 5 & 7 are class names
00230    5 = otUnion
00231    6 = otEnum
00232    7 = otClass
00233    8 = otEnumElement
00234    */
00235 
00236 void CPPParser::declaratorArray(int size) { }
00237 
00238 void CPPParser::declaratorParameterList(int def)
00239 {
00240     symbols->saveScope();
00241     //printf("declaratorParameterList saveScope() now %d\n",symbols->getCurrentScopeIndex());
00242 }
00243 
00244 void CPPParser::declaratorEndParameterList(int def)
00245 {
00246     if (!def)
00247     {
00248         symbols->dumpScope(stdout);
00249         symbols->removeScope();
00250         symbols->restoreScope();
00251         //printf("declaratorEndParameterList restoreScope() now %d\n",symbols->getCurrentScopeIndex());
00252     }
00253 }
00254 
00255 void CPPParser::functionParameterList()
00256 {
00257     symbols->saveScope();
00258     //printf("functionParameterList saveScope() now %d\n",symbols->getCurrentScopeIndex());
00259     // DW 25/3/97 change flag from function to parameter list
00260     functionDefinition = 2;
00261 }
00262 
00263 void CPPParser::functionEndParameterList(int def)
00264 {
00265     // If this parameter list is not in a definition then this
00266     if ( !def)
00267     {
00268         symbols->dumpScope(stdout);
00269         symbols->removeScope();
00270         symbols->restoreScope();
00271         //printf("functionEndParameterList restoreScope() now %d\n",symbols->getCurrentScopeIndex());
00272     }
00273     else
00274     {
00275         // Change flag from parameter list to body of definition
00276         functionDefinition = 3;   
00277     }
00278     /* Otherwise endFunctionDefinition removes the parameters from scope */
00279 }
00280 
00281 void CPPParser::enterNewLocalScope()
00282 {
00283     symbols->saveScope();
00284     //printf("enterNewLocalScope saveScope() now %d\n",symbols->getCurrentScopeIndex());
00285 }
00286 
00287 void CPPParser::exitLocalScope()
00288 {
00289     symbols->dumpScope(stdout);
00290     symbols->removeScope();
00291     symbols->restoreScope();
00292     //printf("exitLocalScope restoreScope() now %d\n",symbols->getCurrentScopeIndex());
00293 }
00294 
00295 void CPPParser::enterExternalScope()
00296 {// Scope has been initialised to 1 in CPPParser.init() in CPPParser.hpp
00297     // DW 25/3/97 initialise
00298     functionDefinition = 0;
00299     //classDefinition = 0;      DW 19/03/04 not used anywhere
00300 }
00301 
00302 void CPPParser::exitExternalScope()
00303 {
00304     symbols->dumpScope(stdout);
00305     symbols->removeScope();             // This just removes the symbols stored in the current scope
00306     symbols->restoreScope();    // This just reduces the current scope by 1
00307     //if (symbols->getCurrentScopeIndex()==0)
00308     //    printf("\nSupport exitExternalScope, scope now %d\n",symbols->getCurrentScopeIndex());
00309     //else
00310     //    printf("\nSupport exitExternalScope, scope now %d, should be 0\n",symbols->getCurrentScopeIndex());
00311 }
00312 
00313 void CPPParser::classForwardDeclaration(TypeSpecifier ts, DeclSpecifier ds, const std::string& tag)
00314 {
00315     CPPSymbol *c = NULL;
00316 
00317     // if already in symbol table as a class, don't add
00318     // of course, this is incorrect as you can rename
00319     // classes by entering a new scope, but our limited
00320     // example basically keeps all types globally visible.
00321     if ( symbols->lookup(tag)!=NULL )
00322         return;
00323 
00324     switch (ts)
00325     {
00326         case tsSTRUCT :
00327             c = new CPPSymbol(tag, CPPSymbol::otStruct);
00328             break;
00329         case tsUNION :
00330             c = new CPPSymbol(tag, CPPSymbol::otUnion);
00331             break;
00332         case tsCLASS :
00333             c = new CPPSymbol(tag, CPPSymbol::otClass);
00334             break;
00335     }
00336 
00337     symbols->defineInScope(tag, c, externalScope);
00338 }
00339 
00340 void CPPParser::beginClassDefinition(TypeSpecifier ts,const std::string& tag)
00341 {
00342     CPPSymbol *c;
00343 
00344     // if already in symbol table as a class, don't add
00345     // of course, this is incorrect as you can rename
00346     // classes by entering a new scope, but our limited
00347     // example basically keeps all types globally visible.
00348     if (symbols->lookup(tag) != NULL)
00349     {
00350         symbols->saveScope();   // still have to use scope to collect members
00351         //printf("support.cpp beginClassDefinition_1 saveScope() now %d\n",symbols->getCurrentScopeIndex());
00352         return;
00353     }
00354 
00355     switch (ts)
00356     {
00357         case tsSTRUCT:
00358             c = new CPPSymbol(tag, CPPSymbol::otStruct);
00359             break;
00360         case tsUNION:
00361             c = new CPPSymbol(tag, CPPSymbol::otUnion);
00362             break;
00363         case tsCLASS:
00364             c = new CPPSymbol(tag, CPPSymbol::otClass);
00365             break;
00366         default:
00367             throw std::runtime_error("unexpected TypeSpecifier in CPPParser::beginClassDefinition");
00368     }
00369     symbols->defineInScope(tag, c, externalScope);
00370     qualifierPrefix += tag;
00371     qualifierPrefix += "::";
00372 
00373     // add all member type symbols into the global scope (not correct, but
00374     // will work for most code).
00375     // This symbol lives until the end of the file
00376 
00377     symbols->saveScope();   // use the scope to collect list of fields
00378 }
00379 
00380 void CPPParser::endClassDefinition()
00381 {
00382     symbols->dumpScope(stdout);
00383     symbols->removeScope();
00384     symbols->restoreScope();
00385     // remove final T:: from A::B::C::T::
00386     // upon backing out of last class, qualifierPrefix is set to ""
00387     size_t index = qualifierPrefix.rfind("::");
00388     if (index == std::string::npos)
00389         return;
00390     qualifierPrefix.resize(index);
00391 }
00392 
00393 void CPPParser::enumElement(const std::string& e, bool has_value, int value)
00394 { }
00395 
00396 void CPPParser::beginEnumDefinition(const std::string& e)
00397 {// DW 26/3/97 Set flag for new class
00398 
00399     // add all enum tags into the global scope (not correct, but
00400     // will work for most code).
00401     // This symbol lives until the end of the file
00402     CPPSymbol *c = new CPPSymbol(e, CPPSymbol::otEnum);
00403     symbols->defineInScope(e, c, externalScope);
00404 }
00405 
00406 void CPPParser::endEnumDefinition() {   }
00407 
00408 void CPPParser::foundSimpleType(const std::list<std::string>& full_type) { }
00409 
00410 void CPPParser::end_of_stmt() { }                    
00411 
00412 


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Mon Sep 14 2015 15:08:18