Changed Table to store vectors of actions, changed Parser appropriately.

This commit is contained in:
Nathan Braswell
2013-07-28 23:48:10 -04:00
parent 6d7b38a03b
commit 733fe1c08d
8 changed files with 142 additions and 72 deletions

View File

@@ -1,6 +1,6 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include "GSSNode.h" #include "NodeTree<int>.h"
#ifndef GRAPH_STRUCTURED_STACK #ifndef GRAPH_STRUCTURED_STACK
#define GRAPH_STRUCTURED_STACK #define GRAPH_STRUCTURED_STACK
@@ -9,15 +9,15 @@ class GraphStructuredStack {
public: public:
GraphStructuredStack(); GraphStructuredStack();
~GraphStructuredStack(); ~GraphStructuredStack();
GSSNode* newNode(int stateNum); NodeTree<int>* newNode(int stateNum);
void addToFrontier(int frontier, GSSNode* node); void addToFrontier(int frontier, NodeTree<int>* node);
bool inFrontier(int frontier, int state); NodeTree<int>* inFrontier(int frontier, int state);
bool frontierIsEmpty(int frontier); bool frontierIsEmpty(int frontier);
bool frontierHasAccState(int frontier); bool frontierHasAccState(int frontier);
std::vector<GSSNode*>* getReachable(GSSNode* start, int lenght); std::vector<NodeTree<int>*>* getReachable(NodeTree<int>* start, int lenght);
bool hasEdge(GSSNode* start, GSSNode* end); bool hasEdge(NodeTree<int>* start, NodeTree<int>* end);
void addEdge(GSSNode* start, GSSNode* end); void addEdge(NodeTree<int>* start, NodeTree<int>* end);
private: private:
std::vector<std::vector<GSSNode*>*> gss; std::vector<std::vector<NodeTree<int>*>*> gss;
// //
}; };

View File

