/* SI413 Fall 2018
* This program contains code to build a labeled parse tree
* and later print it out to a dot file.
*/
#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;
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:
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() {
for (vector<ParseTree*>::iterator iter = children.begin();
iter != children.end(); ++iter)
{
delete *iter;
}
children.clear();
}
void addChild(ParseTree* c) {
children.push_back(c);
}
bool isLeaf() {
return children.empty();
}
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