Have almost got the RNGLR recognizer. Something is wrong with the GSS, I think when it's built. It seems to sometimes have parents as children, or something.

This commit is contained in:
Nathan Braswell
2013-07-31 23:51:05 -04:00
parent 3fba45591b
commit 9887555dd5
12 changed files with 169 additions and 77 deletions

View File

@@ -4,7 +4,7 @@ project(Kraken)
set( MY_INCLUDES ${PROJECT_SOURCE_DIR}/include) set( MY_INCLUDES ${PROJECT_SOURCE_DIR}/include)
set( MY_SOURCES main.cpp src/Parser.cpp src/LALRParser.cpp src/ParseAction.cpp src/ParseRule.cpp src/Symbol.cpp src/StringReader.cpp src/State.cpp src/util.cpp src/Lexer.cpp src/RegEx.cpp src/RegExState.cpp src/Table.cpp ) set( MY_SOURCES main.cpp src/Parser.cpp src/LALRParser.cpp src/GraphStructuredStack.cpp src/RNGLRParser.cpp src/ParseAction.cpp src/ParseRule.cpp src/Symbol.cpp src/StringReader.cpp src/State.cpp src/util.cpp src/Lexer.cpp src/RegEx.cpp src/RegExState.cpp src/Table.cpp )
include_directories( ${MY_INCLUDES} ) include_directories( ${MY_INCLUDES} )

View File

@@ -1,6 +1,8 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include "NodeTree<int>.h" #include <queue>
#include "NodeTree.h"
#include "util.h"
#ifndef GRAPH_STRUCTURED_STACK #ifndef GRAPH_STRUCTURED_STACK
#define GRAPH_STRUCTURED_STACK #define GRAPH_STRUCTURED_STACK
@@ -17,7 +19,10 @@ class GraphStructuredStack {
std::vector<NodeTree<int>*>* getReachable(NodeTree<int>* start, int lenght); std::vector<NodeTree<int>*>* getReachable(NodeTree<int>* start, int lenght);
bool hasEdge(NodeTree<int>* start, NodeTree<int>* end); bool hasEdge(NodeTree<int>* start, NodeTree<int>* end);
void addEdge(NodeTree<int>* start, NodeTree<int>* end); void addEdge(NodeTree<int>* start, NodeTree<int>* end);
std::string toString();
private: private:
std::vector<std::vector<NodeTree<int>*>*> gss; std::vector<std::vector<NodeTree<int>*>*> gss;
//
}; };
#endif

View File