@@ -22,15 +22,18 @@ class NodeTree {
NodeTree(std::string name, T inData); NodeTree(std::string name, T inData);
~NodeTree(); ~NodeTree();
void setParent(NodeTree* parent); void setParent(NodeTree<T>* parent);
NodeTree* getParent(); void addParent(NodeTree<T>* parent);
NodeTree<T>* getParent();
std::vector<NodeTree<T>*> getParents();
void addChild(NodeTree* child); void addChild(NodeTree<T>* child);
int findChild(NodeTree* child); int findChild(NodeTree<T>* child);
void removeChild(NodeTree* child); void removeChild(NodeTree<T>* child);
void removeChild(int index); void removeChild(int index);
std::vector<NodeTree<T>*> getChildren();
NodeTree* get(int index); NodeTree<T>* get(int index);
std::string getName(); std::string getName();
void setName(std::string); void setName(std::string);
@@ -46,8 +49,8 @@ class NodeTree {
std::string getDOTName(); std::string getDOTName();
std::string name; std::string name;
T data; T data;
NodeTree* parent; std::vector<NodeTree<T>*> parents;
std::vector<NodeTree*> children; std::vector<NodeTree<T>*> children;
static int idCounter; static int idCounter;
int id; int id;
@@ -59,7 +62,6 @@ int NodeTree<T>::idCounter;
template<class T> template<class T>
NodeTree<T>::NodeTree() { NodeTree<T>::NodeTree() {
parent = NULL;
name = "UnnamedNode"; name = "UnnamedNode";
data = NULL; data = NULL;
@@ -68,7 +70,6 @@ NodeTree<T>::NodeTree() {
template<class T> template<class T>
NodeTree<T>::NodeTree(std::string name, T inData) { NodeTree<T>::NodeTree(std::string name, T inData) {
parent = NULL;
data = NULL; data = NULL;
this->name = name; this->name = name;
this->data = inData; this->data = inData;
@@ -78,21 +79,33 @@ NodeTree<T>::NodeTree(std::string name, T inData) {
template<class T> template<class T>
NodeTree<T>::~NodeTree() { NodeTree<T>::~NodeTree() {
children.clear(); children.clear();
parents.clear(); //? Will this segfault?
} }
template<class T> template<class T>
void NodeTree<T>::setParent(NodeTree<T>* parent) { void NodeTree<T>::setParent(NodeTree<T>* parent) {
if (this->parent != NULL) { parents.clear();
this->parent->removeChild(this); parents.push_back(parent);
} }
this->parent = parent;
template<class T>
void NodeTree<T>::addParent(NodeTree<T>* parent) {
parents.push_back(parent);
} }
template<class T> template<class T>
NodeTree<T>* NodeTree<T>::getParent() { NodeTree<T>* NodeTree<T>::getParent() {
return parent; if (parents.size() > 0)
return parents[0];
return NULL;
} }
template<class T>
std::vector<NodeTree<T>*> NodeTree<T>::getParents() {
return parents;
}
template<class T> template<class T>
void NodeTree<T>::addChild(NodeTree<T>* child) { void NodeTree<T>::addChild(NodeTree<T>* child) {
if (findChild(child) == -1) if (findChild(child) == -1)
@@ -118,11 +131,16 @@ void NodeTree<T>::removeChild(int index) {
template<class T> template<class T>
void NodeTree<T>::removeChild(NodeTree<T>* child) { void NodeTree<T>::removeChild(NodeTree<T>* child) {
int index = findChild(child); int index = findChild(child);
if (index != 0) { if (index != -1) {
removeChild(index); removeChild(index);
} }
} }
template<class T>
std::vector<NodeTree<T>*> NodeTree<T>::getChildren() {
return &children;
}
template<class T> template<class T>
int NodeTree<T>::size() { int NodeTree<T>::size() {
int count = 0; int count = 0;

View File

@@ -11,7 +11,7 @@ class RNGLRParser {
std::vector<Symbol*> input; std::vector<Symbol*> input;
GraphStructuredStack gss; GraphStructuredStack gss;
//start node, lefthand side of the reduction, reduction length //start node, lefthand side of the reduction, reduction length
std::queue<std::pair< std::pair<GSSNode*, Symbol*>, int > toReduce; std::queue<std::pair< std::pair<NodeTree<int>*, Symbol*>, int > toReduce;
//Node coming from, state going to //Node coming from, state going to
std::queue< std::pair<GSSNode*, int> > toShift; std::queue< std::pair<NodeTree<int>*, int> > toShift;
}; };

View File

@@ -13,10 +13,10 @@ class Table {
~Table(); ~Table();
void setSymbols(Symbol* EOFSymbol, Symbol* nullSymbol); void setSymbols(Symbol* EOFSymbol, Symbol* nullSymbol);
void add(int stateNum, Symbol* tranSymbol, ParseAction* action); void add(int stateNum, Symbol* tranSymbol, ParseAction* action);
ParseAction* get(int state, Symbol* token); std::vector<ParseAction*>* get(int state, Symbol* token);
std::string toString(); std::string toString();
private: private:
std::vector< std::vector<ParseAction*>* > table; std::vector< std::vector< std::vector<ParseAction*>* >* > table;
std::vector<Symbol*> symbolIndexVec; std::vector<Symbol*> symbolIndexVec;
//The EOFSymbol, a pointer because of use in table, etc //The EOFSymbol, a pointer because of use in table, etc
Symbol* EOFSymbol; Symbol* EOFSymbol;

View File

@@ -8,34 +8,66 @@ GraphStructuredStack::~GraphStructuredStack() {
// //
} }
GSSNode* GraphStructuredStack::newNode(int stateNum) { NodeTree<int>* GraphStructuredStack::newNode(int stateNum) {
// return new NodeTree<int>("gssNode", stateNum);
} }
void GraphStructuredStack::addToFrontier(int frontier, GSSNode* node) { void GraphStructuredStack::addToFrontier(int frontier, NodeTree<int>* 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<NodeTree<int>*>());
}
gss[frontier]->push_back(node);
} }
bool GraphStructuredStack::inFrontier(int frontier, int state) { NodeTree<int>* GraphStructuredStack::inFrontier(int frontier, int state) {
// if (frontierIsEmpty())
return NULL;
for (std::vector<NodeTree<int>*>::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) { bool GraphStructuredStack::frontierIsEmpty(int frontier) {
// return frontier >= gss.size() || gss[frontier]->size() == 0;
} }
bool GraphStructuredStack::frontierHasAccState(int frontier) { bool GraphStructuredStack::frontierHasAccState(int frontier) {
// //The acc state is always state 1, for now
return inFrontier(frontier, 1);
} }
std::vector<GSSNode*>* GraphStructuredStack::getReachable(GSSNode* start, int lenght) { std::vector<NodeTree<int>*>* GraphStructuredStack::getReachable(NodeTree<int>* start, int lenght) {
// std::vector<NodeTree<int>*>* reachableList = new std::vector<NodeTree<int>*>();
std::queue<NodeTree<int>*> currentNodes;
std::queue<NodeTree<int>*> nextNodes;
currentNodes.push_back(start);
for (int i = 0; i < lenght; i++) {
while (!currentNodes.empty()) {
NodeTree<int>* currentNode = currentNodes.front();
currentNodes.pop();
std::vector<NodeTree<T>*> children = currentNode->getChildren();
for (std::vector<NodeTree<T>*>::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<int>* start, NodeTree<int>* 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<int>* start, NodeTree<int>* end) {
// start->addChild(end);
end->addChild(start);
} }

View File

@@ -313,6 +313,7 @@ std::string Parser::tableToString() {
NodeTree<Symbol*>* Parser::parseInput(std::string inputString) { NodeTree<Symbol*>* Parser::parseInput(std::string inputString) {
lexer.setInput(inputString); lexer.setInput(inputString);
Symbol* token = lexer.next(); Symbol* token = lexer.next();
std::vector<ParseAction*>* actionList;
ParseAction* action; ParseAction* action;
stateStack.push(0); stateStack.push(0);
@@ -320,7 +321,8 @@ NodeTree<Symbol*>* Parser::parseInput(std::string inputString) {
while (true) { while (true) {
std::cout << "In state: " << intToString(stateStack.top()) << std::endl; 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; //std::cout << "Doing ParseAction: " << action->toString() << std::endl;
switch (action->action) { switch (action->action) {
case ParseAction::REDUCE: case ParseAction::REDUCE:
@@ -340,8 +342,12 @@ NodeTree<Symbol*>* Parser::parseInput(std::string inputString) {
Symbol* newSymbol = action->reduceRule->getLeftSide()->clone(); Symbol* newSymbol = action->reduceRule->getLeftSide()->clone();
newSymbol->setSubTree(reduceTreeCombine(newSymbol, poppedSymbols)); newSymbol->setSubTree(reduceTreeCombine(newSymbol, poppedSymbols));
symbolStack.push(newSymbol); symbolStack.push(newSymbol);
//std::cout << "top of state is " << intToString(stateStack.top()) << " symbolStack top is " << symbolStack.top()->toString() << std::endl; 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);
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 << "Reduced, now condition is" << std::endl;
//std::cout << "top of state is " << intToString(stateStack.top()) << " symbolStack top is " << symbolStack.top()->toString() << std::endl; //std::cout << "top of state is " << intToString(stateStack.top()) << " symbolStack top is " << symbolStack.top()->toString() << std::endl;
break; break;

View File

@@ -21,7 +21,7 @@ RNGLRParser::parseInput(std::string inputString) {
} }
//Frontier 0, new node with state 0 //Frontier 0, new node with state 0
GSSNode* v0 = gss.newNode(0); NodeTree<int>* v0 = gss.newNode(0);
gss.addToFrontier(0,v0); gss.addToFrontier(0,v0);
std::vector<ParseAction*> firstActions = table.get(0, input[0]); std::vector<ParseAction*> firstActions = table.get(0, input[0]);
@@ -48,13 +48,13 @@ RNGLRParser::parseInput(std::string inputString) {
} }
RNGLRParser::reducer(int i) { RNGLRParser::reducer(int i) {
std::pair< std::pair<GSSNode*, Symbol*>, int > reduction = toReduce.front(); std::pair< std::pair<NodeTree<int>*, Symbol*>, int > reduction = toReduce.front();
int pathLength = reduction.second > 0 : reduction.second -1 ? 0; int pathLength = reduction.second > 0 : reduction.second -1 ? 0;
std::vector<GSSNode*>* reachable = gss.getReachable(reduction.first.first, pathLength); std::vector<NodeTree<int>*>* reachable = gss.getReachable(reduction.first.first, pathLength);
for (std::vector<GSSNode*>::size_type j = 0; j < reachable->size(); j++) { for (std::vector<NodeTree<int>*>::size_type j = 0; j < reachable->size(); j++) {
GSSNode* currentReached = (*reachable)[j]; NodeTree<int>* currentReached = (*reachable)[j];
int toState = table.getShift(currentReached->state(), reduction.first.second); int toState = table.getShift(currentReached->state(), reduction.first.second);
GSSNode* toStateNode = gss.inFrontier(i, toState); NodeTree<int>* toStateNode = gss.inFrontier(i, toState);
if (toStateNode) { if (toStateNode) {
if (!gss.hasEdge(toStateNode, currentReached)) { if (!gss.hasEdge(toStateNode, currentReached)) {
gss.addEdge(toStateNode, currentReached); gss.addEdge(toStateNode, currentReached);
@@ -86,8 +86,8 @@ RNGLRParser::shifter(int i) {
if (i != input.length()-1) { if (i != input.length()-1) {
std::queue<ParseAction*> nextShifts; std::queue<ParseAction*> nextShifts;
while (!toShift.empty()) { while (!toShift.empty()) {
std::pair<GSSNode*, int> shift = toShift.front(); std::pair<NodeTree<int>*, int> shift = toShift.front();
GSSNode* shiftTo = gss.inFrontier(i+1, shift.second); NodeTree<int>* shiftTo = gss.inFrontier(i+1, shift.second);
if (shiftTo) { if (shiftTo) {
gss.addEdge(shiftTo, shift.first); gss.addEdge(shiftTo, shift.first);
std::vector<ParseAction*> actions = table.get(shift.second, input[i+2]); std::vector<ParseAction*> actions = table.get(shift.second, input[i+2]);

View File

@@ -23,7 +23,7 @@ void Table::add(int stateNum, Symbol* tranSymbol, ParseAction* action) {
//std::cout << "table size is " << table.size() <<std::endl; //std::cout << "table size is " << table.size() <<std::endl;
while (stateNum >= table.size()) { while (stateNum >= table.size()) {
//std::cout << "Pushing back table" << std::endl; //std::cout << "Pushing back table" << std::endl;
table.push_back(new std::vector<ParseAction*>); table.push_back(new std::vector<std::vector< ParseAction*>* >());
} }
//find out what index this symbol is on //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 ) { if ( (*(table[stateNum]))[symbolIndex] == NULL ) {
//std::cout << "Null, adding " << action->toString() << std::endl; //std::cout << "Null, adding " << action->toString() << std::endl;
(*(table[stateNum]))[symbolIndex] = action; std::vector<ParseAction*>* actionList = new std::vector<ParseAction*>();
actionList->push_back(action);
(*(table[stateNum]))[symbolIndex] = actionList;
} }
//If the slot is not empty and does not contain ourself, then it is a conflict //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 << "not Null!" << std::endl;
std::cout << "State: " << stateNum << " Conflict between old: " << (*(table[stateNum]))[symbolIndex]->toString() << " and new: " << action->toString() << " on " << tranSymbol->toString() << 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; (*(table[stateNum]))[symbolIndex]->push_back(action);
} }
} }
ParseAction* Table::get(int state, Symbol* token) { std::vector<ParseAction*>* Table::get(int state, Symbol* token) {
int symbolIndex = -1; int symbolIndex = -1;
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) { for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) {
if ( *(symbolIndexVec[i]) == *token) { 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 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) //(This assumes singular goal assignment, a simplification for now)
if (state == 1 && symbolIndex == 0) std::vector<ParseAction*>* action = (*(table[state]))[symbolIndex];
return(new ParseAction(ParseAction::ACCEPT));
if (state == 1 && symbolIndex == 0) {
if (action == NULL)
action = new std::vector<ParseAction*>();
action->push_back(new ParseAction(ParseAction::ACCEPT));
}
//If ourside the symbol range of this state (same as NULL), reject //If ourside the symbol range of this state (same as NULL), reject
if ( symbolIndex >= table[state]->size() ) if ( symbolIndex >= table[state]->size() ) {
return(new ParseAction(ParseAction::REJECT)); action = new std::vector<ParseAction*>();
action->push_back(new ParseAction(ParseAction::REJECT));
}
ParseAction* action = (*(table[state]))[symbolIndex];
//If null, reject. (this is a space with no other action) //If null, reject. (this is a space with no other action)
if (action == NULL) if (action == NULL) {
return(new ParseAction(ParseAction::REJECT)); action = new std::vector<ParseAction*>();
action->push_back(new ParseAction(ParseAction::REJECT));
}
//Otherwise, we have something, so return it //Otherwise, we have something, so return it
return (action); return (action);
@@ -101,13 +112,16 @@ std::string Table::toString() {
concat += "\t" + symbolIndexVec[i]->toString(); concat += "\t" + symbolIndexVec[i]->toString();
concat += "\n"; 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"; concat += intToString(i) + "\t";
for (std::vector< ParseRule* >::size_type j = 0; j < table[i]->size(); j++) { for (std::vector< std::vector< ParseRule* >* >::size_type j = 0; j < table[i]->size(); j++) {
if ( (*(table[i]))[j] != NULL) if ( (*(table[i]))[j] != NULL) {
concat += (*(table[i]))[j]->toString() + "\t"; for (std::vector< ParseRule* >::size_type k = 0; k < (*(table[i]))[j]->size(); k++) {
else concat += (*((*(table[i]))[j]))[k]->toString() + "\t";
}
} else {
concat += "NULL\t"; concat += "NULL\t";
}
} }
concat += "\n"; concat += "\n";
} }