/* SI 413 Fall 2011 * parsetree.hpp * This is a C++ header file for the ParseTree class. * A ParseTree is recursively defined with a very simple structure. */ #ifndef PARSETREE_HPP #define PARSETREE_HPP #include <fstream> #include <string> #include <vector> using namespace std; #define YYSTYPE ParseTree* class ParseTree { private: string label; vector<ParseTree*> children; /* Adds this node in the tree, and its children to the * .dot file attached to fout. * nodes is a count of the number of nodes already added, * so that names will be unique. */ int addToDot(ofstream& fout, int& nodes) { int root = ++nodes; fout << "\tn" << root << " [label=\"" << label << "\"];" << endl; for (vector<ParseTree*>::iterator iter = children.begin(); iter != children.end(); ++iter) { int child = (*iter)->addToDot(fout,nodes); fout << "\tn" << root << " -> n" << child << ";" << endl; } return root; } public: /* The following are constructors to create a ParseTree * with anywhere from 0-7 children. * It's probably bad programming practice to have multiple constructors * instead of just using the addChild method, but this makes the ypp * code smaller. */ ParseTree (const char* l) :label(l), children(0) { } ParseTree (const char* l, ParseTree* c1) :label(l), children(1) { children[0] = c1; } ParseTree (const char* l, ParseTree* c1, ParseTree* c2) :label(l), children(2) { children[0] = c1; children[1] = c2; } ParseTree (const char* l, ParseTree* c1, ParseTree* c2, ParseTree* c3) :label(l), children(3) { children[0] = c1; children[1] = c2; children[2] = c3; } ParseTree (const char* l, ParseTree* c1, ParseTree* c2, ParseTree* c3, ParseTree* c4) :label(l), children(4) { children[0] = c1; children[1] = c2; children[2] = c3; children[3] = c4; } ParseTree (const char* l, ParseTree* c1, ParseTree* c2, ParseTree* c3, ParseTree* c4, ParseTree* c5) :label(l), children(5) { children[0] = c1; children[1] = c2; children[2] = c3; children[3] = c4; children[4] = c5; } ParseTree (const char* l, ParseTree* c1, ParseTree* c2, ParseTree* c3, ParseTree* c4, ParseTree* c5, ParseTree* c6) :label(l), children(6) { children[0] = c1; children[1] = c2; children[2] = c3; children[3] = c4; children[4] = c5; children[5] = c6; } ParseTree (const char* l, ParseTree* c1, ParseTree* c2, ParseTree* c3, ParseTree* c4, ParseTree* c5, ParseTree* c6, ParseTree* c7) :label(l), children(7) { children[0] = c1; children[1] = c2; children[2] = c3; children[3] = c4; children[4] = c5; children[5] = c6; children[6] = c7; } /* Destructor to free all the memory allocated by this tree. */ ~ParseTree() { for (vector<ParseTree*>::iterator iter = children.begin(); iter != children.end(); ++iter) { delete *iter; } children.clear(); } /* Adds a new child under this node. */ void addChild(ParseTree* c) { children.push_back(c); } /* Indicates whether this is a leaf in the tree or if it has children. */ bool isLeaf() { return children.empty(); } /* Writes this ParseTree to a .dot file as named. */ void writeDot(const char* fname) { ofstream fout(fname); int nodes = 0; fout << "digraph g {" << endl; addToDot(fout,nodes); fout << "}" << endl; fout.close(); } }; extern ParseTree pt; #endif //PARSETREE_HPP