From 733fe1c08da6a3659b677b001863b92379f16dc2 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sun, 28 Jul 2013 23:48:10 -0400 Subject: [PATCH] Changed Table to store vectors of actions, changed Parser appropriately. --- include/GraphStructuredStack.h | 16 ++++----- include/NodeTree.h | 50 +++++++++++++++++++--------- include/RNGLRParser.h | 4 +-- include/Table.h | 4 +-- src/GraphStructuredStack.cpp | 60 ++++++++++++++++++++++++++-------- src/Parser.cpp | 12 +++++-- src/RNGLRParser.cpp | 16 ++++----- src/Table.cpp | 52 ++++++++++++++++++----------- 8 files changed, 142 insertions(+), 72 deletions(-) diff --git a/include/GraphStructuredStack.h b/include/GraphStructuredStack.h index 38ad704..dba8123 100644 --- a/include/GraphStructuredStack.h +++ b/include/GraphStructuredStack.h @@ -1,6 +1,6 @@ #include #include -#include "GSSNode.h" +#include "NodeTree.h" #ifndef GRAPH_STRUCTURED_STACK #define GRAPH_STRUCTURED_STACK @@ -9,15 +9,15 @@ class GraphStructuredStack { public: GraphStructuredStack(); ~GraphStructuredStack(); - GSSNode* newNode(int stateNum); - void addToFrontier(int frontier, GSSNode* node); - bool inFrontier(int frontier, int state); + NodeTree* newNode(int stateNum); + void addToFrontier(int frontier, NodeTree* node); + NodeTree* inFrontier(int frontier, int state); bool frontierIsEmpty(int frontier); bool frontierHasAccState(int frontier); - std::vector* getReachable(GSSNode* start, int lenght); - bool hasEdge(GSSNode* start, GSSNode* end); - void addEdge(GSSNode* start, GSSNode* end); + std::vector*>* getReachable(NodeTree* start, int lenght); + bool hasEdge(NodeTree* start, NodeTree* end); + void addEdge(NodeTree* start, NodeTree* end); private: - std::vector*> gss; + std::vector*>*> gss; // }; diff --git a/include/NodeTree.h b/include/NodeTree.h index fc713f0..24b89f4 100644 --- a/include/NodeTree.h +++ b/include/NodeTree.h @@ -22,15 +22,18 @@ class NodeTree { NodeTree(std::string name, T inData); ~NodeTree(); - void setParent(NodeTree* parent); - NodeTree* getParent(); + void setParent(NodeTree* parent); + void addParent(NodeTree* parent); + NodeTree* getParent(); + std::vector*> getParents(); - void addChild(NodeTree* child); - int findChild(NodeTree* child); - void removeChild(NodeTree* child); + void addChild(NodeTree* child); + int findChild(NodeTree* child); + void removeChild(NodeTree* child); void removeChild(int index); + std::vector*> getChildren(); - NodeTree* get(int index); + NodeTree* get(int index); std::string getName(); void setName(std::string); @@ -46,8 +49,8 @@ class NodeTree { std::string getDOTName(); std::string name; T data; - NodeTree* parent; - std::vector children; + std::vector*> parents; + std::vector*> children; static int idCounter; int id; @@ -59,7 +62,6 @@ int NodeTree::idCounter; template NodeTree::NodeTree() { - parent = NULL; name = "UnnamedNode"; data = NULL; @@ -68,7 +70,6 @@ NodeTree::NodeTree() { template NodeTree::NodeTree(std::string name, T inData) { - parent = NULL; data = NULL; this->name = name; this->data = inData; @@ -78,21 +79,33 @@ NodeTree::NodeTree(std::string name, T inData) { template NodeTree::~NodeTree() { children.clear(); + parents.clear(); //? Will this segfault? } template void NodeTree::setParent(NodeTree* parent) { - if (this->parent != NULL) { - this->parent->removeChild(this); - } - this->parent = parent; + parents.clear(); + parents.push_back(parent); +} + +template +void NodeTree::addParent(NodeTree* parent) { + parents.push_back(parent); } template NodeTree* NodeTree::getParent() { - return parent; + if (parents.size() > 0) + return parents[0]; + return NULL; } +template +std::vector*> NodeTree::getParents() { + return parents; +} + + template void NodeTree::addChild(NodeTree* child) { if (findChild(child) == -1) @@ -118,11 +131,16 @@ void NodeTree::removeChild(int index) { template void NodeTree::removeChild(NodeTree* child) { int index = findChild(child); - if (index != 0) { + if (index != -1) { removeChild(index); } } +template +std::vector*> NodeTree::getChildren() { + return &children; +} + template int NodeTree::size() { int count = 0; diff --git a/include/RNGLRParser.h b/include/RNGLRParser.h index 750606f..d1113ea 100644 --- a/include/RNGLRParser.h +++ b/include/RNGLRParser.h @@ -11,7 +11,7 @@ class RNGLRParser { std::vector input; GraphStructuredStack gss; //start node, lefthand side of the reduction, reduction length - std::queue, int > toReduce; + std::queue*, Symbol*>, int > toReduce; //Node coming from, state going to - std::queue< std::pair > toShift; + std::queue< std::pair*, int> > toShift; }; diff --git a/include/Table.h b/include/Table.h index b4354e1..7becf30 100644 --- a/include/Table.h +++ b/include/Table.h @@ -13,10 +13,10 @@ class Table { ~Table(); void setSymbols(Symbol* EOFSymbol, Symbol* nullSymbol); void add(int stateNum, Symbol* tranSymbol, ParseAction* action); - ParseAction* get(int state, Symbol* token); + std::vector* get(int state, Symbol* token); std::string toString(); private: - std::vector< std::vector* > table; + std::vector< std::vector< std::vector* >* > table; std::vector symbolIndexVec; //The EOFSymbol, a pointer because of use in table, etc Symbol* EOFSymbol; diff --git a/src/GraphStructuredStack.cpp b/src/GraphStructuredStack.cpp index 6a22c46..c586192 100644 --- a/src/GraphStructuredStack.cpp +++ b/src/GraphStructuredStack.cpp @@ -8,34 +8,66 @@ GraphStructuredStack::~GraphStructuredStack() { // } -GSSNode* GraphStructuredStack::newNode(int stateNum) { - // +NodeTree* GraphStructuredStack::newNode(int stateNum) { + return new NodeTree("gssNode", stateNum); } -void GraphStructuredStack::addToFrontier(int frontier, GSSNode* node) { - // +void GraphStructuredStack::addToFrontier(int frontier, NodeTree* node) { + //First, make sure our vector has this and lesser frontiers. If not, add it and up to it + while (frontier >= gss.size()) { + gss.push_back(new std::vector*>()); + } + gss[frontier]->push_back(node); } -bool GraphStructuredStack::inFrontier(int frontier, int state) { - // +NodeTree* GraphStructuredStack::inFrontier(int frontier, int state) { + if (frontierIsEmpty()) + return NULL; + for (std::vector*>::size_type i = 0; i < gss[frontier]->size(); i++) { + if ((*(gss[frontier]))[i]->getData() == state) + return (*(gss[frontier]))[i]; + } + return NULL; } bool GraphStructuredStack::frontierIsEmpty(int frontier) { - // + return frontier >= gss.size() || gss[frontier]->size() == 0; } bool GraphStructuredStack::frontierHasAccState(int frontier) { - // + //The acc state is always state 1, for now + return inFrontier(frontier, 1); } -std::vector* GraphStructuredStack::getReachable(GSSNode* start, int lenght) { - // +std::vector*>* GraphStructuredStack::getReachable(NodeTree* start, int lenght) { + std::vector*>* reachableList = new std::vector*>(); + std::queue*> currentNodes; + std::queue*> nextNodes; + currentNodes.push_back(start); + for (int i = 0; i < lenght; i++) { + while (!currentNodes.empty()) { + NodeTree* currentNode = currentNodes.front(); + currentNodes.pop(); + std::vector*> children = currentNode->getChildren(); + for (std::vector*>::size_type j = 0; j < children.size(); j++) + nextNodes.push_back(children[j]); + } + currentNodes = nextNodes; + nextNodes.clear(); + } + while (!currentNodes.empty()) { + reachableList->push_back(currentNodes.front()); + currentNodes.pop(); + } + return reachableList; } -bool GraphStructuredStack::hasEdge(GSSNode* start, GSSNode* end) { - // +bool GraphStructuredStack::hasEdge(NodeTree* start, NodeTree* end) { + //Really, either testing for parent or child should work. + return start->findChild(end) != -1; } -void GraphStructuredStack::addEdge(GSSNode* start, GSSNode* end) { - // +void GraphStructuredStack::addEdge(NodeTree* start, NodeTree* end) { + start->addChild(end); + end->addChild(start); } \ No newline at end of file diff --git a/src/Parser.cpp b/src/Parser.cpp index 6d3e60d..d30d44a 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -313,6 +313,7 @@ std::string Parser::tableToString() { NodeTree* Parser::parseInput(std::string inputString) { lexer.setInput(inputString); Symbol* token = lexer.next(); + std::vector* actionList; ParseAction* action; stateStack.push(0); @@ -320,7 +321,8 @@ NodeTree* Parser::parseInput(std::string inputString) { while (true) { std::cout << "In state: " << intToString(stateStack.top()) << std::endl; - action = table.get(stateStack.top(), token); + actionList = table.get(stateStack.top(), token); + action = (*(actionList))[actionList->size()-1]; //std::cout << "Doing ParseAction: " << action->toString() << std::endl; switch (action->action) { case ParseAction::REDUCE: @@ -340,8 +342,12 @@ NodeTree* Parser::parseInput(std::string inputString) { Symbol* newSymbol = action->reduceRule->getLeftSide()->clone(); newSymbol->setSubTree(reduceTreeCombine(newSymbol, poppedSymbols)); symbolStack.push(newSymbol); - //std::cout << "top of state is " << intToString(stateStack.top()) << " symbolStack top is " << symbolStack.top()->toString() << std::endl; - stateStack.push(table.get(stateStack.top(), symbolStack.top())->shiftState); + std::cout << "top of state is " << intToString(stateStack.top()) << " symbolStack top is " << symbolStack.top()->toString() << std::endl; + + actionList = table.get(stateStack.top(), symbolStack.top()); + action = (*(actionList))[actionList->size()-1]; + + stateStack.push(action->shiftState); //std::cout << "Reduced, now condition is" << std::endl; //std::cout << "top of state is " << intToString(stateStack.top()) << " symbolStack top is " << symbolStack.top()->toString() << std::endl; break; diff --git a/src/RNGLRParser.cpp b/src/RNGLRParser.cpp index e4748ed..1e78d0d 100644 --- a/src/RNGLRParser.cpp +++ b/src/RNGLRParser.cpp @@ -21,7 +21,7 @@ RNGLRParser::parseInput(std::string inputString) { } //Frontier 0, new node with state 0 - GSSNode* v0 = gss.newNode(0); + NodeTree* v0 = gss.newNode(0); gss.addToFrontier(0,v0); std::vector firstActions = table.get(0, input[0]); @@ -48,13 +48,13 @@ RNGLRParser::parseInput(std::string inputString) { } RNGLRParser::reducer(int i) { - std::pair< std::pair, int > reduction = toReduce.front(); + std::pair< std::pair*, Symbol*>, int > reduction = toReduce.front(); int pathLength = reduction.second > 0 : reduction.second -1 ? 0; - std::vector* reachable = gss.getReachable(reduction.first.first, pathLength); - for (std::vector::size_type j = 0; j < reachable->size(); j++) { - GSSNode* currentReached = (*reachable)[j]; + std::vector*>* reachable = gss.getReachable(reduction.first.first, pathLength); + for (std::vector*>::size_type j = 0; j < reachable->size(); j++) { + NodeTree* currentReached = (*reachable)[j]; int toState = table.getShift(currentReached->state(), reduction.first.second); - GSSNode* toStateNode = gss.inFrontier(i, toState); + NodeTree* toStateNode = gss.inFrontier(i, toState); if (toStateNode) { if (!gss.hasEdge(toStateNode, currentReached)) { gss.addEdge(toStateNode, currentReached); @@ -86,8 +86,8 @@ RNGLRParser::shifter(int i) { if (i != input.length()-1) { std::queue nextShifts; while (!toShift.empty()) { - std::pair shift = toShift.front(); - GSSNode* shiftTo = gss.inFrontier(i+1, shift.second); + std::pair*, int> shift = toShift.front(); + NodeTree* shiftTo = gss.inFrontier(i+1, shift.second); if (shiftTo) { gss.addEdge(shiftTo, shift.first); std::vector actions = table.get(shift.second, input[i+2]); diff --git a/src/Table.cpp b/src/Table.cpp index bf1a4b8..1f88af5 100644 --- a/src/Table.cpp +++ b/src/Table.cpp @@ -23,7 +23,7 @@ void Table::add(int stateNum, Symbol* tranSymbol, ParseAction* action) { //std::cout << "table size is " << table.size() <= table.size()) { //std::cout << "Pushing back table" << std::endl; - table.push_back(new std::vector); + table.push_back(new std::vector* >()); } //find out what index this symbol is on @@ -57,18 +57,21 @@ void Table::add(int stateNum, Symbol* tranSymbol, ParseAction* action) { if ( (*(table[stateNum]))[symbolIndex] == NULL ) { //std::cout << "Null, adding " << action->toString() << std::endl; - (*(table[stateNum]))[symbolIndex] = action; + std::vector* actionList = new std::vector(); + actionList->push_back(action); + (*(table[stateNum]))[symbolIndex] = actionList; } //If the slot is not empty and does not contain ourself, then it is a conflict - else if ( !(*(table[stateNum]))[symbolIndex]->equalsExceptLookahead(*action)) { + //else if ( !(*(table[stateNum]))[symbolIndex]->equalsExceptLookahead(*action)) { + else { //std::cout << "not Null!" << std::endl; - std::cout << "State: " << stateNum << " Conflict between old: " << (*(table[stateNum]))[symbolIndex]->toString() << " and new: " << action->toString() << " on " << tranSymbol->toString() << std::endl; - //Don't overwrite - //(*(table[stateNum]))[symbolIndex] = action; + //std::cout << "State: " << stateNum << " Conflict between old: " << (*(table[stateNum]))[symbolIndex]->toString() << " and new: " << action->toString() << " on " << tranSymbol->toString() << std::endl; + + (*(table[stateNum]))[symbolIndex]->push_back(action); } } -ParseAction* Table::get(int state, Symbol* token) { +std::vector* Table::get(int state, Symbol* token) { int symbolIndex = -1; for (std::vector::size_type i = 0; i < symbolIndexVec.size(); i++) { if ( *(symbolIndexVec[i]) == *token) { @@ -79,17 +82,25 @@ ParseAction* Table::get(int state, Symbol* token) { //This is the accepting state, as it is the 1th's state's reduction on EOF, which is 0 in the symbolIndexVec //(This assumes singular goal assignment, a simplification for now) - if (state == 1 && symbolIndex == 0) - return(new ParseAction(ParseAction::ACCEPT)); + std::vector* action = (*(table[state]))[symbolIndex]; + + if (state == 1 && symbolIndex == 0) { + if (action == NULL) + action = new std::vector(); + action->push_back(new ParseAction(ParseAction::ACCEPT)); + } //If ourside the symbol range of this state (same as NULL), reject - if ( symbolIndex >= table[state]->size() ) - return(new ParseAction(ParseAction::REJECT)); + if ( symbolIndex >= table[state]->size() ) { + action = new std::vector(); + action->push_back(new ParseAction(ParseAction::REJECT)); + } - ParseAction* action = (*(table[state]))[symbolIndex]; //If null, reject. (this is a space with no other action) - if (action == NULL) - return(new ParseAction(ParseAction::REJECT)); + if (action == NULL) { + action = new std::vector(); + action->push_back(new ParseAction(ParseAction::REJECT)); + } //Otherwise, we have something, so return it return (action); @@ -101,13 +112,16 @@ std::string Table::toString() { concat += "\t" + symbolIndexVec[i]->toString(); concat += "\n"; - for (std::vector< std::vector< ParseRule* > >::size_type i = 0; i < table.size(); i++) { + for (std::vector< std::vector< std::vector< ParseRule* >* >* >::size_type i = 0; i < table.size(); i++) { concat += intToString(i) + "\t"; - for (std::vector< ParseRule* >::size_type j = 0; j < table[i]->size(); j++) { - if ( (*(table[i]))[j] != NULL) - concat += (*(table[i]))[j]->toString() + "\t"; - else + for (std::vector< std::vector< ParseRule* >* >::size_type j = 0; j < table[i]->size(); j++) { + if ( (*(table[i]))[j] != NULL) { + for (std::vector< ParseRule* >::size_type k = 0; k < (*(table[i]))[j]->size(); k++) { + concat += (*((*(table[i]))[j]))[k]->toString() + "\t"; + } + } else { concat += "NULL\t"; + } } concat += "\n"; }