Made Symbol always stack, not heap, allocated. Finally fixed bugs with ASTTransformation.

This commit is contained in:
Nathan Braswell
2013-10-02 03:15:20 -04:00
parent 0110672f50
commit b9ffe33d0b
25 changed files with 375 additions and 278 deletions

View File

@@ -3,10 +3,9 @@
ASTData::ASTData(ASTType type, ValueType valueType) {
this->type = type;
this->valueType = valueType;
this->symbol = NULL;
}
ASTData::ASTData(ASTType type, Symbol* symbol, ValueType valueType) {
ASTData::ASTData(ASTType type, Symbol symbol, ValueType valueType) {
this->type = type;
this->valueType = valueType;
this->symbol = symbol;
@@ -15,3 +14,7 @@ ASTData::ASTData(ASTType type, Symbol* symbol, ValueType valueType) {
ASTData::~ASTData() {
}
std::string ASTData::toString() {
return "ASTData!";
}

View File

@@ -8,6 +8,6 @@ ASTTransformation::~ASTTransformation() {
//
}
virtual NodeTree<Symbol*>* ASTTransformation::transform(NodeTree<ASTData>* from) {
NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
return NULL;
}

View File

@@ -107,11 +107,11 @@ bool GraphStructuredStack::hasEdge(NodeTree<int>* start, NodeTree<int>* end) {
return start->findChild(end) != -1;
}
NodeTree<Symbol*>* GraphStructuredStack::getEdge(NodeTree<int>* start, NodeTree<int>* end) {
NodeTree<Symbol>* GraphStructuredStack::getEdge(NodeTree<int>* start, NodeTree<int>* end) {
return edges[std::make_pair(start, end)];
}
void GraphStructuredStack::addEdge(NodeTree<int>* start, NodeTree<int>* end, NodeTree<Symbol*>* edge) {
void GraphStructuredStack::addEdge(NodeTree<int>* start, NodeTree<int>* end, NodeTree<Symbol>* edge) {
start->addChild(end);
end->addParent(start);
edges[std::make_pair(start, end)] = edge;

View File

@@ -7,14 +7,14 @@ LALRParser::~LALRParser() {
//Nothing to do in this version
}
NodeTree<Symbol*>* LALRParser::parseInput(std::string inputString) {
NodeTree<Symbol>* LALRParser::parseInput(std::string inputString) {
lexer.setInput(inputString);
Symbol* token = lexer.next();
Symbol token = lexer.next();
std::vector<ParseAction*>* actionList;
ParseAction* action;
stateStack.push(0);
symbolStack.push(new Symbol("INVALID", false));
symbolStack.push(Symbol("INVALID", false));
while (true) {
std::cout << "In state: " << intToString(stateStack.top()) << std::endl;
@@ -28,18 +28,18 @@ NodeTree<Symbol*>* LALRParser::parseInput(std::string inputString) {
int rightSideLength = action->reduceRule->getRightSide().size();
//Keep track of symbols popped for parse tree
std::vector<Symbol*> poppedSymbols;
std::vector<Symbol> poppedSymbols;
for (int i = 0; i < rightSideLength; i++) {
poppedSymbols.push_back(symbolStack.top());
stateStack.pop();
symbolStack.pop();
}
std::reverse(poppedSymbols.begin(), poppedSymbols.end()); //To put in order
//Assign the new tree to the new Symbol
Symbol* newSymbol = action->reduceRule->getLeftSide()->clone();
newSymbol->setSubTree(reduceTreeCombine(newSymbol, poppedSymbols));
//Assign the new tree to the Symbol
Symbol newSymbol = action->reduceRule->getLeftSide();
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;
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];
@@ -50,7 +50,7 @@ NodeTree<Symbol*>* LALRParser::parseInput(std::string inputString) {
break;
}
case ParseAction::SHIFT:
std::cout << "Shift " << token->toString() << std::endl;
std::cout << "Shift " << token.toString() << std::endl;
symbolStack.push(token);
token = lexer.next();
@@ -58,11 +58,11 @@ NodeTree<Symbol*>* LALRParser::parseInput(std::string inputString) {
break;
case ParseAction::ACCEPT:
std::cout << "ACCEPTED!" << std::endl;
return(symbolStack.top()->getSubTree());
return(symbolStack.top().getSubTree());
break;
case ParseAction::REJECT:
std::cout << "REJECTED!" << std::endl;
std::cout << "REJECTED Symbol was " << token->toString() << std::endl;
std::cout << "REJECTED Symbol was " << token.toString() << std::endl;
return(NULL);
break;
default:

View File

@@ -22,11 +22,11 @@ void Lexer::addRegEx(std::string regExString) {
regExs.push_back(new RegEx(regExString));
}
Symbol* Lexer::next() {
Symbol Lexer::next() {
//std::cout << "Current at is \"" << input.substr(currentPosition,input.length()-1) << "\" currentPos is " << currentPosition << " out of " << input.length() <<std::endl;
//If we're at the end, return an eof
if (currentPosition >= input.length()-1)
return new Symbol("$EOF$", true);
return Symbol("$EOF$", true);
int longestMatch = -1;
RegEx* longestRegEx = NULL;
std::string remainingString = input.substr(currentPosition,input.length()-1);
@@ -42,10 +42,10 @@ Symbol* Lexer::next() {
std::string eatenString = input.substr(currentPosition, longestMatch+1);
currentPosition += longestMatch + 1;
//std::cout << "Current at is \"" << input.substr(currentPosition,input.length()-1) << "\" currentPos is " << currentPosition <<std::endl;
return new Symbol(longestRegEx->getPattern(), true, eatenString);
return Symbol(longestRegEx->getPattern(), true, eatenString);
} else {
//std::cout << "Found no applicable regex" << std::endl;
//std::cout << "Remaining is ||" << input.substr(currentPosition,input.length()-1) << "||" << std::endl;
return NULL;
return Symbol();
}
}

View File

@@ -2,11 +2,10 @@
ParseRule::ParseRule() {
pointerIndex = 0;
leftHandle = NULL;
lookahead = NULL;
}
ParseRule::ParseRule(Symbol* leftHandle, int pointerIndex, std::vector<Symbol*> &rightSide, std::vector<Symbol*>* lookahead) {
ParseRule::ParseRule(Symbol leftHandle, int pointerIndex, std::vector<Symbol> &rightSide, std::vector<Symbol>* lookahead) {
this->leftHandle = leftHandle;
this->pointerIndex = pointerIndex;
this->rightSide = rightSide;
@@ -33,35 +32,35 @@ ParseRule* ParseRule::clone() {
return( new ParseRule(leftHandle, pointerIndex, rightSide, lookahead) );
}
void ParseRule::setLeftHandle(Symbol* leftHandle) {
void ParseRule::setLeftHandle(Symbol leftHandle) {
this->leftHandle = leftHandle;
}
void ParseRule::appendToRight(Symbol* appendee) {
void ParseRule::appendToRight(Symbol appendee) {
rightSide.push_back(appendee);
}
Symbol* ParseRule::getLeftSide() {
Symbol ParseRule::getLeftSide() {
return leftHandle;
}
void ParseRule::setRightSide(std::vector<Symbol*> rightSide) {
void ParseRule::setRightSide(std::vector<Symbol> rightSide) {
this->rightSide = rightSide;
}
std::vector<Symbol*> ParseRule::getRightSide() {
std::vector<Symbol> ParseRule::getRightSide() {
return rightSide;
}
Symbol* ParseRule::getAtNextIndex() {
Symbol ParseRule::getAtNextIndex() {
if (pointerIndex >= rightSide.size())
return NULL;
return Symbol();
return rightSide[pointerIndex];
}
Symbol* ParseRule::getAtIndex() {
Symbol ParseRule::getAtIndex() {
if (pointerIndex < 1)
return NULL;
return Symbol();
return rightSide[pointerIndex-1];
}
@@ -85,15 +84,15 @@ bool ParseRule::isAtEnd() {
return pointerIndex == rightSide.size();
}
void ParseRule::setLookahead(std::vector<Symbol*>* lookahead) {
void ParseRule::setLookahead(std::vector<Symbol>* lookahead) {
this->lookahead = lookahead;
}
void ParseRule::addLookahead(std::vector<Symbol*>* lookahead) {
for (std::vector<Symbol*>::size_type i = 0; i < lookahead->size(); i++) {
void ParseRule::addLookahead(std::vector<Symbol>* lookahead) {
for (std::vector<Symbol>::size_type i = 0; i < lookahead->size(); i++) {
bool alreadyIn = false;
for (std::vector<Symbol*>::size_type j = 0; j < this->lookahead->size(); j++) {
if (*((*lookahead)[i]) == *((*(this->lookahead))[j])) {
for (std::vector<Symbol>::size_type j = 0; j < this->lookahead->size(); j++) {
if ((*lookahead)[i] == (*(this->lookahead))[j]) {
alreadyIn = true;
break;
}
@@ -103,23 +102,23 @@ void ParseRule::addLookahead(std::vector<Symbol*>* lookahead) {
}
}
std::vector<Symbol*>* ParseRule::getLookahead() {
std::vector<Symbol>* ParseRule::getLookahead() {
return lookahead;
}
std::string ParseRule::toString() {
std::string concat = leftHandle->toString() + " -> ";
std::string concat = leftHandle.toString() + " -> ";
for (int i = 0; i < rightSide.size(); i++) {
if (i == pointerIndex)
concat += "(*) ";
concat += rightSide[i]->toString() + " ";
concat += rightSide[i].toString() + " ";
}
if (pointerIndex >= rightSide.size())
concat += "(*)";
if (lookahead != NULL) {
concat += "**";
for (std::vector<Symbol*>::size_type i = 0; i < lookahead->size(); i++)
concat += (*lookahead)[i]->toString();
for (std::vector<Symbol>::size_type i = 0; i < lookahead->size(); i++)
concat += (*lookahead)[i].toString();
concat += "**";
}
return(concat);
@@ -128,7 +127,7 @@ std::string ParseRule::toString() {
std::string ParseRule::toDOT() {
std::string concat = "";
for (int i = 0; i < rightSide.size(); i++) {
concat += leftHandle->toString() + " -> " + rightSide[i]->toString() + ";\n";
concat += leftHandle.toString() + " -> " + rightSide[i].toString() + ";\n";
}
return(concat);
}

View File

@@ -1,21 +1,17 @@
#include "Parser.h"
Parser::Parser() {
EOFSymbol = new Symbol("$EOF$", true);
nullSymbol = new Symbol("$NULL$", true);
Parser::Parser() : EOFSymbol("$EOF$", true), nullSymbol("$NULL$", true){
table.setSymbols(EOFSymbol, nullSymbol);
}
Parser::~Parser() {
delete EOFSymbol;
delete nullSymbol;
}
Symbol* Parser::getOrAddSymbol(std::string symbolString, bool isTerminal) {
Symbol* symbol;
Symbol Parser::getOrAddSymbol(std::string symbolString, bool isTerminal) {
Symbol symbol;
std::pair<std::string, bool> entry = std::make_pair(symbolString, isTerminal);
if (symbols.find(entry) == symbols.end()) {
symbol = new Symbol(symbolString, isTerminal);
symbol = Symbol(symbolString, isTerminal);
symbols[entry] = symbol;
} else {
symbol = symbols[entry];
@@ -31,10 +27,10 @@ void Parser::loadGrammer(std::string grammerInputString) {
while(currToken != "") {
//Load the left of the rule
ParseRule* currentRule = new ParseRule();
Symbol* leftSide = getOrAddSymbol(currToken, false); //Left handle is never a terminal
Symbol leftSide = getOrAddSymbol(currToken, false); //Left handle is never a terminal
currentRule->setLeftHandle(leftSide);
reader.word(); //Remove the =
//Add the right side, adding new Symbols to symbol map.
//Add the right side, adding Symbols to symbol map.
currToken = reader.word();
while (currToken != ";") {
@@ -84,7 +80,7 @@ void Parser::createStateSet() {
//Set the first state's basis to be the goal rule with lookahead EOF
ParseRule* goalRule = loadedGrammer[0]->clone();
std::vector<Symbol*>* goalRuleLookahead = new std::vector<Symbol*>();
std::vector<Symbol>* goalRuleLookahead = new std::vector<Symbol>();
goalRuleLookahead->push_back(EOFSymbol);
goalRule->setLookahead(goalRuleLookahead);
State* zeroState = new State(0, goalRule);
@@ -111,38 +107,38 @@ int Parser::stateNum(State* state) {
return -1;
}
std::vector<Symbol*>* Parser::firstSet(Symbol* token) {
std::vector<Symbol*> avoidList;
std::vector<Symbol>* Parser::firstSet(Symbol token) {
std::vector<Symbol> avoidList;
return firstSet(token, avoidList);
}
std::vector<Symbol*>* Parser::firstSet(Symbol* token, std::vector<Symbol*> avoidList) {
std::vector<Symbol>* Parser::firstSet(Symbol token, std::vector<Symbol> avoidList) {
//If we've already done this token, don't do it again
for (std::vector<Symbol*>::size_type i = 0; i < avoidList.size(); i++)
if (*(avoidList[i]) == *token) {
return new std::vector<Symbol*>();
for (std::vector<Symbol>::size_type i = 0; i < avoidList.size(); i++)
if (avoidList[i] == token) {
return new std::vector<Symbol>();
}
avoidList.push_back(token);
std::vector<Symbol*>* first = new std::vector<Symbol*>();
std::vector<Symbol>* first = new std::vector<Symbol>();
//First, if the symbol is a terminal, than it's first set is just itself.
if (token->isTerminal()) {
if (token.isTerminal()) {
first->push_back(token);
return(first);
}
//Otherwise....
//Ok, to make a first set, go through the grammer, if the token it's left side, add it's production's first token's first set.
//If that one includes mull, do the next one too (if it exists).
Symbol* rightToken = NULL;
std::vector<Symbol*>* recursiveFirstSet = NULL;
Symbol rightToken;
std::vector<Symbol>* recursiveFirstSet = NULL;
for (std::vector<ParseRule*>::size_type i = 0; i < loadedGrammer.size(); i++) {
if (*token == *(loadedGrammer[i]->getLeftSide())) {
if (token == loadedGrammer[i]->getLeftSide()) {
//Loop through the rule adding first sets for each token if the previous token contained NULL
bool recFirstSetHasNull = false;
int j = 0;
do {
rightToken = loadedGrammer[i]->getRightSide()[j]; //Get token of the right side of this rule
if (rightToken->isTerminal()) {
recursiveFirstSet = new std::vector<Symbol*>();
if (rightToken.isTerminal()) {
recursiveFirstSet = new std::vector<Symbol>();
recursiveFirstSet->push_back(rightToken);
} else {
//Add the entire set
@@ -151,8 +147,8 @@ std::vector<Symbol*>* Parser::firstSet(Symbol* token, std::vector<Symbol*> avoid
first->insert(first->end(), recursiveFirstSet->begin(), recursiveFirstSet->end());
//Check to see if the current recursiveFirstSet contains NULL, if so, then go through again with the next token. (if there is one)
recFirstSetHasNull = false;
for (std::vector<Symbol*>::size_type k = 0; k < recursiveFirstSet->size(); k++) {
if ((*(*recursiveFirstSet)[k]) == *nullSymbol) {
for (std::vector<Symbol>::size_type k = 0; k < recursiveFirstSet->size(); k++) {
if ((*recursiveFirstSet)[k] == nullSymbol) {
recFirstSetHasNull = true;
}
}
@@ -165,20 +161,20 @@ std::vector<Symbol*>* Parser::firstSet(Symbol* token, std::vector<Symbol*> avoid
}
//Return the correct lookahead. This followSet is built based on the current rule's lookahead if at end, or the next Symbol's first set.
std::vector<Symbol*>* Parser::incrementiveFollowSet(ParseRule* rule) {
std::vector<Symbol>* Parser::incrementiveFollowSet(ParseRule* rule) {
//Advance the pointer past the current Symbol (the one we want the followset for) to the next symbol (which might be in our follow set, or might be the end)
rule = rule->clone();
rule->advancePointer();
//Get the first set of the next Symbol. If it contains nullSymbol, keep doing for the next one
std::vector<Symbol*>* followSet = new std::vector<Symbol*>();
std::vector<Symbol*>* symbolFirstSet;
std::vector<Symbol>* followSet = new std::vector<Symbol>();
std::vector<Symbol>* symbolFirstSet;
bool symbolFirstSetHasNull = true;
while (symbolFirstSetHasNull && !rule->isAtEnd()) {
symbolFirstSetHasNull = false;
symbolFirstSet = firstSet(rule->getAtNextIndex());
for (std::vector<Symbol*>::size_type i = 0; i < symbolFirstSet->size(); i++) {
if (*((*symbolFirstSet)[i]) == *nullSymbol) {
for (std::vector<Symbol>::size_type i = 0; i < symbolFirstSet->size(); i++) {
if ((*symbolFirstSet)[i] == nullSymbol) {
symbolFirstSetHasNull = true;
symbolFirstSet->erase(symbolFirstSet->begin()+i);
break;
@@ -192,11 +188,11 @@ std::vector<Symbol*>* Parser::incrementiveFollowSet(ParseRule* rule) {
symbolFirstSet = rule->getLookahead();
followSet->insert(followSet->end(), symbolFirstSet->begin(), symbolFirstSet->end());
}
std::vector<Symbol*>* followSetReturn = new std::vector<Symbol*>();
for (std::vector<Symbol*>::size_type i = 0; i < followSet->size(); i++) {
std::vector<Symbol>* followSetReturn = new std::vector<Symbol>();
for (std::vector<Symbol>::size_type i = 0; i < followSet->size(); i++) {
bool alreadyIn = false;
for (std::vector<Symbol*>::size_type j = 0; j < followSetReturn->size(); j++)
if (*((*followSet)[i]) == *((*followSetReturn)[j])) {
for (std::vector<Symbol>::size_type j = 0; j < followSetReturn->size(); j++)
if ((*followSet)[i] == (*followSetReturn)[j]) {
alreadyIn = true;
break;
}
@@ -216,7 +212,7 @@ void Parser::closure(State* state) {
for (std::vector<ParseRule*>::size_type j = 0; j < loadedGrammer.size(); j++) {
//If the current symbol in the rule is not null (rule completed) and it equals a grammer's left side
ParseRule* currentGramRule = loadedGrammer[j]->clone();
if ( !currentStateRule->isAtEnd() && *(currentStateRule->getAtNextIndex()) == *(currentGramRule->getLeftSide())) {
if ( !currentStateRule->isAtEnd() && currentStateRule->getAtNextIndex() == currentGramRule->getLeftSide()) {
//std::cout << (*stateTotal)[i]->getAtNextIndex()->toString() << " has an applicable production " << loadedGrammer[j]->toString() << std::endl;
//Now, add the correct lookahead. This followSet is built based on the current rule's lookahead if at end, or the next Symbol's first set.
//std::cout << "Setting lookahead for " << currentGramRule->toString() << " in state " << state->toString() << std::endl;
@@ -259,7 +255,7 @@ void Parser::addStates(std::vector< State* >* stateSets, State* state, std::queu
//If not, create it.
bool symbolAlreadyInState = false;
for (std::vector< State* >::size_type j = 0; j < newStates.size(); j++) {
if (*(newStates[j]->basis[0]->getAtIndex()) == *(advancedRule->getAtIndex())) {
if (newStates[j]->basis[0]->getAtIndex() == advancedRule->getAtIndex()) {
symbolAlreadyInState = true;
//So now check to see if this exact rule is in this state
if (!newStates[j]->containsRule(advancedRule))
@@ -276,21 +272,21 @@ void Parser::addStates(std::vector< State* >* stateSets, State* state, std::queu
//Also add any completed rules as reduces in the action table
//See if reduce
//Also, this really only needs to be done for the state's basis, but we're already iterating through, so...
std::vector<Symbol*>* lookahead = (*currStateTotal)[i]->getLookahead();
std::vector<Symbol>* lookahead = (*currStateTotal)[i]->getLookahead();
if ((*currStateTotal)[i]->isAtEnd()) {
for (std::vector<Symbol*>::size_type j = 0; j < lookahead->size(); j++)
for (std::vector<Symbol>::size_type j = 0; j < lookahead->size(); j++)
table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i]));
} else if (*((*currStateTotal)[i]->getAtNextIndex()) == *nullSymbol) {
} else if ((*currStateTotal)[i]->getAtNextIndex() == nullSymbol) {
//If is a rule that produces only NULL, add in the approprite reduction, but use a new rule with a right side of length 0. (so we don't pop off stack)
ParseRule* nullRule = (*currStateTotal)[i]->clone();
nullRule->setRightSide(* new std::vector<Symbol*>());
for (std::vector<Symbol*>::size_type j = 0; j < lookahead->size(); j++)
nullRule->setRightSide(* new std::vector<Symbol>());
for (std::vector<Symbol>::size_type j = 0; j < lookahead->size(); j++)
table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, nullRule));
}
}
//Put all our new states in the set of states only if they're not already there.
bool stateAlreadyInAllStates = false;
Symbol* currStateSymbol;
Symbol currStateSymbol;
for (std::vector< State * >::size_type i = 0; i < newStates.size(); i++) {
stateAlreadyInAllStates = false;
currStateSymbol = (*(newStates[i]->getBasis()))[0]->getAtIndex();
@@ -327,13 +323,13 @@ std::string Parser::tableToString() {
//parseInput is now pure virtual
NodeTree<Symbol*>* Parser::reduceTreeCombine(Symbol* newSymbol, std::vector<Symbol*> &symbols) {
NodeTree<Symbol*>* newTree = new NodeTree<Symbol*>(newSymbol->getName(), newSymbol);
for (std::vector<Symbol*>::size_type i = 0; i < symbols.size(); i++) {
if (symbols[i]->isTerminal())
newTree->addChild(new NodeTree<Symbol*>(symbols[i]->getName(), symbols[i]));
NodeTree<Symbol>* Parser::reduceTreeCombine(Symbol newSymbol, std::vector<Symbol> &symbols) {
NodeTree<Symbol>* newTree = new NodeTree<Symbol>(newSymbol.getName(), newSymbol);
for (std::vector<Symbol>::size_type i = 0; i < symbols.size(); i++) {
if (symbols[i].isTerminal())
newTree->addChild(new NodeTree<Symbol>(symbols[i].getName(), symbols[i]));
else
newTree->addChild(symbols[i]->getSubTree());
newTree->addChild(symbols[i].getSubTree());
}
return(newTree);
}

View File

@@ -8,7 +8,7 @@ RNGLRParser::~RNGLRParser() {
//
}
NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
NodeTree<Symbol>* RNGLRParser::parseInput(std::string inputString) {
//Check for no tokens
bool accepting = false;
@@ -24,23 +24,17 @@ NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
} else {
std::cout << "Rejected, no input (with no accepting state)" << std::endl;
}
return new NodeTree<Symbol*>();
return new NodeTree<Symbol>();
}
lexer.setInput(inputString);
//Now fully lex our input because this algorithm was designed in that manner and simplifies this first implementation.
//It could be converted to on-line later.
Symbol* currentToken = lexer.next();
Symbol currentToken = lexer.next();
input.push_back(currentToken);
while (*currentToken != *EOFSymbol) {
//std::cout << EOFSymbol->toString() << " " << currentToken->toString() << std::endl;
while (currentToken != EOFSymbol) {
currentToken = lexer.next();
if (currentToken != NULL) {
input.push_back(currentToken);
} else {
std::cout << "Rejected, lexer unable to fully tokenize sentence" << std::endl;
return new NodeTree<Symbol*>();
}
input.push_back(currentToken);
}
std::cout << "\nDone with Lexing\n" << std::endl;
@@ -78,11 +72,11 @@ NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
// std::cout << "Checking if frontier " << i << " is empty" << std::endl;
if (gss.frontierIsEmpty(i)) {
std::cout << "Frontier " << i << " is empty." << std::endl;
std::cout << "Failed on " << input[i]->toString() << std::endl;
std::cout << "Failed on " << input[i].toString() << std::endl;
std::cout << "Nearby is:" << std::endl;
int range = 5;
for (int j = (i-range >= 0 ? i-range : 0); j < (i+range < input.size() ? i+range : input.size()); j++)
std::cout << input[j]->toString() << " ";
std::cout << input[j].toString() << " ";
std::cout << std::endl;
break;
}
@@ -124,7 +118,7 @@ void RNGLRParser::reducer(int i) {
std::vector<NodeTree<int>*> currentPath = (*paths)[j];
//Get the edges for the current path
std::vector<NodeTree<Symbol*>*> pathEdges = getPathEdges(currentPath);
std::vector<NodeTree<Symbol>*> pathEdges = getPathEdges(currentPath);
std::reverse(pathEdges.begin(), pathEdges.end());
//If the reduction length is 0, label as passed in is null
if (reduction.length != 0)
@@ -132,24 +126,24 @@ void RNGLRParser::reducer(int i) {
//The end of the current path
NodeTree<int>* currentReached = currentPath[currentPath.size()-1];
std::cout << "Getting the shfit state for state " << currentReached->getData() << " and symbol " << reduction.symbol->toString() << std::endl;
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;
NodeTree<Symbol>* newLabel = NULL;
if (reduction.length == 0) {
newLabel = reduction.nullableParts;
} 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->getData()) == *(reduction.symbol)) {
for (std::vector<std::pair<NodeTree<Symbol>*, int> >::size_type k = 0; k < SPPFStepNodes.size(); k++) {
if ( SPPFStepNodes[k].second == reachedFrontier && SPPFStepNodes[k].first->getData() == reduction.symbol) {
newLabel = SPPFStepNodes[k].first;
break;
}
}
if (!newLabel) {
newLabel = new NodeTree<Symbol*>("frontier: " + intToString(reachedFrontier), reduction.symbol);
newLabel = new NodeTree<Symbol>("frontier: " + intToString(reachedFrontier), reduction.symbol);
SPPFStepNodes.push_back(std::make_pair(newLabel, reachedFrontier));
}
}
@@ -198,7 +192,7 @@ void RNGLRParser::reducer(int i) {
void RNGLRParser::shifter(int i) {
if (i != input.size()-1) {
std::queue< std::pair<NodeTree<int>*, int> > nextShifts;
NodeTree<Symbol*>* newLabel = new NodeTree<Symbol*>("frontier: " + intToString(i), input[i]);
NodeTree<Symbol>* newLabel = new NodeTree<Symbol>("frontier: " + intToString(i), input[i]);
while (!toShift.empty()) {
std::pair<NodeTree<int>*, int> shift = toShift.front();
toShift.pop();
@@ -239,7 +233,7 @@ void RNGLRParser::shifter(int i) {
}
}
void RNGLRParser::addChildren(NodeTree<Symbol*>* parent, std::vector<NodeTree<Symbol*>*>* children, NodeTree<Symbol*>* nullableParts) {
void RNGLRParser::addChildren(NodeTree<Symbol>* parent, std::vector<NodeTree<Symbol>*>* children, NodeTree<Symbol>* nullableParts) {
if (nullableParts)
children->push_back(nullableParts);
@@ -248,14 +242,14 @@ void RNGLRParser::addChildren(NodeTree<Symbol*>* parent, std::vector<NodeTree<Sy
parent->addChildren(children);
} else {
if (!arePacked(parent->getChildren())) {
NodeTree<Symbol*>* subParent = new NodeTree<Symbol*>("AmbiguityPackInner", NULL);
NodeTree<Symbol>* subParent = new NodeTree<Symbol>("AmbiguityPackInner", Symbol("AmbiguityPackInner", true));
setPacked(subParent, true);
std::vector<NodeTree<Symbol*>*> tmp = parent->getChildren();
std::vector<NodeTree<Symbol>*> tmp = parent->getChildren();
subParent->addChildren(&tmp);
parent->clearChildren();
parent->addChild(subParent);
}
NodeTree<Symbol*>* t = new NodeTree<Symbol*>("AmbiguityPackOuter", NULL);
NodeTree<Symbol>* t = new NodeTree<Symbol>("AmbiguityPackOuter", Symbol("AmbiguityPackInner", true));
setPacked(t, true);
parent->addChild(t);
t->addChildren(children);
@@ -263,12 +257,12 @@ 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::cout << "Checking " << node->getData()->toString() << "'s family" << std::endl;
std::vector<NodeTree<Symbol*>*> children = node->getChildren();
for (std::vector<NodeTree<Symbol*>*>::size_type i = 0; i < nodes->size(); i++) {
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++) {
for (std::vector<NodeTree<Symbol>*>::size_type j = 0; j < children.size(); j++) {
//Not sure where null comes from. For right now, just check to be sure we don't segfault
if ((*nodes)[i] == children[j] || ( (*nodes)[i] != NULL && children[j] != NULL && (*(*nodes)[i]) == *(children[j]) )) {
containsOne = true;
@@ -282,18 +276,18 @@ bool RNGLRParser::belongsToFamily(NodeTree<Symbol*>* node, std::vector<NodeTree<
return true;
}
bool RNGLRParser::arePacked(std::vector<NodeTree<Symbol*>*> nodes) {
bool RNGLRParser::arePacked(std::vector<NodeTree<Symbol>*> nodes) {
bool packed = true;
for (std::vector<NodeTree<Symbol*>*>::size_type i = 0; i < nodes.size(); i++)
for (std::vector<NodeTree<Symbol>*>::size_type i = 0; i < nodes.size(); i++)
packed &= packedMap[*(nodes[i])];
return packed;
}
bool RNGLRParser::isPacked(NodeTree<Symbol*>* node) {
bool RNGLRParser::isPacked(NodeTree<Symbol>* node) {
return packedMap[*node];
}
void RNGLRParser::setPacked(NodeTree<Symbol*>* node, bool isPacked) {
void RNGLRParser::setPacked(NodeTree<Symbol>* node, bool isPacked) {
packedMap[*node] = isPacked;
}
@@ -315,7 +309,7 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state, std:
//If not, create it.
bool symbolAlreadyInState = false;
for (std::vector< State* >::size_type j = 0; j < newStates.size(); j++) {
if (*(newStates[j]->basis[0]->getAtIndex()) == *(advancedRule->getAtIndex())) {
if (newStates[j]->basis[0]->getAtIndex() == advancedRule->getAtIndex()) {
symbolAlreadyInState = true;
//Add rule to state, combining with idenical rule except lookahead if exists
newStates[j]->addRuleCombineLookahead(advancedRule);
@@ -331,7 +325,7 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state, std:
}
//Put all our new states in the set of states only if they're not already there.
bool stateAlreadyInAllStates = false;
Symbol* currStateSymbol;
Symbol currStateSymbol;
for (std::vector< State * >::size_type i = 0; i < newStates.size(); i++) {
stateAlreadyInAllStates = false;
currStateSymbol = (*(newStates[i]->getBasis()))[0]->getAtIndex();
@@ -367,9 +361,9 @@ void RNGLRParser::addStateReductionsToTable(State* state) {
for (std::vector<ParseRule*>::size_type i = 0; i < currStateTotal->size(); i++) {
//See if reduce
//Also, this really only needs to be done for the state's basis, but we're already iterating through, so...
std::vector<Symbol*>* lookahead = (*currStateTotal)[i]->getLookahead();
std::vector<Symbol>* lookahead = (*currStateTotal)[i]->getLookahead();
if ((*currStateTotal)[i]->isAtEnd()) {
for (std::vector<Symbol*>::size_type j = 0; j < lookahead->size(); j++)
for (std::vector<Symbol>::size_type j = 0; j < lookahead->size(); j++)
table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i]));
//If this has an appropriate ruduction to null, get the reduce trees out
} else if (reducesToNull((*currStateTotal)[i])) {
@@ -377,7 +371,7 @@ void RNGLRParser::addStateReductionsToTable(State* state) {
//It used to be that if is a rule that produces only NULL, add in the approprite reduction, but use a new rule with a right side that is equal to
//the part that we've already gone through in the rule. (so we don't pop extra off stack)
//Now we use the same rule and make sure that the index location is used
for (std::vector<Symbol*>::size_type j = 0; j < lookahead->size(); j++)
for (std::vector<Symbol>::size_type j = 0; j < lookahead->size(); j++)
table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i]));
}
}
@@ -388,33 +382,33 @@ bool RNGLRParser::fullyReducesToNull(ParseRule* rule) {
}
bool RNGLRParser::reducesToNull(ParseRule* rule) {
std::vector<Symbol*> avoidList;
std::vector<Symbol> avoidList;
return reducesToNull(rule, avoidList);
}
bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector<Symbol*> avoidList) {
bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector<Symbol> avoidList) {
//If the rule is completed and not null, it doesn't reduce to null, it's just completed.
if (rule->isAtEnd() && rule->getRightSize() != 0)
return false;
for (std::vector<Symbol*>::size_type i = 0; i < avoidList.size(); i++)
if (*(rule->getLeftSide()) == *(avoidList[i]))
for (std::vector<Symbol>::size_type i = 0; i < avoidList.size(); i++)
if (rule->getLeftSide() == avoidList[i])
return false;
avoidList.push_back(rule->getLeftSide());
std::vector<Symbol*> rightSide = rule->getRightSide();
std::vector<Symbol> rightSide = rule->getRightSide();
bool reduces = true;
for (std::vector<Symbol*>::size_type i = rule->getIndex(); i < rightSide.size(); i++) {
if (*rightSide[i] == *nullSymbol)
for (std::vector<Symbol>::size_type i = rule->getIndex(); i < rightSide.size(); i++) {
if (rightSide[i] == nullSymbol)
continue;
if (rightSide[i]->isTerminal()) {
if (rightSide[i].isTerminal()) {
reduces = false;
break;
}
bool subSymbolReduces = false;
for (std::vector<ParseRule*>::size_type j = 0; j < loadedGrammer.size(); j++) {
if (*(loadedGrammer[j]->getLeftSide()) == *(rightSide[i])) {
if (loadedGrammer[j]->getLeftSide() == rightSide[i]) {
if(reducesToNull(loadedGrammer[j], avoidList)) {
subSymbolReduces = true;
break;
@@ -429,32 +423,32 @@ bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector<Symbol*> avoidList)
return reduces;
}
NodeTree<Symbol*>* RNGLRParser::getNullableParts(ParseRule* rule) {
return getNullableParts(rule, std::vector<NodeTree<Symbol*>*>());
NodeTree<Symbol>* RNGLRParser::getNullableParts(ParseRule* rule) {
return getNullableParts(rule, std::vector<NodeTree<Symbol>*>());
}
NodeTree<Symbol*>* RNGLRParser::getNullableParts(ParseRule* rule, std::vector<NodeTree<Symbol*>*> avoidList) {
NodeTree<Symbol>* RNGLRParser::getNullableParts(ParseRule* rule, std::vector<NodeTree<Symbol>*> avoidList) {
if (reducesToNull(rule)) {
//std::cout << "Reduces to null so adding parts " << rule->toString() << std::endl;
Symbol* symbol = rule->getLeftSide();
NodeTree<Symbol*>* symbolNode = new NodeTree<Symbol*>(symbol->getName(), symbol);
if (*(rule->getAtNextIndex()) == *nullSymbol) {
symbolNode->addChild(new NodeTree<Symbol*>(nullSymbol->getName(), nullSymbol));
Symbol symbol = rule->getLeftSide();
NodeTree<Symbol>* symbolNode = new NodeTree<Symbol>(symbol.getName(), symbol);
if (rule->getAtNextIndex() == nullSymbol) {
symbolNode->addChild(new NodeTree<Symbol>(nullSymbol.getName(), nullSymbol));
} else {
//Find recursively
ParseRule* iterate = rule->clone();
while (!iterate->isAtEnd()) {
//Check to see if we've done this symbol already, if so use it
for (std::vector<NodeTree<Symbol*>*>::size_type i = 0; i < avoidList.size(); i++) {
if (*(iterate->getAtNextIndex()) == *(avoidList[i]->getData())) {
for (std::vector<NodeTree<Symbol>*>::size_type i = 0; i < avoidList.size(); i++) {
if (iterate->getAtNextIndex() == avoidList[i]->getData()) {
symbolNode->addChild(avoidList[i]);
break;
}
}
//We haven't so do it recursively
for (std::vector<ParseRule*>::size_type i = 0; i < loadedGrammer.size(); i++) {
if (fullyReducesToNull(loadedGrammer[i]) && *(iterate->getAtNextIndex()) == *(loadedGrammer[i]->getLeftSide())) {
NodeTree<Symbol*>* symbolTree = getNullableParts(loadedGrammer[i], avoidList);
if (fullyReducesToNull(loadedGrammer[i]) && iterate->getAtNextIndex() == loadedGrammer[i]->getLeftSide()) {
NodeTree<Symbol>* symbolTree = getNullableParts(loadedGrammer[i], avoidList);
avoidList.push_back(symbolTree);
symbolNode->addChild(symbolTree);
}
@@ -467,12 +461,12 @@ NodeTree<Symbol*>* RNGLRParser::getNullableParts(ParseRule* rule, std::vector<No
return NULL;
}
NodeTree<Symbol*>* RNGLRParser::getNullableParts(Symbol* symbol) {
return new NodeTree<Symbol*>("CRAZY_SYMBOL", nullSymbol);
NodeTree<Symbol>* RNGLRParser::getNullableParts(Symbol symbol) {
return new NodeTree<Symbol>("CRAZY_SYMBOL", nullSymbol);
}
std::vector<NodeTree<Symbol*>*> RNGLRParser::getPathEdges(std::vector<NodeTree<int>*> path) {
std::vector<NodeTree<Symbol*>*> pathEdges;
std::vector<NodeTree<Symbol>*> RNGLRParser::getPathEdges(std::vector<NodeTree<int>*> path) {
std::vector<NodeTree<Symbol>*> pathEdges;
for (std::vector<NodeTree<int>*>::size_type i = 0; i < path.size()-1; i++)
pathEdges.push_back(gss.getEdge(path[i], path[i+1]));
return pathEdges;

View File

@@ -1,5 +1,12 @@
#include "Symbol.h"
Symbol::Symbol() {
this->name = "UninitlizedSymbol";
this->terminal = false;
this->subTree = NULL;
value = "NoValue";
}
Symbol::Symbol(std::string name, bool isTerminal) {
this->name = name;
this->terminal = isTerminal;
@@ -14,7 +21,7 @@ Symbol::Symbol(std::string name, bool isTerminal, std::string value) {
this->value = value;
}
Symbol::Symbol(std::string name, bool isTerminal, NodeTree<Symbol*>* tree) {
Symbol::Symbol(std::string name, bool isTerminal, NodeTree<Symbol>* tree) {
this->name = name;
this->terminal = isTerminal;
this->subTree = tree;
@@ -24,31 +31,31 @@ Symbol::~Symbol() {
}
const bool Symbol::operator==(const Symbol &other) {
const bool Symbol::operator==(const Symbol &other) const {
return( name == other.name && terminal == other.terminal);
}
const bool Symbol::operator!=(const Symbol &other) {
const bool Symbol::operator!=(const Symbol &other) const {
return(!this->operator==(other));
}
std::string Symbol::getName() {
const bool Symbol::operator<(const Symbol &other) const {
return name < other.getName();
}
std::string Symbol::getName() const {
return(name);
}
std::string Symbol::toString() {
std::string Symbol::toString() const {
return(name + (terminal ? " " + value : ""));
}
Symbol* Symbol::clone() {
return new Symbol(name, terminal, subTree);
}
void Symbol::setSubTree(NodeTree<Symbol*>* tree) {
void Symbol::setSubTree(NodeTree<Symbol>* tree) {
subTree = tree;
}
NodeTree<Symbol*>* Symbol::getSubTree() {
NodeTree<Symbol>* Symbol::getSubTree() {
return subTree;
}

View File

@@ -8,12 +8,12 @@ Table::~Table() {
//
}
void Table::setSymbols(Symbol* EOFSymbol, Symbol* nullSymbol) {
void Table::setSymbols(Symbol EOFSymbol, Symbol nullSymbol) {
this->EOFSymbol = EOFSymbol;
this->nullSymbol = nullSymbol;
}
void Table::add(int stateNum, Symbol* tranSymbol, ParseAction* action) {
void Table::add(int stateNum, Symbol tranSymbol, ParseAction* action) {
//If this is the first time we're adding to the table, add the EOF character
if (symbolIndexVec.size() == 0)
@@ -28,8 +28,8 @@ void Table::add(int stateNum, Symbol* tranSymbol, ParseAction* action) {
//find out what index this symbol is on
int symbolIndex = -1;
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) {
if ( *(symbolIndexVec[i]) == *tranSymbol ) {
for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++) {
if ( symbolIndexVec[i] == tranSymbol ) {
//Has been found
symbolIndex = i;
break;
@@ -79,11 +79,11 @@ void Table::add(int stateNum, Symbol* tranSymbol, ParseAction* action) {
}
}
void Table::remove(int stateNum, Symbol* tranSymbol) {
void Table::remove(int stateNum, Symbol tranSymbol) {
//find out what index this symbol is on
int symbolIndex = -1;
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) {
if ( *(symbolIndexVec[i]) == *tranSymbol ) {
for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++) {
if ( symbolIndexVec[i] == tranSymbol ) {
//Has been found
symbolIndex = i;
break;
@@ -92,21 +92,21 @@ void Table::remove(int stateNum, Symbol* tranSymbol) {
(*(table[stateNum]))[symbolIndex] = NULL;
}
std::vector<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) {
for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++) {
if ( symbolIndexVec[i] == token) {
symbolIndex = i;
break;
}
}
if (symbolIndex == -1) {
std::cout << "Unrecognized symbol: " << token->toString() << ", cannot get from table!" << std::endl;
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::cout << "Get for state: " << state << ", and Symbol: " << token.toString() << std::endl;
if (state < 0 || state >= table.size()) {
std::cout << "State bad: " << state << std::endl;
return NULL;
@@ -115,7 +115,7 @@ std::vector<ParseAction*>* Table::get(int state, Symbol* token) {
std::vector<ParseAction*>* action = NULL;
if (symbolIndex < 0 || symbolIndex >= table[state]->size()) {
std::cout << "Symbol bad for this state: " << token->toString() << ". This is a reject." << std::endl;
std::cout << "Symbol bad for this state: " << token.toString() << ". This is a reject." << std::endl;
} else {
action = (*(table[state]))[symbolIndex];
}
@@ -144,7 +144,7 @@ std::vector<ParseAction*>* Table::get(int state, Symbol* token) {
return (action);
}
ParseAction* Table::getShift(int state, Symbol* token) {
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++) {
@@ -158,8 +158,8 @@ ParseAction* Table::getShift(int state, Symbol* token) {
std::string Table::toString() {
std::string concat = "";
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++)
concat += "\t" + symbolIndexVec[i]->toString();
for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++)
concat += "\t" + symbolIndexVec[i].toString();
concat += "\n";
for (std::vector< std::vector< std::vector< ParseRule* >* >* >::size_type i = 0; i < table.size(); i++) {