blob: 9ba33b398800f3319ccff21163b743447232a99f [file] [log] [blame]
/*
* PUBLIC DOMAIN PCCTS-BASED C++ GRAMMAR (cplusplus.g, stat.g, expr.g)
*
* Authors: Sumana Srinivasan, NeXT Inc.; sumana_srinivasan@next.com
* Terence Parr, Parr Research Corporation; parrt@parr-research.com
* Russell Quong, Purdue University; quong@ecn.purdue.edu
*
* VERSION 1.1
*
* SOFTWARE RIGHTS
*
* This file is a part of the ANTLR-based C++ grammar and is free
* software. We do not reserve any LEGAL rights to its use or
* distribution, but you may NOT claim ownership or authorship of this
* grammar or support code. An individual or company may otherwise do
* whatever they wish with the grammar distributed herewith including the
* incorporation of the grammar or the output generated by ANTLR into
* commerical software. You may redistribute in source or binary form
* without payment of royalties to us as long as this header remains
* in all source distributions.
*
* We encourage users to develop parsers/tools using this grammar.
* In return, we ask that credit is given to us for developing this
* grammar. By "credit", we mean that if you incorporate our grammar or
* the generated code into one of your programs (commercial product,
* research project, or otherwise) that you acknowledge this fact in the
* documentation, research report, etc.... In addition, you should say nice
* things about us at every opportunity.
*
* As long as these guidelines are kept, we expect to continue enhancing
* this grammar. Feel free to send us enhancements, fixes, bug reports,
* suggestions, or general words of encouragement at parrt@parr-research.com.
*
* NeXT Computer Inc.
* 900 Chesapeake Dr.
* Redwood City, CA 94555
* 12/02/1994
*
* Restructured for public consumption by Terence Parr late February, 1995.
*
* DISCLAIMER: we make no guarantees that this grammar works, makes sense,
* or can be used to do anything useful.
*/
/*
* 2001-2003 Version 2.0 September 2003
*
* Some modifications were made to this file to support a project by
* Jianguo Zuo and David Wigg at
* The Centre for Systems and Software Engineering
* South Bank University
* London, UK.
* wiggjd@bcs.ac.uk
* blackse@lsbu.ac.uk
*
* These C++ functions are required to support the correct functioning of
* the CPP_parser.g definition of the C++ language.
*/
/* 2003-2004 Version 3.0 July 2004
* Modified by David Wigg at London South Bank University for CPP_parser.g
*/
/* 2004-1005 Version 3.1 November 2005
* Modified by David Wigg at London South Bank University for CPP_parser.g
*
* See MyReadMe.txt for further information
*
* This file is best viewed in courier font with tabs set to 4 spaces
*/
extern "C" {
#ifndef WIN32
#include <unistd.h>
#endif
}
#include <iostream>
#include <stdio.h>
#include <string.h>
#include "../CPPParser/CPPParser.hpp"
extern int
statementTrace; // Used to control selected tracing at statement level
// for testing and program verification purposes
// Shorthand for a string of (qualifiedItemIs()==xxx||...)
int CPPParser::qualifiedItemIsOneOf(
QualifiedItem qiFlags, // Ored combination of flags
int lookahead_offset) {
QualifiedItem qi = qualifiedItemIs(lookahead_offset);
return (qi & qiFlags) != 0;
}
// This is an important function, but will be replaced with
// an enhanced predicate in the future, once predicates
// and/or predicate guards can contain loops.
//
// Scan past the ::T::B:: to see what lies beyond.
// Return qiType if the qualified item can pose as type name.
// Note that T::T is NOT a type; it is a constructor. Also,
// class T { ... T...} yields the enclosed T as a ctor. This
// is probably a type as I separate out the constructor defs/decls,
// I want it consistent with T::T.
//
// In the below examples, I use A,B,T and example types, and
// a,b as example ids.
// In the below examples, any A or B may be a
// qualified template, i.e., A<...>
//
// T::T outside of class T yields qiCtor.
// T<...>::T outside of class T yields qiCtor.
// T inside of class T {...} yields qiCtor.
// T, ::T, A::T outside of class T yields qiType.
// a, ::a, A::B::a yields qiId
// a::b yields qiInvalid
// ::operator, operator, A::B::operator yield qiOPerator
// A::*, A::B::* yield qiPtrMember
// ::*, * yields qiInvalid
// ::~T, ~T, A::~T yield qiDtor
// ~a, ~A::a, A::~T::, ~T:: yield qiInvalid
CPPParser::QualifiedItem CPPParser::qualifiedItemIs(int lookahead_offset) {
int offset = lookahead_offset + 1;
int final_type_idx = 0;
// Skip leading "::"
if (LT(offset)->getType() == SCOPE) {
offset++;
}
// Skip sequences of T:: or T<...>::
// DW 11/02/05 Note that LT(offset)->getType() is not a "type" but a type of
// token, eg. ID
// printf("support.cpp qualifiedItemIs while reached offset %d %s type %d
// isType %d, isClass %d, guessing %d\n",
// offset,(LT(offset)->getText()).data(),LT(offset)->getType(),isTypeName((LT(offset)->getText()).data()),isClassName((LT(offset)->getText()).data()),inputState->guessing);
while (LT(offset)->getType() == ID &&
isTypeName((LT(offset)->getText()).data())) { // If this type is the
// same as the last
// type, then ctor
if (final_type_idx != 0 &&
strcmp((LT(final_type_idx)->getText()).data(),
(LT(offset)->getText()).data()) == 0) { // Like T::T
// As an extra check, do not allow T::T::
if (LT(offset + 1)->getType() == SCOPE) { // printf("support.cpp
// qualifiedItemIs qiInvalid
// returned\n");
return qiInvalid;
} else { // printf("support.cpp qualifiedItemIs qiCtor_1 returned %s %s
// %s \n",
// enclosingClass,(LT(lookahead_offset+1)->getText()).data(),
//(LT(final_type_idx)->getText()).data());
return qiCtor;
}
}
// Record this as the most recent type seen in the series
final_type_idx = offset;
// Skip this token
offset++;
// Skip over any template qualifiers <...>
// I believe that "T<..." cannot be anything valid but a template
if (LT(offset)->getType() == LESSTHAN) {
if (!skipTemplateQualifiers(offset)) { // printf("support.cpp
// qualifiedItemIs qiInvalid_2
// returned\n");
return qiInvalid;
}
// printf("support.cpp qualifiedItemIs template skipped, offset
// %d\n",offset);
// offset has been updated to token following <...>
}
// Skip any "::" and keep going
if (LT(offset)->getType() == SCOPE) {
offset++;
}
// Otherwise series terminated -- last ID in the sequence was a type
else {
// Return ctor if last type is in containing class
// We already checked for T::T inside loop
if (strcmp(enclosingClass, (LT(final_type_idx)->getText()).data()) ==
0) { // Like class T T()
// printf("support.cpp qualifiedItemIs qiCtor_2 returned %s %s %s\n",
// enclosingClass,(LT(lookahead_offset+1)->getText()).data(),
// (LT(final_type_idx)->getText()).data());
return qiCtor;
} else { // printf("support.cpp qualifiedItemIs qiType returned\n");
return qiType;
}
}
}
// LT(offset) is not an ID, or it is an ID but not a typename.
// printf("support.cpp qualifiedItemIs second switch reached with type
// %d\n",LT(offset)->getType());
switch (LT(offset)->getType()) {
case ID:
// ID but not a typename
// Do not allow id::
if (LT(offset + 1)->getType() == SCOPE) {
// printf("support.cpp qualifiedItemIs qiInvalid_3 returned\n");
return qiInvalid;
}
if (strcmp(enclosingClass, (LT(offset)->getText()).data()) ==
0) { // Like class T T()
// printf("support.cpp qualifiedItemIs qiCtor_3 returned
// %s\n",enclosingClass);
return qiCtor;
} else {
if (isTypeName((LT(offset)->getText()).data())) {
return qiType;
} else {
// printf("support.cpp qualifiedItemIs qiVar returned\n");
return qiVar; // DW 19/03/04 was qiVar Could be function, qiFun?
}
}
case TILDE:
// check for dtor
if (LT(offset + 1)->getType() == ID &&
isTypeName((LT(offset + 1)->getText()).data()) &&
LT(offset + 2)->getType() != SCOPE) { // Like ~B or A::B::~B
// Also (incorrectly?) matches ::~A.
// printf("support.cpp qualifiedItemIs qiDtor returned\n");
return qiDtor;
} else { // ~a or ~A::a is qiInvalid
// printf("support.cpp qualifiedItemIs qiInvalid_4 returned\n");
return qiInvalid;
}
break;
case STAR:
// Like A::*
// Do not allow * or ::*
if (final_type_idx == 0) { // Haven't seen a type yet
// printf("support.cpp qualifiedItemIs qiInvalid_5 returned\n");
return qiInvalid;
} else { // printf("support.cpp qualifiedItemIs qiPtrMember returned\n");
return qiPtrMember;
}
case OPERATOR:
// Like A::operator, ::operator, or operator
// printf("support.cpp qualifiedItemIs qiOperator returned\n");
return qiOperator;
default:
// Something that neither starts with :: or ID, or
// a :: not followed by ID, operator, ~, or *
// printf("support.cpp qualifiedItemIs qiInvalid_6 returned\n");
return qiInvalid;
}
}
// Skip over <...>. This correctly handles nested <> and (), e.g:
// <T>
// < (i>3) >
// < T2<...> >
// but not
// < i>3 >
//
// On input, kInOut is the index of the "<"
// On output, if the return is true, then
// kInOut is the index of the token after ">"
// else
// kInOut is unchanged
int CPPParser::skipTemplateQualifiers(int &kInOut) { // Start after "<"
int offset = kInOut + 1;
while (LT(offset)->getType() != GREATERTHAN) // scan to end of <...>
{
switch (LT(offset)->getType()) {
case EOF:
return 0;
case LESSTHAN:
if (!skipTemplateQualifiers(offset)) {
return 0;
}
break;
case LPAREN:
if (!skipNestedParens(offset)) {
return 0;
}
break;
default:
offset++; // skip everything else
break;
}
if (offset > MaxTemplateTokenScan) {
return 0;
}
}
// Update output argument to point past ">"
kInOut = offset + 1;
return 1;
}
// Skip over (...). This correctly handles nested (), e.g:
// (i>3, (i>5))
//
// On input, kInOut is the index of the "("
// On output, if the return is true, then
// kInOut is the index of the token after ")"
// else
// kInOut is unchanged
int CPPParser::skipNestedParens(int &kInOut) { // Start after "("
int offset = kInOut + 1;
while (LT(offset)->getType() != RPAREN) // scan to end of (...)
{
switch (LT(offset)->getType()) {
case EOF:
return 0;
case LPAREN:
if (!skipNestedParens(offset)) {
return 0;
}
break;
default:
offset++; // skip everything else
break;
}
if (offset > MaxTemplateTokenScan) {
return 0;
}
}
// Update output argument to point past ")"
kInOut = offset + 1;
return 1;
}
// Return true if "::blah" or "foo::bar<args>::..." found.
int CPPParser::scopedItem(int k) {
// printf("support.cpp scopedItem k %d\n",k);
return (LT(k)->getType() == SCOPE ||
(LT(k)->getType() == ID && !finalQualifier(k)));
}
// Return true if ID<...> or ID is last item in qualified item list.
// Return false if LT(k) is not an ID.
// ID must be a type to check for ID<...>,
// or else we would get confused by "i<3"
int CPPParser::finalQualifier(int k) {
if (LT(k)->getType() == ID) {
if (isTypeName((LT(k)->getText()).data()) &&
LT(k + 1)->getType() == LESSTHAN) { // Starts with "T<". Skip <...>
k++;
skipTemplateQualifiers(k);
} else { // skip ID;
k++;
}
return (LT(k)->getType() != SCOPE);
} else { // not an ID
return 0;
}
}
/*
* Return true if 's' can pose as a type name
*/
int CPPParser::isTypeName(
const char *s) { // printf("isTypeName entered with %s\n",s);
// To look for any type name only
return 1;
/*
CPPSymbol *cs = ( CPPSymbol * ) symbols->lookup( s,CPPSymbol::otTypename );
if ( cs==NULL )
{
printf("support.cpp isTypeName %s not found\n",s);
return 0;
}
// This should now be redundant
if ( cs->getType()==CPPSymbol::otTypedef||
cs->getType()==CPPSymbol::otEnum||
cs->getType()==CPPSymbol::otClass||
cs->getType()==CPPSymbol::otStruct||
cs->getType()==CPPSymbol::otUnion )
{
return 1;
}
return 0;
*/
}
/*
* Return true if 's' is a class name (or a struct which is a class
* with all members public).
*/
int CPPParser::isClassName(const char *s) {
return 1;
/*
// To look for any type name omly
CPPSymbol *cs = ( CPPSymbol * ) symbols->lookup( s,CPPSymbol::otTypename );
if ( cs==NULL )
{
printf("support.cpp isClassName %s not found\n",s);
return 0;
}
if ( cs->getType()==CPPSymbol::otClass||
cs->getType()==CPPSymbol::otStruct||
cs->getType()==CPPSymbol::otUnion )
{
return 1;
}
return 0;
*/
}
void CPPParser::beginDeclaration() {}
void CPPParser::endDeclaration() {}
void CPPParser::beginFunctionDefinition() { functionDefinition = 1; }
void CPPParser::endFunctionDefinition() {
// Remove parameter scope
symbols->dumpScope(stdout); // Diagnostic - See CPPDictionary.hpp
// printf("endFunctionDefinition remove parameter
// scope(%d):\n",symbols->getCurrentScopeIndex());
symbols->removeScope(); // Remove symbols stored in current scope
symbols->restoreScope(); // Reduce currentScope (higher level)
// printf("endFunctionDefinition restoreScope() now
// %d\n",symbols->getCurrentScopeIndex());
functionDefinition = 0;
}
void CPPParser::beginConstructorDefinition() { functionDefinition = 1; }
void CPPParser::endConstructorDefinition() {
symbols->dumpScope(stdout); // Diagnostic - See CPPDictionary.hpp
symbols->removeScope(); // Remove symbols stored in current scope
symbols->restoreScope(); // Reduce currentScope (higher level)
// printf("endConstructorDefinition restoreScope() now
// %d\n",symbols->getCurrentScopeIndex());
functionDefinition = 0;
}
void CPPParser::beginConstructorDeclaration(const char *ctor) {}
void CPPParser::endConstructorDeclaration() {}
void CPPParser::beginDestructorDefinition() { functionDefinition = 1; }
void CPPParser::endDestructorDefinition() {
symbols->dumpScope(stdout); // Diagnostic - See CPPDictionary.hpp
symbols->removeScope(); // Remove symbols stored in current scope
symbols->restoreScope(); // Reduce currentScope (higher level)
// printf("endDestructorDefinition restoreScope() now
// %d\n",symbols->getCurrentScopeIndex());
functionDefinition = 0;
}
void CPPParser::beginDestructorDeclaration(const char *dtor) {}
void CPPParser::endDestructorDeclaration() {}
void CPPParser::beginParameterDeclaration() {}
void CPPParser::beginFieldDeclaration() {}
void CPPParser::declarationSpecifier(bool td, bool fd, StorageClass sc,
TypeQualifier tq, TypeSpecifier ts,
FunctionSpecifier fs) {
// printf("support.cpp declarationSpecifier td %d, fd %d, sc %d, tq %d, ts %d,
// fs %d\n",
// td,fd,sc,tq,ts,fs);
_td = td; // For typedef
_fd = fd; // For friend
_sc = sc;
_tq = tq;
_ts = ts;
_fs = fs;
}
/* Symbols from declarators are added to the symbol table here.
* The symbol is added to external scope or whatever the current scope is, in
* the symbol table.
* See list of object types below.
*/
void CPPParser::declaratorID(const char *id, QualifiedItem qi) {
// printf("declaratorID entered for %s\n",id);
CPPSymbol *c;
// printf("support.cpp declaratorID line %d %s found, _ts = %d, _td = %d, qi =
// %d\n",
// LT(1)->getLine(),id,_ts,_td,qi);
if (qi == qiType || qi == qiNamespace) // Check for type declaration
{
c = new CPPSymbol(id, CPPSymbol::otTypedef);
if (c == NULL) panic("can't alloc CPPSymbol");
symbols->defineInScope(id, c, externalScope);
if (statementTrace >= 2) {
printf(
"%d support.cpp declaratorID declare %s in external scope 1, "
"ObjectType %d\n",
LT(1)->getLine(), id, c->getType());
}
// DW 04/08/03 Scoping not fully implemented
// Typedefs all recorded in 'external' scope and therefor never removed
} else if (qi == qiFun) // Check for function declaration
{
c = new CPPSymbol(id, CPPSymbol::otFunction);
if (c == NULL) panic("can't alloc CPPSymbol");
symbols->define(id, c); // Add to current scope
if (statementTrace >= 2) {
printf(
"%d support.cpp declaratorID declare %s in current scope %d, "
"ObjectType %d\n",
LT(1)->getLine(), id, symbols->getCurrentScopeIndex(), c->getType());
}
} else {
if (qi != qiVar) {
fprintf(
stderr,
"%d support.cpp declaratorID warning qi (%d) not qiVar (%d) for %s\n",
LT(1)->getLine(), qi, qiVar, id);
}
c = new CPPSymbol(id, CPPSymbol::otVariable);
if (c == NULL) panic("can't alloc CPPSymbol");
symbols->define(id, c); // Add to current scope
if (statementTrace >= 2) {
printf(
"%d support.cpp declaratorID declare %s in current scope %d, "
"ObjectType %d\n",
LT(1)->getLine(), id, symbols->getCurrentScopeIndex(), c->getType());
}
}
}
/* These are the object types
0 = otInvalid
1 = otFunction
2 = otVariable
3 = otTypedef Note. 3-7 are type names
4 = otStruct Note. 4, 5 & 7 are class names
5 = otUnion
6 = otEnum
7 = otClass
10 = otTypename
11 = otNonTypename
*/
void CPPParser::declaratorArray() {}
void CPPParser::declaratorParameterList(int def) {
symbols->saveScope(); // Advance currentScope (lower level)
// printf("declaratorParameterList saveScope() now
// %d\n",symbols->getCurrentScopeIndex());
}
void CPPParser::declaratorEndParameterList(int def) {
if (!def) {
symbols->dumpScope(stdout); // Diagnostic - See CPPDictionary.hpp
symbols->removeScope(); // Remove symbols stored in current scope
symbols->restoreScope(); // Reduce currentScope (higher level)
// printf("declaratorEndParameterList restoreScope() now
// %d\n",symbols->getCurrentScopeIndex());
}
}
void CPPParser::functionParameterList() {
symbols->saveScope(); // Advance currentScope (lower level)
// printf("functionParameterList saveScope() now
// %d\n",symbols->getCurrentScopeIndex());
// DW 25/3/97 change flag from function to parameter list
functionDefinition = 2;
}
void CPPParser::functionEndParameterList(int def) {
// If this parameter list is not in a definition then this
if (!def) {
symbols->dumpScope(stdout); // Diagnostic - See CPPDictionary.hpp
symbols->removeScope(); // Remove symbols stored in current scope
symbols->restoreScope(); // Reduce currentScope (higher level)
// printf("functionEndParameterList restoreScope() now
// %d\n",symbols->getCurrentScopeIndex());
} else {
// Change flag from parameter list to body of definition
functionDefinition = 3;
}
// Otherwise endFunctionDefinition removes the parameters from scope
}
void CPPParser::enterNewLocalScope() {
symbols->saveScope(); // Advance currentScope (lower level)
// printf("enterNewLocalScope saveScope() now
// %d\n",symbols->getCurrentScopeIndex());
}
void CPPParser::exitLocalScope() {
symbols->dumpScope(stdout); // Diagnostic - See CPPDictionary.hpp
symbols->removeScope(); // Remove symbols stored in current scope
symbols->restoreScope(); // Reduce currentScope (higher level)
// printf("exitLocalScope restoreScope() now
// %d\n",symbols->getCurrentScopeIndex());
}
void CPPParser::enterExternalScope() { // Scope has been initialised to 1 in
// CPPParser.init() in CPPParser.hpp
functionDefinition = 0;
}
void CPPParser::exitExternalScope() {
symbols->dumpScope(stdout); // Diagnostic - See CPPDictionary.hpp
symbols->removeScope(); // Remove symbols stored in current scope s/b 2
symbols->restoreScope(); // Reduce currentScope (higher level)
symbols->dumpScope(stdout); // Diagnostic - See CPPDictionary.hpp
symbols->removeScope(); // Remove symbols stored in current scope s/b 1
symbols->restoreScope(); // Reduce currentScope (higher level)
if (symbols->getCurrentScopeIndex() == 0) {
if (statementTrace >= 2) {
fprintf(stdout, "\nSupport exitExternalScope, scope now %d as required\n",
symbols->getCurrentScopeIndex());
}
} else {
fprintf(stderr, "\nSupport exitExternalScope, scope now %d, should be 0\n",
symbols->getCurrentScopeIndex());
}
}
void CPPParser::classForwardDeclaration(TypeSpecifier ts, FunctionSpecifier fs,
const char *tag)
// classForwardDeclaration(const char *tag, TypeSpecifier ts, FunctionSpecifier
// fs)
{
CPPSymbol *c = NULL;
// if already in symbol table as a class, don't add
// of course, this is incorrect as you can rename
// classes by entering a new scope, but our limited
// example basically keeps all types globally visible.
if (symbols->lookup(tag, CPPSymbol::otTypename) != NULL) {
CPPSymbol *cs = (CPPSymbol *)symbols->lookup(tag, CPPSymbol::otTypename);
if (statementTrace >= 2) {
printf(
"%d support.cpp classForwardDeclaration %s already stored in "
"dictionary, ObjectType %d\n",
LT(1)->getLine(), tag, cs->getType());
}
return;
}
switch (ts) {
case tsSTRUCT:
c = new CPPSymbol(tag, CPPSymbol::otStruct);
break;
case tsUNION:
c = new CPPSymbol(tag, CPPSymbol::otUnion);
break;
case tsCLASS:
c = new CPPSymbol(tag, CPPSymbol::otClass);
break;
}
if (c == NULL) panic("can't alloc CPPSymbol");
symbols->defineInScope(tag, c, externalScope);
if (statementTrace >= 2) {
printf(
"%d support.cpp classForwardDeclaration declare %s in external scope, "
"ObjectType %d\n",
LT(1)->getLine(), tag, c->getType());
}
// If it's a friend class forward decl, put in global scope also.
// DW 04/07/03 No need if already in external scope. See above.
// if ( ds==dsFRIEND )
// {
// CPPSymbol *ext_c = new CPPSymbol(tag, CPPSymbol::otClass);
// if ( ext_c==NULL ) panic("can't alloc CPPSymbol");
// if ( symbols->getCurrentScopeIndex()!=externalScope ) // DW 04/07/03
// Not sure this test is really necessary
// {
// printf("classForwardDeclaration
// defineInScope(externalScope)\n");
// symbols->defineInScope(tag, ext_c, externalScope);
// }
// }
}
void CPPParser::exitNamespaceScope() {}
void CPPParser::beginClassDefinition(TypeSpecifier ts, const char *tag) {
CPPSymbol *c = NULL;
// if already in symbol table as a class, don't add
// of course, this is incorrect as you can rename
// classes by entering a new scope, but our limited
// example basically keeps all types globally visible.
if (symbols->lookup(tag, CPPSymbol::otTypename) != NULL) {
symbols->saveScope(); // still have to use scope to collect members
// printf("support.cpp beginClassDefinition_1 saveScope() now
// %d\n",symbols->getCurrentScopeIndex());
if (statementTrace >= 2) {
printf(
"%d support.cpp beginClassDefinition classname %s already in "
"dictionary\n",
LT(1)->getLine(), tag);
}
return;
}
switch (ts) {
case tsSTRUCT:
c = new CPPSymbol(tag, CPPSymbol::otStruct);
break;
case tsUNION:
c = new CPPSymbol(tag, CPPSymbol::otUnion);
break;
case tsCLASS:
c = new CPPSymbol(tag, CPPSymbol::otClass);
break;
}
if (c == NULL) panic("can't alloc CPPSymbol");
symbols->defineInScope(tag, c, externalScope);
if (statementTrace >= 2) {
printf(
"%d support.cpp beginClassDefinition define %s in external scope (1), "
"ObjectType %d\n",
LT(1)->getLine(), tag, c->getType());
}
strcat(qualifierPrefix, tag);
strcat(qualifierPrefix, "::");
// add all member type symbols into the global scope (not correct, but
// will work for most code).
// This symbol lives until the end of the file
symbols->saveScope(); // Advance currentScope (lower level)
}
void CPPParser::endClassDefinition() {
symbols->dumpScope(stdout); // Diagnostic - See CPPDictionary.hpp
symbols->removeScope(); // Remove symbols stored in current scope
symbols->restoreScope(); // Reduce currentScope (higher level)
// remove final T:: from A::B::C::T::
// upon backing out of last class, qualifierPrefix is set to ""
char *p = &(qualifierPrefix[strlen(qualifierPrefix) - 3]);
while (p > &(qualifierPrefix[0]) && *p != ':') {
p--;
}
if (p > &(qualifierPrefix[0])) p++;
*p = '\0';
}
void CPPParser::enumElement(const char *e) {}
void CPPParser::beginEnumDefinition(
const char *e) { // DW 26/3/97 Set flag for new class
// add all enum tags into the global scope (not correct, but
// will work for most code).
// This symbol lives until the end of the file
CPPSymbol *c = new CPPSymbol(e, CPPSymbol::otEnum);
symbols->defineInScope(e, c, externalScope);
if (statementTrace >= 2) {
printf(
"%d support.cpp beginEnumDefinition %s define in external scope, "
"ObjectType %d\n",
LT(1)->getLine(), e, c->getType());
}
}
void CPPParser::endEnumDefinition() {}
void CPPParser::templateTypeParameter(const char *t) {
// DW 11/06/03 Symbol saved in templateParameterScope (0)
// as a temporary measure until scope is implemented fully
// This symbol lives until the end of the file
CPPSymbol *e = new CPPSymbol(t, CPPSymbol::otTypedef); // DW 22/03/05
// CPPSymbol *e = new CPPSymbol(t, CPPSymbol::otClass);
if (e == NULL) panic("can't alloc CPPSymbol");
// symbols->defineInScope(t, e, templateParameterScope); // DW 22/03/05
// DW 10/08/05 Replaced to make template parameters local
symbols->defineInScope(t, e, externalScope);
// symbols->define(t,e); // Save template parameter in local scope
if (statementTrace >= 2) {
// printf("%d support.cpp templateTypeParameter declare %s in
// parameter
// scope (0), ObjectType %d\n",
printf(
"%d support.cpp templateTypeParameter declare %s in external scope "
"(1), ObjectType %d\n",
LT(1)->getLine(), t, e->getType());
}
// printf("%d support.cpp templateTypeParameter declare %s in
// current
// scope %d, ObjectType %d\n",
// LT(1)->getLine(),t,symbols->getCurrentScopeIndex(),e->getType());
}
void CPPParser::beginTemplateDeclaration() {
symbols->saveScope(); // Advance currentScope (lower level)
// printf("Support beginTemplateDeclaration, Scope now
// %d\n",symbols->getCurrentScopeIndex());
}
void CPPParser::endTemplateDeclaration() {
symbols->dumpScope(stdout); // Diagnostic - See CPPDictionary.hpp
symbols->removeScope(); // Remove symbols stored in current scope
symbols->restoreScope(); // Reduce currentScope (higher level)
// printf("Support endTemplateDeclaration, Scope now
// %d\n",symbols->getCurrentScopeIndex());
}
void CPPParser::beginTemplateDefinition() {}
void CPPParser::endTemplateDefinition() {}
void CPPParser::beginTemplateParameterList() {
// DW 26/05/03 To scope template parameters
symbols->saveScope(); // Advance currentScope (lower level)
}
void CPPParser::endTemplateParameterList() {
// DW 26/05/03 To end scope template parameters
symbols->restoreScope(); // Reduce currentScope (higher level)
}
void CPPParser::exceptionBeginHandler() {}
void CPPParser::exceptionEndHandler() { // remove parm elements from the
// handler scope
symbols->dumpScope(stdout); // Diagnostic - See CPPDictionary.hpp
symbols->removeScope(); // Remove symbols stored in current scope
symbols->restoreScope(); // Reduce currentScope (higher level)
}
void CPPParser::end_of_stmt() {
#ifdef MYCODE
myCode_end_of_stmt();
#endif // MYCODE
}
void CPPParser::panic(const char *err) {
fprintf(stdout, "CPPParser: %s\n", err);
_exit(-1);
}
/* DW 090204 leave out of support.cpp for the time being
// want to see how supplied routine in LLkParser works first
void CPPParser::
tracein(char *r)
{
// testing
printf("support tracein entered\n");
getchar();
if ( !doTracing ) return;
for (int i=1; i<=traceIndentLevel; i++)
fprintf(stdout, " ");
traceIndentLevel++;
fprintf(stdout, "enter %s('%s %s')%s\n",
r,
(LT(1)->getText()).data(),
(LT(2)->getText()).data(),
inputState->guessing?" [guessing]":""
);
fflush(stdout);
}
void CPPParser::
traceout(char *r)
{
if ( !doTracing ) return;
traceIndentLevel--;
for (int i=1; i<=traceIndentLevel; i++)
fprintf(stdout, " ");
fprintf(stdout, "exit %s('%s %s')%s\n",
r,
(LT(1)->getText()).data(),
(LT(2)->getText()).data(),
inputState->guessing?" [guessing]":""
);
fflush(stdout);
}
*/
// Functions which may be overridden by MyCode subclass
void CPPParser::myCode_pre_processing(int argc, char *argv[]) {}
void CPPParser::myCode_post_processing() {}
void CPPParser::myCode_end_of_stmt() {}
void CPPParser::myCode_function_direct_declarator(const char *id) {
// printf("support myCode_function_direct_declarator entered for %s\n",id);
}