diff --git a/include/NodeTree.h b/include/NodeTree.h index dab3bca..27c3a02 100644 --- a/include/NodeTree.h +++ b/include/NodeTree.h @@ -22,6 +22,9 @@ class NodeTree { NodeTree(std::string name, T inData); ~NodeTree(); + bool const operator==(NodeTree &other); + bool const operator<(const NodeTree &other) const; + void setParent(NodeTree* parent); void addParent(NodeTree* parent); NodeTree* getParent(); @@ -36,11 +39,10 @@ class NodeTree { std::vector*> getChildren(); NodeTree* get(int index); - std::string getName(); void setName(std::string); - T getData(); + T getData() const; void setData(T data); int size(); @@ -83,6 +85,23 @@ NodeTree::~NodeTree() { parents.clear(); //? Will this segfault? } +template +const bool NodeTree::operator==(NodeTree &other) { + if (!(data == other.data)) + return false; + if (children.size() != other.getChildren().size()) + return false; + for (typename std::vector*>::size_type i = 0; i < children.size(); i++) + if (! (*(children[i]) == *(other.getChildren()[i]))) + return false; + return true; +} + +template +const bool NodeTree::operator<(const NodeTree &other) const { + return data < other.getData(); +} + template void NodeTree::setParent(NodeTree* parent) { parents.clear(); @@ -180,7 +199,7 @@ void NodeTree::setName(std::string name) { } template -T NodeTree::getData() { +T NodeTree::getData() const { return data; } @@ -198,7 +217,10 @@ template std::string NodeTree::DOTGraphStringHelper() { std::string ourDOTRelation = ""; for (int i = 0; i < children.size(); i++) { - ourDOTRelation += getDOTName() + " -> " + children[i]->getDOTName() + ";\n" + children[i]->DOTGraphStringHelper(); + if (children[i] != NULL) + ourDOTRelation += getDOTName() + " -> " + children[i]->getDOTName() + ";\n" + children[i]->DOTGraphStringHelper(); + else + ourDOTRelation += getDOTName() + " -> BAD_NULL_" + getDOTName(); } return(ourDOTRelation); } diff --git a/include/RNGLRParser.h b/include/RNGLRParser.h index ccf3d34..ba9dde4 100644 --- a/include/RNGLRParser.h +++ b/include/RNGLRParser.h @@ -9,6 +9,7 @@ #include "Parser.h" #include "Symbol.h" #include "GraphStructuredStack.h" +#include "util.h" class RNGLRParser: public Parser { public: @@ -19,21 +20,21 @@ class RNGLRParser: public Parser { private: void reducer(int i); void shifter(int i); - void addChildren(NodeTree* parent, std::vector*> children, int nullablePartsIndex); + void addChildren(NodeTree* parent, std::vector*>* children, int nullablePartsIndex); void addStates(std::vector< State* >* stateSets, State* state); bool reducesToNull(ParseRule* rule); bool reducesToNull(ParseRule* rule, std::vector avoidList); bool belongsToFamily(NodeTree* node, std::vector*>* nodes); - bool arePacked(std::vector*>* nodes); + bool arePacked(std::vector*> nodes); bool isPacked(NodeTree* node); void setPacked(NodeTree* node, bool isPacked); int getNullableIndex(ParseRule* rule); - NodeTree getNullableParts(ParseRule* rule); - NodeTree getNullableParts(Symbol* symbol); - NodeTree getNullableParts(int index); + NodeTree* getNullableParts(ParseRule* rule); + NodeTree* getNullableParts(Symbol* symbol); + NodeTree* getNullableParts(int index); std::vector*> getPathEdges(std::vector*> path); @@ -53,7 +54,7 @@ class RNGLRParser: public Parser { std::vector*, int> > SPPFStepNodes; std::vector*> nullableParts; - std::map*, bool> packedMap; + std::map, bool> packedMap; }; #endif diff --git a/src/RNGLRParser.cpp b/src/RNGLRParser.cpp index cf71d15..e9a80d3 100644 --- a/src/RNGLRParser.cpp +++ b/src/RNGLRParser.cpp @@ -20,7 +20,7 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { } if (accepting) { std::cout << "Accepted!" << std::endl; - return getNullableParts(stateSets[0]->getBasis()->operator[0]->getLeftSide()); + return getNullableParts((*(stateSets[0]->getBasis()))[0]->getLeftSide()); } else { std::cout << "Rejected, no input (with no accepting state)" << std::endl; } @@ -64,7 +64,7 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { if (firstActions[i]->action == ParseAction::SHIFT) toShift.push(std::make_pair(v0,firstActions[i]->shiftState)); else if (firstActions[i]->action == ParseAction::REDUCE && firstActions[i]->reduceRule->getRightSide().size() == 0) { - Reduction newReduction = {v0, firstActions[i]->reduceRule->getLeftSide(), 0, getNullableIndex(firstActions[i]->reduceRule), new NodeTree("null", nullSymbol)} + Reduction newReduction = {v0, firstActions[i]->reduceRule->getLeftSide(), 0, getNullableIndex(firstActions[i]->reduceRule), new NodeTree("null", nullSymbol)}; toReduce.push(newReduction); //toReduce.push(std::make_pair(std::make_pair(v0, firstActions[i]->reduceRule->getLeftSide()), 0)); } @@ -83,8 +83,8 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { } //Clear the vector of SPPF nodes created every step - for (std::vector*>::size_type j = 0; j < SPPFStepNodes.size(); j++) - SPPFStepNodes[j] = NULL; + // for (std::vector*>::size_type j = 0; j < SPPFStepNodes.size(); j++) + // SPPFStepNodes[j] = NULL; SPPFStepNodes.clear(); while (toReduce.size() != 0) { @@ -97,7 +97,7 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { std::cout << "GSS:\n" << gss.toString() << std::endl; } std::cout << "Done with parsing loop, checking for acceptance" << std::endl; - NodeTree* accState = gss.frontierHasAccState(input.size()-1); + NodeTree* accState = gss.frontierGetAccState(input.size()-1); if (accState) { std::cout << "Accepted!" << std::endl; return gss.getEdge(accState, v0); @@ -112,7 +112,7 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { void RNGLRParser::reducer(int i) { Reduction reduction = toReduce.front(); toReduce.pop(); - std::cout << "Doing reduction of length " << reduction.length << " from state " << reduction.from->getData() << " to symbol " << reduction.first.second->toString() << std::endl; + std::cout << "Doing reduction of length " << reduction.length << " from state " << reduction.from->getData() << " to symbol " << reduction.symbol->toString() << std::endl; int pathLength = reduction.length > 0 ? reduction.length -1 : 0; //Get every reachable path std::vector*> >* paths = gss.getReachablePaths(reduction.from, pathLength); @@ -143,7 +143,7 @@ void RNGLRParser::reducer(int i) { //Otherwise, we create the new label if we haven't already int reachedFrontier = gss.getContainingFrontier(currentReached); for (std::vector*, int> >::size_type k = 0; k < SPPFStepNodes.size(); k++) { - if ( SPPFStepNodes[k].second == reachedFrontier && *(SPPFStepNodes[k].first->data) == *(reduction.symbol)) { + if ( SPPFStepNodes[k].second == reachedFrontier && *(SPPFStepNodes[k].first->getData()) == *(reduction.symbol)) { newLabel = SPPFStepNodes[k].first; break; } @@ -164,7 +164,7 @@ void RNGLRParser::reducer(int i) { std::vector actions = *(table.get(toState, input[i])); for (std::vector::size_type k = 0; k < actions.size(); k++) { if (actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule->getRightSize() != 0) { - Reduction newReduction = {currentReached, actions[k]->reduceRule->getLeftSide(), actions[k]->reduceRule->getRightSize(), getNullableIndex(actions[k]->reduceRule), newLabel} + Reduction newReduction = {currentReached, actions[k]->reduceRule->getLeftSide(), actions[k]->reduceRule->getRightSize(), getNullableIndex(actions[k]->reduceRule), newLabel}; toReduce.push(newReduction); } } @@ -182,10 +182,10 @@ void RNGLRParser::reducer(int i) { if (actions[k]->action == ParseAction::SHIFT) { toShift.push(std::make_pair(toStateNode, actions[k]->shiftState)); } else if (actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule->getRightSize() == 0) { - Reduction newReduction = {toStateNode, actions[k]->reduceRule->getLeftSide(), 0, getNullableIndex(actions[k]->reduceRule), new NodeTree("null", nullSymbol)} + Reduction newReduction = {toStateNode, actions[k]->reduceRule->getLeftSide(), 0, getNullableIndex(actions[k]->reduceRule), new NodeTree("null", nullSymbol)}; toReduce.push(newReduction); } else if (reduction.length != 0 && actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule->getRightSize() != 0) { - Reduction newReduction = {currentReached, actions[k]->reduceRule->getLeftSide(), actions[k]->reduceRule->getRightSize(), getNullableIndex(actions[k]->reduceRule), newLabel} + Reduction newReduction = {currentReached, actions[k]->reduceRule->getLeftSide(), actions[k]->reduceRule->getRightSize(), getNullableIndex(actions[k]->reduceRule), newLabel}; toReduce.push(newReduction); } } @@ -198,7 +198,7 @@ void RNGLRParser::reducer(int i) { void RNGLRParser::shifter(int i) { if (i != input.size()-1) { std::queue< std::pair*, int> > nextShifts; - NodeTree nextLabel = new NodeTree("frontier: " + intToString(i), input[i]); + NodeTree* newLabel = new NodeTree("frontier: " + intToString(i), input[i]); while (!toShift.empty()) { std::pair*, int> shift = toShift.front(); toShift.pop(); @@ -206,11 +206,11 @@ void RNGLRParser::shifter(int i) { NodeTree* shiftTo = gss.inFrontier(i+1, shift.second); if (shiftTo) { std::cout << "State already existed, just adding edge" << std::endl; - gss.addEdge(shiftTo, shift.first, nextLabel); + gss.addEdge(shiftTo, shift.first, newLabel); std::vector actions = *(table.get(shift.second, input[i+1])); for (std::vector::size_type j = 0; j < actions.size(); j++) { if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() != 0) { - Reduction newReduction = {shift.first, actions[j]->reduceRule->getLeftSide(), actions[j]->reduceRule->getRightSize(), getNullableIndex(actions[j]->reduceRule), newLabel} + Reduction newReduction = {shift.first, actions[j]->reduceRule->getLeftSide(), actions[j]->reduceRule->getRightSize(), getNullableIndex(actions[j]->reduceRule), newLabel}; toReduce.push(newReduction); } } @@ -226,10 +226,10 @@ void RNGLRParser::shifter(int i) { if (actions[j]->action == ParseAction::SHIFT) { nextShifts.push(std::make_pair(shiftTo, actions[j]->shiftState)); } else if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() != 0) { - Reduction newReduction = {shift.first, actions[j]->reduceRule->getLeftSide(), actions[j]->reduceRule->getRightSize(), getNullableIndex(actions[j]->reduceRule), newLabel} + Reduction newReduction = {shift.first, actions[j]->reduceRule->getLeftSide(), actions[j]->reduceRule->getRightSize(), getNullableIndex(actions[j]->reduceRule), newLabel}; toReduce.push(newReduction); } else if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() == 0) { - Reduction newReduction = {shiftTo, actions[j]->reduceRule->getLeftSide(), 0, getNullableIndex(actions[j]->reduceRule), new NodeTree("null", nullSymbol)} + Reduction newReduction = {shiftTo, actions[j]->reduceRule->getLeftSide(), 0, getNullableIndex(actions[j]->reduceRule), new NodeTree("null", nullSymbol)}; toReduce.push(newReduction); } } @@ -241,7 +241,7 @@ void RNGLRParser::shifter(int i) { void RNGLRParser::addChildren(NodeTree* parent, std::vector*>* children, int nullablePartsIndex) { if (nullablePartsIndex != 0) - children->push_back(getNullableParts(nullablePartsIndex); + children->push_back(getNullableParts(nullablePartsIndex)); if (!belongsToFamily(parent, children)) { if (parent->getChildren().size() == 0) { parent->addChildren(children); @@ -249,7 +249,8 @@ void RNGLRParser::addChildren(NodeTree* parent, std::vectorgetChildren())) { NodeTree* subParent = new NodeTree(); setPacked(subParent, true); - subParent->addChildren(&(parent->getChildren()); + std::vector*> tmp = parent->getChildren(); + subParent->addChildren(&tmp); parent->clearChildren(); parent->addChild(subParent); } @@ -262,11 +263,13 @@ void RNGLRParser::addChildren(NodeTree* parent, std::vector* node, std::vector*>* nodes) { + std::cout << "Checking " << node->getData()->toString() << "'s family" << std::endl; std::vector*> children = node->getChildren(); for (std::vector*>::size_type i = 0; i < nodes->size(); i++) { bool containsOne = false; for (std::vector*>::size_type j = 0; j < children.size(); j++) { - if ((*(*nodes)[i]) == *(children[j])) { + //Not sure where null comes from. For right now, just check to be sure we don't segfault + if ((*nodes)[i] == children[j] || (*nodes)[i] != NULL && children[j] != NULL && (*(*nodes)[i]) == *(children[j])) { containsOne = true; break; } @@ -278,19 +281,19 @@ bool RNGLRParser::belongsToFamily(NodeTree* node, std::vector*>* nodes) { +bool RNGLRParser::arePacked(std::vector*> nodes) { bool packed = true; - for (std::vector*>::size_type i = 0; i < nodes->size(); i++) - packed &= packedMap[node]; + for (std::vector*>::size_type i = 0; i < nodes.size(); i++) + packed &= packedMap[*(nodes[i])]; return packed; } bool RNGLRParser::isPacked(NodeTree* node) { - return packedMap[node]; + return packedMap[*node]; } void RNGLRParser::setPacked(NodeTree* node, bool isPacked) { - packedMap[node] = isPacked; + packedMap[*node] = isPacked; } @@ -408,15 +411,15 @@ int RNGLRParser::getNullableIndex(ParseRule* rule) { return 1; } -NodeTree RNGLRParser::getNullableParts(ParseRule* rule) { +NodeTree* RNGLRParser::getNullableParts(ParseRule* rule) { return new NodeTree("null", nullSymbol); } -NodeTree RNGLRParser::getNullableParts(Symbol* symbol) { +NodeTree* RNGLRParser::getNullableParts(Symbol* symbol) { return new NodeTree("null", nullSymbol); } -NodeTree RNGLRParser::getNullableParts(int index) { +NodeTree* RNGLRParser::getNullableParts(int index) { if (index == 0) return new NodeTree("not_null", nullSymbol); return new NodeTree("null", nullSymbol); @@ -424,7 +427,7 @@ NodeTree RNGLRParser::getNullableParts(int index) { std::vector*> RNGLRParser::getPathEdges(std::vector*> path) { std::vector*> pathEdges; - for (std::vector*>::size_type i < path.size()-1; i++) + for (std::vector*>::size_type i = 0; i < path.size()-1; i++) pathEdges.push_back(gss.getEdge(path[i], path[i+1])); return pathEdges; }