@@ -2,24 +2,7 @@
#define LALRPARSER_H #define LALRPARSER_H
#include "Parser.h" #include "Parser.h"
/*
#include "util.h"
#include "ParseRule.h"
#include "ParseAction.h"
#include "Symbol.h"
#include "State.h"
#include "StringReader.h"
#include "Lexer.h"
#include "NodeTree.h"
#include "Table.h"
#include <map>
#include <vector>
#include <algorithm>
#include <stack>
#include <string>
#include <iostream>
*/
class LALRParser: public Parser { class LALRParser: public Parser {
public: public:
LALRParser(); LALRParser();

View File

@@ -70,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) {
data = NULL;
this->name = name; this->name = name;
this->data = inData; this->data = inData;
id = idCounter++; id = idCounter++;
@@ -138,7 +137,7 @@ void NodeTree<T>::removeChild(NodeTree<T>* child) {
template<class T> template<class T>
std::vector<NodeTree<T>*> NodeTree<T>::getChildren() { std::vector<NodeTree<T>*> NodeTree<T>::getChildren() {
return &children; return children;
} }
template<class T> template<class T>

View File

@@ -1,17 +1,20 @@
#include <iostream> #include <iostream>
#include <queue>
#include "Parser.h"
#include "GraphStructuredStack.h"
class RNGLRParser { class RNGLRParser: public Parser {
public: public:
parseInput(std::string inputString); RNGLRParser();
reducer(int i); ~RNGLRParser();
shifter(int i); NodeTree<Symbol*>* parseInput(std::string inputString);
void reducer(int i);
void shifter(int i);
private: private:
Lexer lexer;
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; 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<NodeTree<int>*, int> > toShift; std::queue< std::pair<NodeTree<int>*, int> > toShift;
}; };

View File

@@ -20,6 +20,7 @@ class Symbol {
Symbol(std::string name, bool isTerminal, NodeTree<Symbol*>* tree); Symbol(std::string name, bool isTerminal, NodeTree<Symbol*>* tree);
~Symbol(); ~Symbol();
bool const operator==(const Symbol &other); bool const operator==(const Symbol &other);
bool const operator!=(const Symbol &other);
std::string getName(); std::string getName();
std::string toString(); std::string toString();
Symbol* clone(); Symbol* clone();

View File

@@ -14,6 +14,7 @@ class 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);
std::vector<ParseAction*>* get(int state, Symbol* token); std::vector<ParseAction*>* get(int state, Symbol* token);
ParseAction* getShift(int state, Symbol* token);
std::string toString(); std::string toString();
private: private:
std::vector< std::vector< std::vector<ParseAction*>* >* > table; std::vector< std::vector< std::vector<ParseAction*>* >* > table;

View File

@@ -2,6 +2,7 @@
#include "Symbol.h" #include "Symbol.h"
#include "Lexer.h" #include "Lexer.h"
#include "LALRParser.h" #include "LALRParser.h"
#include "RNGLRParser.h"
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
@@ -43,7 +44,8 @@ int main(int argc, char* argv[]) {
programInputFileString.append(line+"\n"); programInputFileString.append(line+"\n");
} }
LALRParser parser; //LALRParser parser;
RNGLRParser parser;
parser.loadGrammer(grammerInputFileString); parser.loadGrammer(grammerInputFileString);
//std::cout << "Creating State Set from Main" << std::endl; //std::cout << "Creating State Set from Main" << std::endl;
std::cout << "\n\n\n\n\n\n\n\n\n\nState Set" << std::endl; std::cout << "\n\n\n\n\n\n\n\n\n\nState Set" << std::endl;

View File

@@ -14,14 +14,16 @@ NodeTree<int>* GraphStructuredStack::newNode(int stateNum) {
void GraphStructuredStack::addToFrontier(int frontier, NodeTree<int>* 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 //First, make sure our vector has this and lesser frontiers. If not, add it and up to it
while (frontier >= gss.size()) { while (gss.size() <= frontier) {
std::cout << "Adding a new frontier: " << gss.size() << std::endl;
gss.push_back(new std::vector<NodeTree<int>*>()); gss.push_back(new std::vector<NodeTree<int>*>());
} }
std::cout << "Adding " << node << " (" << node->getData() << ") to frontier " << frontier << std::endl;
gss[frontier]->push_back(node); gss[frontier]->push_back(node);
} }
NodeTree<int>* GraphStructuredStack::inFrontier(int frontier, int state) { NodeTree<int>* GraphStructuredStack::inFrontier(int frontier, int state) {
if (frontierIsEmpty()) if (frontierIsEmpty(frontier))
return NULL; return NULL;
for (std::vector<NodeTree<int>*>::size_type i = 0; i < gss[frontier]->size(); i++) { for (std::vector<NodeTree<int>*>::size_type i = 0; i < gss[frontier]->size(); i++) {
if ((*(gss[frontier]))[i]->getData() == state) if ((*(gss[frontier]))[i]->getData() == state)
@@ -39,24 +41,31 @@ bool GraphStructuredStack::frontierHasAccState(int frontier) {
return inFrontier(frontier, 1); return inFrontier(frontier, 1);
} }
std::vector<NodeTree<int>*>* GraphStructuredStack::getReachable(NodeTree<int>* start, int lenght) { std::vector<NodeTree<int>*>* GraphStructuredStack::getReachable(NodeTree<int>* start, int length) {
std::vector<NodeTree<int>*>* reachableList = new std::vector<NodeTree<int>*>(); std::vector<NodeTree<int>*>* reachableList = new std::vector<NodeTree<int>*>();
std::queue<NodeTree<int>*> currentNodes; std::queue<NodeTree<int>*> currentNodes;
std::queue<NodeTree<int>*> nextNodes; std::queue<NodeTree<int>*> nextNodes;
currentNodes.push_back(start); currentNodes.push(start);
for (int i = 0; i < lenght; i++) { for (int i = 0; i < length; i++) {
while (!currentNodes.empty()) { while (!currentNodes.empty()) {
NodeTree<int>* currentNode = currentNodes.front(); NodeTree<int>* currentNode = currentNodes.front();
currentNodes.pop(); currentNodes.pop();
std::vector<NodeTree<T>*> children = currentNode->getChildren(); std::vector<NodeTree<int>*> children = currentNode->getChildren();
for (std::vector<NodeTree<T>*>::size_type j = 0; j < children.size(); j++) std::cout << currentNode->getData() << " has children ";
nextNodes.push_back(children[j]); for (std::vector<NodeTree<int>*>::size_type j = 0; j < children.size(); j++) {
std::cout << children[j]->getData() << " ";
nextNodes.push(children[j]);
}
std::cout << std::endl;
} }
currentNodes = nextNodes; currentNodes = nextNodes;
nextNodes.clear(); //No clear function, so go through and remove
while(!nextNodes.empty())
nextNodes.pop();
} }
while (!currentNodes.empty()) { while (!currentNodes.empty()) {
reachableList->push_back(currentNodes.front()); reachableList->push_back(currentNodes.front());
std::cout << currentNodes.front()->getData() << " is reachable from " << start->getData() << " by length " << length << std::endl;
currentNodes.pop(); currentNodes.pop();
} }
return reachableList; return reachableList;
@@ -71,3 +80,15 @@ void GraphStructuredStack::addEdge(NodeTree<int>* start, NodeTree<int>* end) {
start->addChild(end); start->addChild(end);
end->addChild(start); end->addChild(start);
} }
std::string GraphStructuredStack::toString() {
std::string tostring = "";
for (std::vector<std::vector<NodeTree<int>*>*>::size_type i = 0; i < gss.size(); i++) {
tostring += "Frontier: " + intToString(i) + "\n";
for (std::vector<NodeTree<int>*>::size_type j = 0; j < gss[i]->size(); j++) {
tostring += "|" + intToString((*(gss[i]))[j]->getData()) + "| ";
}
tostring += "\n";
}
return tostring;
}

View File

@@ -1,13 +1,28 @@
#include "RNGLRParser.h"
RNGLRParser::parseInput(std::string inputString) { RNGLRParser::RNGLRParser() {
//
}
RNGLRParser::~RNGLRParser() {
//
}
NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
//Check for no tokens //Check for no tokens
bool accepting = false;
if (inputString == "") { if (inputString == "") {
if (table.get(0,EOFSymbol)->action == ParseAction::REDUCE) std::vector<ParseAction*>* zeroStateActions = table.get(0,EOFSymbol);
for (int i = 0; i < zeroStateActions->size(); i++) {
if ((*zeroStateActions)[i]->action == ParseAction::REDUCE)
accepting = true;
}
if (accepting)
std::cout << "Accepted!" << std::endl; std::cout << "Accepted!" << std::endl;
else else
std::cout << "Rejected, no input (with no accepting state)" << std::endl; std::cout << "Rejected, no input (with no accepting state)" << std::endl;
return; return new NodeTree<Symbol*>();
} }
lexer.setInput(inputString); lexer.setInput(inputString);
@@ -15,51 +30,86 @@ RNGLRParser::parseInput(std::string inputString) {
//It could be converted to on-line later. //It could be converted to on-line later.
Symbol* currentToken = lexer.next(); Symbol* currentToken = lexer.next();
input.push_back(currentToken); input.push_back(currentToken);
while (*currentToken != *EOFToken) { while (*currentToken != *EOFSymbol) {
std::cout << EOFSymbol->toString() << " " << currentToken->toString() << std::endl;
currentToken = lexer.next(); currentToken = lexer.next();
input.push_back(currentToken); input.push_back(currentToken);
} }
std::cout << "\n\n\nDone with Lexing\n\n\n" << std::endl;
for (int i = 0; i < input.size(); i++)
std::cout << "|" << input[i]->toString() << "|";
std::cout << std::endl;
std::cout << "Setting up 0th frontier, first actions, toShift, toReduce" << std::endl;
//Frontier 0, new node with state 0 //Frontier 0, new node with state 0
NodeTree<int>* 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::cout << "Done setting up new frontier" << std::endl;
std::vector<ParseAction*> firstActions = *(table.get(0, input[0]));
for (std::vector<ParseAction*>::size_type i = 0; i < firstActions.size(); i++) { for (std::vector<ParseAction*>::size_type i = 0; i < firstActions.size(); i++) {
if (firstActions[i]->action == ParseAction::SHIFT) if (firstActions[i]->action == ParseAction::SHIFT)
toShift.push_back(std::make_pair(v0,firstActions[i]->toState())); 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_back(std::make_pair(std::make_pair(v0, firstActions[i]->reduceRule->getLeftSide()), 0)); toReduce.push(std::make_pair(std::make_pair(v0, firstActions[i]->reduceRule->getLeftSide()), 0));
} }
} }
std::cout << "GSS:\n" << gss.toString() << std::endl;
std::cout << "Starting parse loop" << std::endl;
for (int i = 0; i < input.size(); i++) { for (int i = 0; i < input.size(); i++) {
if (gss.frontierIsEmpty(i)) std::cout << "Checking if frontier " << i << " is empty" << std::endl;
if (gss.frontierIsEmpty(i)) {
std::cout << "Frontier " << i << " is empty." << std::endl;
break; break;
while (toReduce.size() != 0) }
while (toReduce.size() != 0) {
std::cout << "Reducing for " << i << std::endl;
//std::cout << "GSS:\n" << gss.toString() << std::endl;
reducer(i); reducer(i);
}
std::cout << "Shifting for " << i << std::endl;
shifter(i); shifter(i);
std::cout << "GSS:\n" << gss.toString() << std::endl;
} }
if (gss.frontierHasAccSt(input.size()-1)) std::cout << "Done with parsing loop, checking for acceptance" << std::endl;
if (gss.frontierHasAccState(input.size()-1))
std::cout << "Accepted!" << std::endl; std::cout << "Accepted!" << std::endl;
else else
std::cout << "Rejected!" << std::endl; std::cout << "Rejected!" << std::endl;
return;
std::cout << "GSS:\n" << gss.toString() << std::endl;
return new NodeTree<Symbol*>();
} }
RNGLRParser::reducer(int i) { void RNGLRParser::reducer(int i) {
std::pair< std::pair<NodeTree<int>*, 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; toReduce.pop();
std::cout << "Doing reduction of length " << reduction.second << " from state " << reduction.first.first->getData() << " to symbol " << reduction.first.second->toString() << std::endl;
int pathLength = reduction.second > 0 ? reduction.second -1 : 0;
std::vector<NodeTree<int>*>* reachable = gss.getReachable(reduction.first.first, pathLength); std::vector<NodeTree<int>*>* reachable = gss.getReachable(reduction.first.first, pathLength);
for (std::vector<NodeTree<int>*>::size_type j = 0; j < reachable->size(); j++) { for (std::vector<NodeTree<int>*>::size_type j = 0; j < reachable->size(); j++) {
NodeTree<int>* currentReached = (*reachable)[j]; NodeTree<int>* currentReached = (*reachable)[j];
int toState = table.getShift(currentReached->state(), reduction.first.second); std::cout << "Getting the shfit state for state " << currentReached->getData() << " and symbol " << reduction.first.second->toString() << std::endl;
int toState = table.getShift(currentReached->getData(), reduction.first.second)->shiftState;
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);
if (reduction.second != 0) { if (reduction.second != 0) {
//Do all non null reductions //Do all non null reduction
std::vector<ParseAction*> actions = *(table.get(toState, input[i]));
for (std::vector<ParseAction*>::size_type k = 0; k < actions.size(); k++)
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()));
} }
} }
} else { } else {
@@ -67,47 +117,51 @@ RNGLRParser::reducer(int i) {
gss.addToFrontier(i, toStateNode); gss.addToFrontier(i, toStateNode);
gss.addEdge(toStateNode, currentReached); gss.addEdge(toStateNode, currentReached);
std::vector<ParseAction*> actions = table.get(toState, input[i+1]); 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++) {
//Shift //Shift
if (actions[k]->action == ParseAction::SHIFT) if (actions[k]->action == ParseAction::SHIFT)
nextShifts.push_back(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()->size() != 0) else if (actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule->getRightSize() != 0)
toReduce.push_back(std::make_pair(std::make_pair(currentReached, actions[k]->reduceRule->getLeftSide()), actions[k]->reduceRule->size())); toReduce.push(std::make_pair(std::make_pair(currentReached, actions[k]->reduceRule->getLeftSide()), actions[k]->reduceRule->getRightSize()));
else (actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule()->size() == 0) else if (actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule->getRightSize() == 0)
toReduce.push_back(std::make_pair(std::make_pair(toStateNode, actions[k]->reduceRule->getLeftSide()), actions[k]->reduceRule->size())); toReduce.push(std::make_pair(std::make_pair(toStateNode, actions[k]->reduceRule->getLeftSide()), actions[k]->reduceRule->getRightSize()));
} }
} }
} }
} }
RNGLRParser::shifter(int i) { void RNGLRParser::shifter(int i) {
if (i != input.length()-1) { if (i != input.size()-1) {
std::queue<ParseAction*> nextShifts; std::queue< std::pair<NodeTree<int>*, int> > nextShifts;
while (!toShift.empty()) { while (!toShift.empty()) {
std::pair<NodeTree<int>*, int> shift = toShift.front(); std::pair<NodeTree<int>*, int> shift = toShift.front();
toShift.pop();
std::cout << "Current potential shift from " << shift.first->getData() << " to " << shift.second << std::endl;
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;
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+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->size() != 0) if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() != 0)
toReduce.push_back(std::make_pair(std::make_pair(shift.first, actions[j]->reduceRule->getLeftSide()), actions[j]->reduceRule->size())); toReduce.push(std::make_pair(std::make_pair(shift.first, actions[j]->reduceRule->getLeftSide()), actions[j]->reduceRule->getRightSize()));
} }
} else { } else {
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);
std::vector<ParseAction*> actions = table.get(shift.toState(), input[i+2]); 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;
//Shift //Shift
if (actions[j]->action == ParseAction::SHIFT) if (actions[j]->action == ParseAction::SHIFT)
nextShifts.push_back(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()->size() != 0) else if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() != 0)
toReduce.push_back(std::make_pair(std::make_pair(shift.first, actions[j]->reduceRule->getLeftSide()), actions[j]->reduceRule->size())); toReduce.push(std::make_pair(std::make_pair(shift.first, actions[j]->reduceRule->getLeftSide()), actions[j]->reduceRule->getRightSize()));
else (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule()->size() == 0) else if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() == 0)
toReduce.push_back(std::make_pair(std::make_pair(shiftTo, actions[j]->reduceRule->getLeftSide()), actions[j]->reduceRule->size())); toReduce.push(std::make_pair(std::make_pair(shiftTo, actions[j]->reduceRule->getLeftSide()), actions[j]->reduceRule->getRightSize()));
} }
} }
} }

