1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | /* SI 413 Fall 2012 * 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; 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; } /* Prints out this node and its children to the named output * stream, to the specified level of indentation. */ void plainTextOut(ostream& out, int indent) { out << label; for (vector<ParseTree*>::iterator iter = children.begin(); iter != children.end(); ++iter) { out << endl; for (int i=0; i<indent; ++i) out.put(' '); out << "( "; (*iter)->plainTextOut(out, indent + 2); out << " )"; } } 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(); } /* Writes this ParseTree to the named stream as plain text. */ void writeTo(ostream& out) { plainTextOut(out, 0); out << endl; } }; #endif //PARSETREE_HPP |