1

I am creating a symbol table class to be used with an analyzer/parser I've written for a compilers course. Everything has been going well so far, but I cannot get these class files to compile on my school's Linux machines using g++:

SymbolTable.h:

// Multiple definition guard
#ifndef SYMBOLTABLE_H
#defineSYMBOLTABLE_H

// Includes
#include <iostream>
#include <string>
#include "stddef.h"

// Namespace
using namespace std;

// Class for storing all encountered symbols while parsing
class SymbolTable
{
public:
    SymbolTable();                          // Constructor
    ~SymbolTable();                         // Destructor
    void scopeUp();                         // Increases current scope
    void scopeDown();                       // Decreases current scope
    void addSymbol(string symbolTitle);     // Adds a symbol to table
    void addSymboll(string symbolTitle);    // g++ doesn't think this exists

private:
    int scope;

    // Structure for storing symbols.  Currently only contains title from
    // identifier.  Will expand upon / derive from this structure after
    // initial testing.  Symbols are stored in a simple stack, with the
    // container class responsible for keeping track of the top Symbol.
    struct Symbol
    {
        Symbol* previousSymbol;
        string title;
    };

    // Structure for tracking current scope.  All symbols will belong to a
    // particular scope, and are stored in a simple stack to maintain
    // declaration order.  When the scope changes, currentScope will point to
    // a new scope structure with its own list of symbols.  Scopes themselves
    // are also stored in a stack, where currentScope points to the top.
    struct Scope
    {
        Scope* previousScope;
        Symbol* currentSymbol;
    };
    Scope* currentScope;

    // This is a recursive display function used for printing all of the items
    // in a given scope.  This is called from within the scopeDown function, so
    // that the final list of items for that scope can be logged before it is
    // destroyed
    void displayScope(Symbol* displaySymbol);
};

#endif // Multiple definition guard

SymbolTable.cpp:

// Multiple definition guard
#ifndef SYMBOLTABLE_CPP
#define SYMBOLTABLE_CPP

// Includes
#include "SymbolTable.h"


// Constructor
SymbolTable::SymbolTable()
{
    scope = 0;
    currentScope = NULL;
    return;
}

// Destructor
SymbolTable::~SymbolTable()
{
    Scope* nextScopeToDelete = NULL;
    Symbol* nextSymbolToDelete = NULL;

    // While there are scopes left to delete from the table...
    while(currentScope != NULL)
    {
        // Save the pointer to the next scope on the stack
        nextScopeToDelete = currentScope->previousScope;

        // While there are symbols left to delete from the scope...
        while(currentScope->currentSymbol != NULL)
        {
            // Save the pointer to the next symbol on the stack
            nextSymbolToDelete = currentScope->currentSymbol->previousSymbol;

            // For debugging
            cout << "deleting symbol " << currentScope->currentSymbol->title << endl;

            // Delete the current top symbol
            delete currentScope->currentSymbol;

            // Move on to the next one
            currentScope->currentSymbol = nextSymbolToDelete;
        }

        // For debugging
        cout << "deleting scope " << scope << endl;

        // Delete the current top scope
        delete currentScope;
        scope--;

        // Move on to the next one
        currentScope = nextScopeToDelete;
    }
    return;
}

// This is a recursive display function used for printing all of the items
// in a given scope.  This is called from within the scopeDown function, so
// that the final list of items for that scope can be logged before it is
// destroyed
void SymbolTable::displayScope(Symbol* displaySymbol)
{
    // If we've reached the bottom of the scope stack...
    if(displaySymbol == NULL)
    {
        return; // Nothing to do
    }

    // We haven't reached the bottom of the scope stack
    else
    {
        displaySymbol = displaySymbol->previousSymbol; // Keep going
        displayScope(displaySymbol); // Recursive call
    }

    // Display this symbol after all lower ones have been displayed recursively
    cout << displaySymbol->title << endl;
    return;
}