View File

@@ -28,6 +28,10 @@ const bool Symbol::operator==(const Symbol &other) {
return( name == other.name && terminal == other.terminal); return( name == other.name && terminal == other.terminal);
} }
const bool Symbol::operator!=(const Symbol &other) {
return(!this->operator==(other));
}
std::string Symbol::getName() { std::string Symbol::getName() {
return(name); return(name);
} }

View File

@@ -80,10 +80,17 @@ std::vector<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 if (symbolIndex == -1) {
//(This assumes singular goal assignment, a simplification for now) std::cout << "Unrecognized symbol: " << token->toString() << ", cannot get from table!" << std::endl;
return NULL;
}
std::cout << "Get for state: " << state << ", and Symbol: " << token->toString() << std::endl;
std::vector<ParseAction*>* action = (*(table[state]))[symbolIndex]; std::vector<ParseAction*>* action = (*(table[state]))[symbolIndex];
//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) { if (state == 1 && symbolIndex == 0) {
if (action == NULL) if (action == NULL)
action = new std::vector<ParseAction*>(); action = new std::vector<ParseAction*>();
@@ -106,6 +113,18 @@ std::vector<ParseAction*>* Table::get(int state, Symbol* token) {
return (action); return (action);
} }
ParseAction* Table::getShift(int state, Symbol* token) {
std::vector<ParseAction*>* actions = get(state, token);
ParseAction* shift = NULL;
for (int i = 0; i < actions->size(); i++) {
if ((*actions)[i]->action == ParseAction::SHIFT) {
shift = (*actions)[i];
break;
}
}
return shift;
}
std::string Table::toString() { std::string Table::toString() {
std::string concat = ""; std::string concat = "";
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++)