Finished writing first code for turning the RNGLR recognizer into a parser. Doesn't compile yet, needs lots of bugfixing, but I'm calling it a night.
This commit is contained in:
@@ -14,15 +14,20 @@ class GraphStructuredStack {
|
|||||||
NodeTree<int>* newNode(int stateNum);
|
NodeTree<int>* newNode(int stateNum);
|
||||||
void addToFrontier(int frontier, NodeTree<int>* node);
|
void addToFrontier(int frontier, NodeTree<int>* node);
|
||||||
NodeTree<int>* inFrontier(int frontier, int state);
|
NodeTree<int>* inFrontier(int frontier, int state);
|
||||||
|
int getContainingFrontier(NodeTree<int>* node);
|
||||||
bool frontierIsEmpty(int frontier);
|
bool frontierIsEmpty(int frontier);
|
||||||
bool frontierHasAccState(int frontier);
|
NodeTree<int>* frontierGetAccState(int frontier);
|
||||||
std::vector<NodeTree<int>*>* getReachable(NodeTree<int>* start, int lenght);
|
std::vector<NodeTree<int>*>* getReachable(NodeTree<int>* start, int lenght);
|
||||||
|
std::vector<std::vector<NodeTree<int>*> >* getReachablePaths(NodeTree<int>* start, int lenght);
|
||||||
|
void recursivePathFind(NodeTree<int>* start, int length, std::vector<NodeTree<int>*> currentPath, std::vector<std::vector<NodeTree<int>*> >* paths);
|
||||||
bool hasEdge(NodeTree<int>* start, NodeTree<int>* end);
|
bool hasEdge(NodeTree<int>* start, NodeTree<int>* end);
|
||||||
void addEdge(NodeTree<int>* start, NodeTree<int>* end);
|
NodeTree<Symbol*>* getEdge(NodeTree<int>* start, NodeTree<int>* end);
|
||||||
|
void addEdge(NodeTree<int>* start, NodeTree<int>* end, NodeTree<Symbol*>* edge);
|
||||||
|
|
||||||
std::string toString();
|
std::string toString();
|
||||||
private:
|
private:
|
||||||
std::vector<std::vector<NodeTree<int>*>*> gss;
|
std::vector<std::vector<NodeTree<int>*>*> gss;
|
||||||
|
std::map<std::pair<NodeTree<int>*, NodeTree<int>*>, NodeTree<Symbol*> edges;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+19
-2
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
#include "Parser.h"
|
#include "Parser.h"
|
||||||
#include "GraphStructuredStack.h"
|
#include "GraphStructuredStack.h"
|
||||||
|
|
||||||
@@ -24,14 +26,29 @@ class RNGLRParser: public Parser {
|
|||||||
bool belongsToFamily(NodeTree<Symbol*>* node, std::vector<NodeTree<Symbol*>*>* nodes);
|
bool belongsToFamily(NodeTree<Symbol*>* node, std::vector<NodeTree<Symbol*>*>* nodes);
|
||||||
bool arePacked(std::vector<NodeTree<Symbol*>*>* nodes);
|
bool arePacked(std::vector<NodeTree<Symbol*>*>* nodes);
|
||||||
bool isPacked(NodeTree<Symbol*>* node);
|
bool isPacked(NodeTree<Symbol*>* node);
|
||||||
void setPacked(NodeTree<Symbol*>* node, bool isPacked)
|
void setPacked(NodeTree<Symbol*>* node, bool isPacked);
|
||||||
|
|
||||||
|
int getNullableIndex(ParseRule* rule);
|
||||||
|
NodeTree<Symbol*> getNullableParts(ParseRule* rule);
|
||||||
|
NodeTree<Symbol*> getNullableParts(Symbol* symbol);
|
||||||
|
NodeTree<Symbol*> getNullableParts(int index);
|
||||||
|
|
||||||
|
std::vector<NodeTree<Symbol*>*> getPathEdges(std::vector<NodeTree<int>*> path);
|
||||||
|
|
||||||
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<NodeTree<int>*, Symbol*>, int > > toReduce;
|
struct Reduction {
|
||||||
|
NodeTree<int>* from;
|
||||||
|
Symbol* symbol;
|
||||||
|
int length;
|
||||||
|
int nullablePartsIndex;
|
||||||
|
NodeTree<Symbol*>* label;
|
||||||
|
} ;
|
||||||
|
std::queue<reduction> toReduce;
|
||||||
//Node coming from, state going to
|
//Node coming from, state going to
|
||||||
std::queue< std::pair<NodeTree<int>*, int> > toShift;
|
std::queue< std::pair<NodeTree<int>*, int> > toShift;
|
||||||
|
std::vector<std::pair<NodeTree<Symbol*>*, int> > SPPFStepNodes;
|
||||||
|
|
||||||
std::vector<NodeTree<Symbol*>*> nullableParts;
|
std::vector<NodeTree<Symbol*>*> nullableParts;
|
||||||
std::map<NodeTree<Symbol*>*, bool> packedMap;
|
std::map<NodeTree<Symbol*>*, bool> packedMap;
|
||||||
|
|||||||
@@ -32,11 +32,23 @@ NodeTree<int>* GraphStructuredStack::inFrontier(int frontier, int state) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GraphStructuredStack::getContainingFrontier(NodeTree<int>* node) {
|
||||||
|
for (std::vector<std::vector<NodeTree<int>*>*>::size_type i = 0; i < gss.size(); i++) {
|
||||||
|
if (frontierIsEmpty(frontier))
|
||||||
|
continue;
|
||||||
|
for (std::vector<NodeTree<int>*>::size_type j = 0; j < gss[i]->size(); j++) {
|
||||||
|
if (*((*(gss[i]))[j]) == *node)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
bool GraphStructuredStack::frontierIsEmpty(int frontier) {
|
bool GraphStructuredStack::frontierIsEmpty(int frontier) {
|
||||||
return frontier >= gss.size() || gss[frontier]->size() == 0;
|
return frontier >= gss.size() || gss[frontier]->size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GraphStructuredStack::frontierHasAccState(int frontier) {
|
NodeTree<int>* GraphStructuredStack::frontierGetAccState(int frontier) {
|
||||||
//The acc state is always state 1, for now
|
//The acc state is always state 1, for now
|
||||||
return inFrontier(frontier, 1);
|
return inFrontier(frontier, 1);
|
||||||
}
|
}
|
||||||
@@ -71,14 +83,38 @@ std::vector<NodeTree<int>*>* GraphStructuredStack::getReachable(NodeTree<int>* s
|
|||||||
return reachableList;
|
return reachableList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::vector<NodeTree<int>*> >* GraphStructuredStack::getReachablePaths(NodeTree<int>* start, int length) {
|
||||||
|
std::vector<std::vector<NodeTree<int>*> >* paths = new std::vector<std::vector<NodeTree<int>*> >();
|
||||||
|
std::vector<NodeTree<int>*> currentPath;
|
||||||
|
recursivePathFind(start, length, currentPath, paths);
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphStructuredStack::recursivePathFind(NodeTree<int>* start, int length, std::vector<NodeTree<int>*> currentPath, std::vector<std::vector<NodeTree<int>*> >* paths) {
|
||||||
|
currentPath.push_back(start);
|
||||||
|
if (length == 0) {
|
||||||
|
paths->push_back(currentPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<NodeTree<int>*>* children = start->getChildren();
|
||||||
|
for (std::vector<NodeTree<int>*>::size_type i = 0; i < children->size(); i++) {
|
||||||
|
recursivePathFind((*children)[i], length-1, currentPath, paths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool GraphStructuredStack::hasEdge(NodeTree<int>* start, NodeTree<int>* end) {
|
bool GraphStructuredStack::hasEdge(NodeTree<int>* start, NodeTree<int>* end) {
|
||||||
//Really, either testing for parent or child should work.
|
//Really, either testing for parent or child should work.
|
||||||
return start->findChild(end) != -1;
|
return start->findChild(end) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphStructuredStack::addEdge(NodeTree<int>* start, NodeTree<int>* end) {
|
NodeTree<Symbol*>* GraphStructuredStack::getEdge(NodeTree<int>* start, NodeTree<int>* end) {
|
||||||
|
return edges.get(std::make_pair(start, end), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphStructuredStack::addEdge(NodeTree<int>* start, NodeTree<int>* end, NodeTree<Symbol*> edge) {
|
||||||
start->addChild(end);
|
start->addChild(end);
|
||||||
end->addParent(start);
|
end->addParent(start);
|
||||||
|
edges[std::make_pair(start, end)] = edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GraphStructuredStack::toString() {
|
std::string GraphStructuredStack::toString() {
|
||||||
|
|||||||
+136
-36
@@ -18,10 +18,12 @@ NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
|
|||||||
if ((*zeroStateActions)[i]->action == ParseAction::REDUCE)
|
if ((*zeroStateActions)[i]->action == ParseAction::REDUCE)
|
||||||
accepting = true;
|
accepting = true;
|
||||||
}
|
}
|
||||||
if (accepting)
|
if (accepting) {
|
||||||
std::cout << "Accepted!" << std::endl;
|
std::cout << "Accepted!" << std::endl;
|
||||||
else
|
return getNullableParts(stateSets[0]->getBasis()->operator[0]->getLeftSide());
|
||||||
|
} else {
|
||||||
std::cout << "Rejected, no input (with no accepting state)" << std::endl;
|
std::cout << "Rejected, no input (with no accepting state)" << std::endl;
|
||||||
|
}
|
||||||
return new NodeTree<Symbol*>();
|
return new NodeTree<Symbol*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +64,9 @@ NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
|
|||||||
if (firstActions[i]->action == ParseAction::SHIFT)
|
if (firstActions[i]->action == ParseAction::SHIFT)
|
||||||
toShift.push(std::make_pair(v0,firstActions[i]->shiftState));
|
toShift.push(std::make_pair(v0,firstActions[i]->shiftState));
|
||||||
else if (firstActions[i]->action == ParseAction::REDUCE && firstActions[i]->reduceRule->getRightSide().size() == 0) {
|
else if (firstActions[i]->action == ParseAction::REDUCE && firstActions[i]->reduceRule->getRightSide().size() == 0) {
|
||||||
toReduce.push(std::make_pair(std::make_pair(v0, firstActions[i]->reduceRule->getLeftSide()), 0));
|
Reduction newReduction = {v0, firstActions[i]->reduceRule->getLeftSide(), 0, getNullableIndex(firstActions[i]->reduceRule), new NodeTree<Symbol*>("null", nullSymbol)}
|
||||||
|
toReduce.push(newReduction);
|
||||||
|
//toReduce.push(std::make_pair(std::make_pair(v0, firstActions[i]->reduceRule->getLeftSide()), 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,6 +81,12 @@ NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
|
|||||||
std::cout << "Failed on " << input[i]->toString() << " next: " << input[i+1]->toString() << std::endl;
|
std::cout << "Failed on " << input[i]->toString() << " next: " << input[i+1]->toString() << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Clear the vector of SPPF nodes created every step
|
||||||
|
for (std::vector<NodeTree<Symbol*>*>::size_type j = 0; j < SPPFStepNodes.size(); j++)
|
||||||
|
SPPFStepNodes[j] = NULL;
|
||||||
|
SPPFStepNodes.clear();
|
||||||
|
|
||||||
while (toReduce.size() != 0) {
|
while (toReduce.size() != 0) {
|
||||||
std::cout << "Reducing for " << i << std::endl;
|
std::cout << "Reducing for " << i << std::endl;
|
||||||
//std::cout << "GSS:\n" << gss.toString() << std::endl;
|
//std::cout << "GSS:\n" << gss.toString() << std::endl;
|
||||||
@@ -87,61 +97,108 @@ NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
|
|||||||
std::cout << "GSS:\n" << gss.toString() << std::endl;
|
std::cout << "GSS:\n" << gss.toString() << std::endl;
|
||||||
}
|
}
|
||||||
std::cout << "Done with parsing loop, checking for acceptance" << std::endl;
|
std::cout << "Done with parsing loop, checking for acceptance" << std::endl;
|
||||||
if (gss.frontierHasAccState(input.size()-1))
|
NodeTree<int>* accState = gss.frontierHasAccState(input.size()-1);
|
||||||
|
if (accState) {
|
||||||
std::cout << "Accepted!" << std::endl;
|
std::cout << "Accepted!" << std::endl;
|
||||||
else
|
return gss.getEdge(accState, v0);
|
||||||
|
} else {
|
||||||
std::cout << "Rejected!" << std::endl;
|
std::cout << "Rejected!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << "GSS:\n" << gss.toString() << std::endl;
|
std::cout << "GSS:\n" << gss.toString() << std::endl;
|
||||||
return new NodeTree<Symbol*>();
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RNGLRParser::reducer(int i) {
|
void RNGLRParser::reducer(int i) {
|
||||||
std::pair< std::pair<NodeTree<int>*, Symbol*>, int > reduction = toReduce.front();
|
Reduction reduction = toReduce.front();
|
||||||
toReduce.pop();
|
toReduce.pop();
|
||||||
std::cout << "Doing reduction of length " << reduction.second << " from state " << reduction.first.first->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.first.second->toString() << std::endl;
|
||||||
int pathLength = reduction.second > 0 ? reduction.second -1 : 0;
|
int pathLength = reduction.length > 0 ? reduction.length -1 : 0;
|
||||||
std::vector<NodeTree<int>*>* reachable = gss.getReachable(reduction.first.first, pathLength);
|
//Get every reachable path
|
||||||
for (std::vector<NodeTree<int>*>::size_type j = 0; j < reachable->size(); j++) {
|
std::vector<std::vector<NodeTree<int>*> >* paths = gss.getReachablePaths(reduction.from, pathLength);
|
||||||
NodeTree<int>* currentReached = (*reachable)[j];
|
|
||||||
std::cout << "Getting the shfit state for state " << currentReached->getData() << " and symbol " << reduction.first.second->toString() << std::endl;
|
for (std::vector<std::vector<NodeTree<int>*> >::size_type j = 0; j < paths->size(); j++) {
|
||||||
int toState = table.getShift(currentReached->getData(), reduction.first.second)->shiftState;
|
|
||||||
|
//Algorithm expects path in reverse order
|
||||||
|
std::vector<NodeTree<int>*> currentPath = (*paths)[j];
|
||||||
|
std::reverse(currentPath.begin(), currentPath.end());
|
||||||
|
//Add label of first edge to the end, (since reversed, this is the correct place)
|
||||||
|
|
||||||
|
//Get the edges for the current path
|
||||||
|
std::vector<NodeTree<Symbol*>*> pathEdges = getPathEdges(currentPath);
|
||||||
|
//If the reduction length is 0, label as passed in is null
|
||||||
|
if (reduction.length != 0)
|
||||||
|
pathEdges.push_back(reduction.label);
|
||||||
|
//The end of the current path (remember reversed)
|
||||||
|
NodeTree<int>* currentReached = currentPath[0];
|
||||||
|
|
||||||
|
std::cout << "Getting the shfit state for state " << currentReached->getData() << " and symbol " << reduction.symbol->toString() << std::endl;
|
||||||
|
int toState = table.getShift(currentReached->getData(), reduction.symbol)->shiftState;
|
||||||
|
|
||||||
|
//If reduction length is 0, then we make the new label the appropriate nullable parts
|
||||||
|
NodeTree<Symbol*>* newLabel = NULL;
|
||||||
|
if (reduction.length == 0) {
|
||||||
|
newLabel = getNullableParts(reduction.nullablePartsIndex);
|
||||||
|
} else {
|
||||||
|
//Otherwise, we create the new label if we haven't already
|
||||||
|
int reachedFrontier = gss.getContainingFrontier(currentReached);
|
||||||
|
for (std::vector<std::pair<NodeTree<Symbol*>*, int> >::size_type k = 0; k < SPPFStepNodes.size(); k++) {
|
||||||
|
if ( SPPFStepNodes[k].second == reachedFrontier && *(SPPFStepNodes[k].first->data) == *(reduction.symbol)) {
|
||||||
|
newLabel = SPPFStepNodes[k].first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!newLabel) {
|
||||||
|
newLabel = new NodeTree<Symbol*>("frontier: " + intToString(reachedFrontier), reduction.symbol);
|
||||||
|
SPPFStepNodes.push_back(std::make_pair(newLabel, reachedFrontier));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NodeTree<int>* 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, newLabel);
|
||||||
if (reduction.second != 0) {
|
if (reduction.length != 0) {
|
||||||
//Do all non null reduction
|
//Do all non null reduction
|
||||||
std::cout << "Checking for non-null reductions in states that already existed" << std::endl;
|
std::cout << "Checking for non-null reductions in states that already existed" << std::endl;
|
||||||
std::vector<ParseAction*> actions = *(table.get(toState, input[i]));
|
std::vector<ParseAction*> actions = *(table.get(toState, input[i]));
|
||||||
for (std::vector<ParseAction*>::size_type k = 0; k < actions.size(); k++)
|
for (std::vector<ParseAction*>::size_type k = 0; k < actions.size(); k++) {
|
||||||
if (actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule->getRightSize() != 0)
|
if (actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule->getRightSize() != 0) {
|
||||||
toReduce.push(std::make_pair(std::make_pair(currentReached, actions[k]->reduceRule->getLeftSide()), actions[k]->reduceRule->getRightSize()));
|
Reduction newReduction = {currentReached, actions[k]->reduceRule->getLeftSide(), actions[k]->reduceRule->getRightSize(), getNullableIndex(actions[k]->reduceRule), newLabel}
|
||||||
|
toReduce.push(newReduction);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
toStateNode = gss.newNode(toState);
|
toStateNode = gss.newNode(toState);
|
||||||
gss.addToFrontier(i, toStateNode);
|
gss.addToFrontier(i, toStateNode);
|
||||||
gss.addEdge(toStateNode, currentReached);
|
gss.addEdge(toStateNode, currentReached, newLabel);
|
||||||
|
|
||||||
std::cout << "Adding shifts and reductions for a state that did not exist" << std::endl;
|
std::cout << "Adding shifts and reductions for a state that did not exist" << std::endl;
|
||||||
std::vector<ParseAction*> actions = *(table.get(toState, input[i]));
|
std::vector<ParseAction*> actions = *(table.get(toState, input[i]));
|
||||||
for (std::vector<ParseAction*>::size_type k = 0; k < actions.size(); k++) {
|
for (std::vector<ParseAction*>::size_type k = 0; k < actions.size(); k++) {
|
||||||
std::cout << "Action is " << actions[k]->toString() << std::endl;
|
std::cout << "Action is " << actions[k]->toString() << std::endl;
|
||||||
if (actions[k]->action == ParseAction::SHIFT)
|
if (actions[k]->action == ParseAction::SHIFT) {
|
||||||
toShift.push(std::make_pair(toStateNode, actions[k]->shiftState));
|
toShift.push(std::make_pair(toStateNode, actions[k]->shiftState));
|
||||||
else if (actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule->getRightSize() != 0)
|
} else if (actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule->getRightSize() == 0) {
|
||||||
toReduce.push(std::make_pair(std::make_pair(currentReached, actions[k]->reduceRule->getLeftSide()), actions[k]->reduceRule->getRightSize()));
|
Reduction newReduction = {toStateNode, actions[k]->reduceRule->getLeftSide(), 0, getNullableIndex(actions[k]->reduceRule), new NodeTree<Symbol*>("null", nullSymbol)}
|
||||||
else if (actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule->getRightSize() == 0)
|
toReduce.push(newReduction);
|
||||||
toReduce.push(std::make_pair(std::make_pair(toStateNode, actions[k]->reduceRule->getLeftSide()), actions[k]->reduceRule->getRightSize()));
|
} 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}
|
||||||
|
toReduce.push(newReduction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (reduction.length != 0)
|
||||||
|
addChildren(newLabel, &pathEdges, reduction.nullablePartsIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RNGLRParser::shifter(int i) {
|
void RNGLRParser::shifter(int i) {
|
||||||
if (i != input.size()-1) {
|
if (i != input.size()-1) {
|
||||||
std::queue< std::pair<NodeTree<int>*, int> > nextShifts;
|
std::queue< std::pair<NodeTree<int>*, int> > nextShifts;
|
||||||
|
NodeTree<Symbol*> nextLabel = new NodeTree<Symbol*>("frontier: " + intToString(i), input[i]);
|
||||||
while (!toShift.empty()) {
|
while (!toShift.empty()) {
|
||||||
std::pair<NodeTree<int>*, int> shift = toShift.front();
|
std::pair<NodeTree<int>*, int> shift = toShift.front();
|
||||||
toShift.pop();
|
toShift.pop();
|
||||||
@@ -149,27 +206,32 @@ void RNGLRParser::shifter(int i) {
|
|||||||
NodeTree<int>* shiftTo = gss.inFrontier(i+1, shift.second);
|
NodeTree<int>* shiftTo = gss.inFrontier(i+1, shift.second);
|
||||||
if (shiftTo) {
|
if (shiftTo) {
|
||||||
std::cout << "State already existed, just adding edge" << std::endl;
|
std::cout << "State already existed, just adding edge" << std::endl;
|
||||||
gss.addEdge(shiftTo, shift.first);
|
gss.addEdge(shiftTo, shift.first, nextLabel);
|
||||||
std::vector<ParseAction*> actions = *(table.get(shift.second, input[i+1]));
|
std::vector<ParseAction*> actions = *(table.get(shift.second, input[i+1]));
|
||||||
for (std::vector<ParseAction*>::size_type j = 0; j < actions.size(); j++) {
|
for (std::vector<ParseAction*>::size_type j = 0; j < actions.size(); j++) {
|
||||||
if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() != 0)
|
if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() != 0) {
|
||||||
toReduce.push(std::make_pair(std::make_pair(shift.first, actions[j]->reduceRule->getLeftSide()), actions[j]->reduceRule->getRightSize()));
|
Reduction newReduction = {shift.first, actions[j]->reduceRule->getLeftSide(), actions[j]->reduceRule->getRightSize(), getNullableIndex(actions[j]->reduceRule), newLabel}
|
||||||
|
toReduce.push(newReduction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cout << "State did not already exist, adding" << std::endl;
|
std::cout << "State did not already exist, adding" << std::endl;
|
||||||
shiftTo = gss.newNode(shift.second);
|
shiftTo = gss.newNode(shift.second);
|
||||||
gss.addToFrontier(i+1, shiftTo);
|
gss.addToFrontier(i+1, shiftTo);
|
||||||
gss.addEdge(shiftTo, shift.first);
|
gss.addEdge(shiftTo, shift.first, newLabel);
|
||||||
std::vector<ParseAction*> actions = *(table.get(shift.second, input[i+1]));
|
std::vector<ParseAction*> actions = *(table.get(shift.second, input[i+1]));
|
||||||
for (std::vector<ParseAction*>::size_type j = 0; j < actions.size(); j++) {
|
for (std::vector<ParseAction*>::size_type j = 0; j < actions.size(); j++) {
|
||||||
std::cout << "Adding action " << actions[j]->toString() << " to either nextShifts or toReduce" << std::endl;
|
std::cout << "Adding action " << actions[j]->toString() << " to either nextShifts or toReduce" << std::endl;
|
||||||
//Shift
|
//Shift
|
||||||
if (actions[j]->action == ParseAction::SHIFT)
|
if (actions[j]->action == ParseAction::SHIFT) {
|
||||||
nextShifts.push(std::make_pair(shiftTo, actions[j]->shiftState));
|
nextShifts.push(std::make_pair(shiftTo, actions[j]->shiftState));
|
||||||
else if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() != 0)
|
} else if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() != 0) {
|
||||||
toReduce.push(std::make_pair(std::make_pair(shift.first, actions[j]->reduceRule->getLeftSide()), actions[j]->reduceRule->getRightSize()));
|
Reduction newReduction = {shift.first, actions[j]->reduceRule->getLeftSide(), actions[j]->reduceRule->getRightSize(), getNullableIndex(actions[j]->reduceRule), newLabel}
|
||||||
else if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() == 0)
|
toReduce.push(newReduction);
|
||||||
toReduce.push(std::make_pair(std::make_pair(shiftTo, actions[j]->reduceRule->getLeftSide()), actions[j]->reduceRule->getRightSize()));
|
} 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<Symbol*>("null", nullSymbol)}
|
||||||
|
toReduce.push(newReduction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,7 +241,7 @@ void RNGLRParser::shifter(int i) {
|
|||||||
|
|
||||||
void RNGLRParser::addChildren(NodeTree<Symbol*>* parent, std::vector<NodeTree<Symbol*>*>* children, int nullablePartsIndex) {
|
void RNGLRParser::addChildren(NodeTree<Symbol*>* parent, std::vector<NodeTree<Symbol*>*>* children, int nullablePartsIndex) {
|
||||||
if (nullablePartsIndex != 0)
|
if (nullablePartsIndex != 0)
|
||||||
children->push_back(nullableParts[nullablePartsIndex]);
|
children->push_back(getNullableParts(nullablePartsIndex);
|
||||||
if (!belongsToFamily(parent, children)) {
|
if (!belongsToFamily(parent, children)) {
|
||||||
if (parent->getChildren().size() == 0) {
|
if (parent->getChildren().size() == 0) {
|
||||||
parent->addChildren(children);
|
parent->addChildren(children);
|
||||||
@@ -200,7 +262,20 @@ void RNGLRParser::addChildren(NodeTree<Symbol*>* parent, std::vector<NodeTree<Sy
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RNGLRParser::belongsToFamily(NodeTree<Symbol*>* node, std::vector<NodeTree<Symbol*>*>* nodes) {
|
bool RNGLRParser::belongsToFamily(NodeTree<Symbol*>* node, std::vector<NodeTree<Symbol*>*>* nodes) {
|
||||||
//
|
std::vector<NodeTree<Symbol*>*> children = node->getChildren();
|
||||||
|
for (std::vector<NodeTree<Symbol*>*>::size_type i = 0; i < nodes->size(); i++) {
|
||||||
|
bool containsOne = false;
|
||||||
|
for (std::vector<NodeTree<Symbol*>*>::size_type j = 0; j < children.size(); j++) {
|
||||||
|
if ((*(*nodes)[i]) == *(children[j])) {
|
||||||
|
containsOne = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!containsOne) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RNGLRParser::arePacked(std::vector<NodeTree<Symbol*>*>* nodes) {
|
bool RNGLRParser::arePacked(std::vector<NodeTree<Symbol*>*>* nodes) {
|
||||||
@@ -329,3 +404,28 @@ bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector<Symbol*> avoidList)
|
|||||||
return reduces;
|
return reduces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RNGLRParser::getNullableIndex(ParseRule* rule) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeTree<Symbol*> RNGLRParser::getNullableParts(ParseRule* rule) {
|
||||||
|
return new NodeTree<Symbol*>("null", nullSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeTree<Symbol*> RNGLRParser::getNullableParts(Symbol* symbol) {
|
||||||
|
return new NodeTree<Symbol*>("null", nullSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeTree<Symbol*> RNGLRParser::getNullableParts(int index) {
|
||||||
|
if (index == 0)
|
||||||
|
return new NodeTree<Symbol*>("not_null", nullSymbol);
|
||||||
|
return new NodeTree<Symbol*>("null", nullSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<NodeTree<Symbol*>*> RNGLRParser::getPathEdges(std::vector<NodeTree<int>*> path) {
|
||||||
|
std::vector<NodeTree<Symbol*>*> pathEdges;
|
||||||
|
for (std::vector<NodeTree<int>*>::size_type i < path.size()-1; i++)
|
||||||
|
pathEdges.push_back(gss.getEdge(path[i], path[i+1]));
|
||||||
|
return pathEdges;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user