Changed Table to store vectors of actions, changed Parser appropriately.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "GSSNode.h"
|
||||
#include "NodeTree<int>.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<int>* newNode(int stateNum);
|
||||
void addToFrontier(int frontier, NodeTree<int>* node);
|
||||
NodeTree<int>* inFrontier(int frontier, int state);
|
||||
bool frontierIsEmpty(int frontier);
|
||||
bool frontierHasAccState(int frontier);
|
||||
std::vector<GSSNode*>* getReachable(GSSNode* start, int lenght);
|
||||
bool hasEdge(GSSNode* start, GSSNode* end);
|
||||
void addEdge(GSSNode* start, GSSNode* end);
|
||||
std::vector<NodeTree<int>*>* getReachable(NodeTree<int>* start, int lenght);
|
||||
bool hasEdge(NodeTree<int>* start, NodeTree<int>* end);
|
||||
void addEdge(NodeTree<int>* start, NodeTree<int>* end);
|
||||
private:
|
||||
std::vector<std::vector<GSSNode*>*> gss;
|
||||
std::vector<std::vector<NodeTree<int>*>*> gss;
|
||||
//
|
||||
};
|
||||
|
||||
@@ -22,15 +22,18 @@ class NodeTree {
|
||||
NodeTree(std::string name, T inData);
|
||||
~NodeTree();
|
||||
|
||||
void setParent(NodeTree* parent);
|
||||
NodeTree* getParent();
|
||||
void setParent(NodeTree<T>* parent);
|
||||
void addParent(NodeTree<T>* parent);
|
||||
NodeTree<T>* getParent();
|
||||
std::vector<NodeTree<T>*> getParents();
|
||||
|
||||
void addChild(NodeTree* child);
|
||||
int findChild(NodeTree* child);
|
||||
void removeChild(NodeTree* child);
|
||||
void addChild(NodeTree<T>* child);
|
||||
int findChild(NodeTree<T>* child);
|
||||
void removeChild(NodeTree<T>* child);
|
||||
void removeChild(int index);
|
||||
std::vector<NodeTree<T>*> getChildren();
|
||||
|
||||
NodeTree* get(int index);
|
||||
NodeTree<T>* 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<NodeTree*> children;
|
||||
std::vector<NodeTree<T>*> parents;
|
||||
std::vector<NodeTree<T>*> children;
|
||||
|
||||
static int idCounter;
|
||||
int id;
|
||||
@@ -59,7 +62,6 @@ int NodeTree<T>::idCounter;
|
||||
|
||||
template<class T>
|
||||
NodeTree<T>::NodeTree() {
|
||||
parent = NULL;
|
||||
name = "UnnamedNode";
|
||||
data = NULL;
|
||||
|
||||
@@ -68,7 +70,6 @@ NodeTree<T>::NodeTree() {
|
||||
|
||||
template<class T>
|
||||
NodeTree<T>::NodeTree(std::string name, T inData) {
|
||||
parent = NULL;
|
||||
data = NULL;
|
||||
this->name = name;
|
||||
this->data = inData;
|
||||
@@ -78,21 +79,33 @@ NodeTree<T>::NodeTree(std::string name, T inData) {
|
||||
template<class T>
|
||||
NodeTree<T>::~NodeTree() {
|
||||
children.clear();
|
||||
parents.clear(); //? Will this segfault?
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void NodeTree<T>::setParent(NodeTree<T>* parent) {
|
||||
if (this->parent != NULL) {
|
||||
this->parent->removeChild(this);
|
||||
}
|
||||
this->parent = parent;
|
||||
parents.clear();
|
||||
parents.push_back(parent);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void NodeTree<T>::addParent(NodeTree<T>* parent) {
|
||||
parents.push_back(parent);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
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>
|
||||
void NodeTree<T>::addChild(NodeTree<T>* child) {
|
||||
if (findChild(child) == -1)
|
||||
@@ -118,11 +131,16 @@ void NodeTree<T>::removeChild(int index) {
|
||||
template<class T>
|
||||
void NodeTree<T>::removeChild(NodeTree<T>* child) {
|
||||
int index = findChild(child);
|
||||
if (index != 0) {
|
||||
if (index != -1) {
|
||||
removeChild(index);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::vector<NodeTree<T>*> NodeTree<T>::getChildren() {
|
||||
return &children;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int NodeTree<T>::size() {
|
||||
int count = 0;
|
||||
|
||||
@@ -11,7 +11,7 @@ class RNGLRParser {
|
||||
std::vector<Symbol*> input;
|
||||
GraphStructuredStack gss;
|
||||
//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
|
||||
std::queue< std::pair<GSSNode*, int> > toShift;
|
||||
std::queue< std::pair<NodeTree<int>*, int> > toShift;
|
||||
};
|
||||
|
||||
@@ -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<ParseAction*>* get(int state, Symbol* token);
|
||||
std::string toString();
|
||||
private:
|
||||
std::vector< std::vector<ParseAction*>* > table;
|
||||
std::vector< std::vector< std::vector<ParseAction*>* >* > table;
|
||||
std::vector<Symbol*> symbolIndexVec;
|
||||
//The EOFSymbol, a pointer because of use in table, etc
|
||||
Symbol* EOFSymbol;
|
||||
|
||||
@@ -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) {
|
||||
//
|
||||
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<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);
|
||||
}
|
||||
@@ -313,6 +313,7 @@ std::string Parser::tableToString() {
|
||||
NodeTree<Symbol*>* Parser::parseInput(std::string inputString) {
|
||||
lexer.setInput(inputString);
|
||||
Symbol* token = lexer.next();
|
||||
std::vector<ParseAction*>* actionList;
|
||||
ParseAction* action;
|
||||
|
||||
stateStack.push(0);
|
||||
@@ -320,7 +321,8 @@ NodeTree<Symbol*>* 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<Symbol*>* 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;
|
||||
|
||||
@@ -21,7 +21,7 @@ RNGLRParser::parseInput(std::string inputString) {
|
||||
}
|
||||
|
||||
//Frontier 0, new node with state 0
|
||||
GSSNode* v0 = gss.newNode(0);
|
||||
NodeTree<int>* v0 = gss.newNode(0);
|
||||
gss.addToFrontier(0,v0);
|
||||
|
||||
std::vector<ParseAction*> firstActions = table.get(0, input[0]);
|
||||
@@ -48,13 +48,13 @@ RNGLRParser::parseInput(std::string inputString) {
|
||||
}
|
||||
|
||||
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;
|
||||
std::vector<GSSNode*>* reachable = gss.getReachable(reduction.first.first, pathLength);
|
||||
for (std::vector<GSSNode*>::size_type j = 0; j < reachable->size(); j++) {
|
||||
GSSNode* currentReached = (*reachable)[j];
|
||||
std::vector<NodeTree<int>*>* reachable = gss.getReachable(reduction.first.first, pathLength);
|
||||
for (std::vector<NodeTree<int>*>::size_type j = 0; j < reachable->size(); j++) {
|
||||
NodeTree<int>* currentReached = (*reachable)[j];
|
||||
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 (!gss.hasEdge(toStateNode, currentReached)) {
|
||||
gss.addEdge(toStateNode, currentReached);
|
||||
@@ -86,8 +86,8 @@ RNGLRParser::shifter(int i) {
|
||||
if (i != input.length()-1) {
|
||||
std::queue<ParseAction*> nextShifts;
|
||||
while (!toShift.empty()) {
|
||||
std::pair<GSSNode*, int> shift = toShift.front();
|
||||
GSSNode* shiftTo = gss.inFrontier(i+1, shift.second);
|
||||
std::pair<NodeTree<int>*, int> shift = toShift.front();
|
||||
NodeTree<int>* shiftTo = gss.inFrontier(i+1, shift.second);
|
||||
if (shiftTo) {
|
||||
gss.addEdge(shiftTo, shift.first);
|
||||
std::vector<ParseAction*> actions = table.get(shift.second, input[i+2]);
|
||||
|
||||
@@ -23,7 +23,7 @@ void Table::add(int stateNum, Symbol* tranSymbol, ParseAction* action) {
|
||||
//std::cout << "table size is " << table.size() <<std::endl;
|
||||
while (stateNum >= table.size()) {
|
||||
//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
|
||||
@@ -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<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
|
||||
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<ParseAction*>* Table::get(int state, Symbol* token) {
|
||||
int symbolIndex = -1;
|
||||
for (std::vector<Symbol*>::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<ParseAction*>* action = (*(table[state]))[symbolIndex];
|
||||
|
||||
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 ( symbolIndex >= table[state]->size() )
|
||||
return(new ParseAction(ParseAction::REJECT));
|
||||
if ( symbolIndex >= table[state]->size() ) {
|
||||
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 (action == NULL)
|
||||
return(new ParseAction(ParseAction::REJECT));
|
||||
if (action == NULL) {
|
||||
action = new std::vector<ParseAction*>();
|
||||
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";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user