// A new procedure has caused us to increase scope, so we'll create a new
// scope structure with its own symbol stack
void SymbolTable::scopeUp()
{
    // Generate the new scope structure
    Scope* newScope = new Scope;
    newScope->previousScope = currentScope;
    newScope->currentSymbol = NULL;

    // Notification for debugging
    cout << "ENTERING SCOPE " << scope + 1 << endl;
    cout << "--------------------------------------------------";
    cout << "-------------------------" << endl;

    // Switch to the new scope
    currentScope = newScope;
    scope++;
    return;
}

// The end of a procedure has caused us to decrement scope, so we'll delete
// the contents of the current one and fall back to the last scope on the stack
void SymbolTable::scopeDown()
{
    // If we're already at the bottom of the stack...
    if(currentScope == 0)
    {
        // Something is very wrong
        cerr << "CANNOT DELETE SCOPE 0!!!!" << endl;
    }
    else
    {
        // Save the pointer to the next scope on the stack
        Scope* previousScope = currentScope->previousScope;
        Symbol* nextSymbolToDelete = NULL;

        // Display the contents of this scope before deleting it (debugging)
        displayScope(currentScope->currentSymbol);

        // While there are still symbols in this scope to delete...
        while(currentScope->currentSymbol != NULL)
        {
            // Save the pointer to the next symbol on the stack
            nextSymbolToDelete = currentScope->currentSymbol->previousSymbol;

            // Delete the current top symbol on the stack
            delete currentScope->currentSymbol;

            // Move on to the next one
            currentScope->currentSymbol = nextSymbolToDelete;
        }

        // Notification for debugging
        cout << "EXITING SCOPE " << scope-- << endl;
        cout << "==================================================";
        cout << "=========================" << endl;

        // Delete the old top scope from the stack
        delete currentScope;

        // Move on to the next one
        currentScope = previousScope;
    }
    return;
}

// Adds a symbol to the table.  Specifically:  adds a symbol to the top of the
// symbol stack in the scope at the top of the scope stack.  This will soon be
// interfacing with more expansive data structure, but currently just stores
// the title of the symbol as detected in the parser.
void SymbolTable::addSymbol(string symbolTitle)
{
    Symbol* newSymbol = new Symbol;
    newSymbol->previousSymbol = currentScope->currentSymbol;
    newSymbol->title = symbolTitle;
    currentScope->currentSymbol = newSymbol;
    return;
}

// g++ doesn't think this was declared in the class
void SymbolTable::addSymboll(string symbolTitle)
{
    Symbol* newSymbol = new Symbol;
    newSymbol->previousSymbol = currentScope->currentSymbol;
    newSymbol->title = symbolTitle;
    currentScope->currentSymbol = newSymbol;
    return;
}

#endif // Multiple definition guard

Errors:

[...]$ touch SymbolTable.h SymbolTable.cpp
[...]$ g++ -c SymbolTable.cpp
SymbolTable.cpp:67: error: no âvoid SymbolTable::displayScope(SymbolTable::Symbol*)â member function declared in class âSymbolTableâ
SymbolTable.cpp:167: error: no âvoid SymbolTable::addSymboll(std::string)â member function declared in class âSymbolTableâ
[...]$

As far as I can tell, it seemed to think my displayScope function was not declared in the class header file. In order to investigate this further, I added a new function called addSymboll which was identical to the existing addSymbol function. However, it's giving me the same error message for this new function. In fact, after a couple of hours spent trying to compile this, it seems that I cannot add any new functions to this class at all. I am at a complete loss as to what could be causing this. Any ideas would be appreciated!

4

2 回答 2

3

G++ also tells me:

error: invalid preprocessing directive #defineSYMBOLTABLE_H

Add a space after #define:

#defineSYMBOLTABLE_H

于 2012-10-29T07:31:13.673 回答
1

I had previously only been deleting the object (.o) files when cleaning. What I ended up having to do here was delete the .gch files as well. There was nothing wrong with the actual code or g++ (despite the old version running on the school servers).

于 2012-10-29T08:55:31.663 回答