From 3a5d94caaad87fc573ac38354ce02b2208b34ec6 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Mon, 12 Aug 2013 00:02:50 -0400 Subject: [PATCH] Started adding the nullable parts machinery. Also started to fix addStates for RNGLR and null reductions so it only truncated the rule to what had already been parsed, but now it looks like it maybe shouldn't truncate at all and use pointer position for length. However, I have to go to bed and will pick up later. --- include/ParseRule.h | 2 +- include/RNGLRParser.h | 6 ++-- src/ParseRule.cpp | 2 +- src/RNGLRParser.cpp | 76 +++++++++++++++++++++++++------------------ 4 files changed, 49 insertions(+), 37 deletions(-) diff --git a/include/ParseRule.h b/include/ParseRule.h index 9f36367..aac85a7 100644 --- a/include/ParseRule.h +++ b/include/ParseRule.h @@ -26,7 +26,7 @@ class ParseRule { void appendToRight(Symbol* appendee); Symbol* getLeftSide(); - void setRightSide(std::vector &rightSide); + void setRightSide(std::vector rightSide); std::vector getRightSide(); Symbol* getAtNextIndex(); Symbol* getAtIndex(); diff --git a/include/RNGLRParser.h b/include/RNGLRParser.h index ba9dde4..96ed4ff 100644 --- a/include/RNGLRParser.h +++ b/include/RNGLRParser.h @@ -20,7 +20,7 @@ class RNGLRParser: public Parser { private: void reducer(int i); void shifter(int i); - void addChildren(NodeTree* parent, std::vector*>* children, int nullablePartsIndex); + void addChildren(NodeTree* parent, std::vector*>* children, NodeTree* nullableParts); void addStates(std::vector< State* >* stateSets, State* state); bool reducesToNull(ParseRule* rule); @@ -31,10 +31,8 @@ class RNGLRParser: public Parser { bool isPacked(NodeTree* node); void setPacked(NodeTree* node, bool isPacked); - int getNullableIndex(ParseRule* rule); NodeTree* getNullableParts(ParseRule* rule); NodeTree* getNullableParts(Symbol* symbol); - NodeTree* getNullableParts(int index); std::vector*> getPathEdges(std::vector*> path); @@ -45,7 +43,7 @@ class RNGLRParser: public Parser { NodeTree* from; Symbol* symbol; int length; - int nullablePartsIndex; + NodeTree* nullableParts; NodeTree* label; } ; std::queue toReduce; diff --git a/src/ParseRule.cpp b/src/ParseRule.cpp index 6d5aced..d8008de 100644 --- a/src/ParseRule.cpp +++ b/src/ParseRule.cpp @@ -45,7 +45,7 @@ Symbol* ParseRule::getLeftSide() { return leftHandle; } -void ParseRule::setRightSide(std::vector &rightSide) { +void ParseRule::setRightSide(std::vector rightSide) { this->rightSide = rightSide; } diff --git a/src/RNGLRParser.cpp b/src/RNGLRParser.cpp index 7004e5a..e323eaf 100644 --- a/src/RNGLRParser.cpp +++ b/src/RNGLRParser.cpp @@ -64,7 +64,7 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { if (firstActions[i]->action == ParseAction::SHIFT) toShift.push(std::make_pair(v0,firstActions[i]->shiftState)); else if (firstActions[i]->action == ParseAction::REDUCE && firstActions[i]->reduceRule->getRightSide().size() == 0) { - Reduction newReduction = {v0, firstActions[i]->reduceRule->getLeftSide(), 0, getNullableIndex(firstActions[i]->reduceRule), new NodeTree("null", nullSymbol)}; + Reduction newReduction = {v0, firstActions[i]->reduceRule->getLeftSide(), 0, getNullableParts(firstActions[i]->reduceRule), NULL}; toReduce.push(newReduction); //toReduce.push(std::make_pair(std::make_pair(v0, firstActions[i]->reduceRule->getLeftSide()), 0)); } @@ -133,7 +133,7 @@ void RNGLRParser::reducer(int i) { //If reduction length is 0, then we make the new label the appropriate nullable parts NodeTree* newLabel = NULL; if (reduction.length == 0) { - newLabel = getNullableParts(reduction.nullablePartsIndex); + newLabel = reduction.nullableParts; } else { //Otherwise, we create the new label if we haven't already int reachedFrontier = gss.getContainingFrontier(currentReached); @@ -159,7 +159,7 @@ void RNGLRParser::reducer(int i) { std::vector actions = *(table.get(toState, input[i])); for (std::vector::size_type k = 0; k < actions.size(); k++) { if (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}; + Reduction newReduction = {currentReached, actions[k]->reduceRule->getLeftSide(), actions[k]->reduceRule->getRightSize(), getNullableParts(actions[k]->reduceRule), newLabel}; toReduce.push(newReduction); } } @@ -177,16 +177,16 @@ void RNGLRParser::reducer(int i) { if (actions[k]->action == ParseAction::SHIFT) { toShift.push(std::make_pair(toStateNode, actions[k]->shiftState)); } else if (actions[k]->action == ParseAction::REDUCE && actions[k]->reduceRule->getRightSize() == 0) { - Reduction newReduction = {toStateNode, actions[k]->reduceRule->getLeftSide(), 0, getNullableIndex(actions[k]->reduceRule), new NodeTree("null", nullSymbol)}; + Reduction newReduction = {toStateNode, actions[k]->reduceRule->getLeftSide(), 0, getNullableParts(actions[k]->reduceRule), NULL}; toReduce.push(newReduction); } 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}; + Reduction newReduction = {currentReached, actions[k]->reduceRule->getLeftSide(), actions[k]->reduceRule->getRightSize(), getNullableParts(actions[k]->reduceRule), newLabel}; toReduce.push(newReduction); } } } if (reduction.length != 0) - addChildren(newLabel, &pathEdges, reduction.nullablePartsIndex); + addChildren(newLabel, &pathEdges, reduction.nullableParts); } } @@ -205,7 +205,7 @@ void RNGLRParser::shifter(int i) { std::vector actions = *(table.get(shift.second, input[i+1])); for (std::vector::size_type j = 0; j < actions.size(); j++) { if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() != 0) { - Reduction newReduction = {shift.first, actions[j]->reduceRule->getLeftSide(), actions[j]->reduceRule->getRightSize(), getNullableIndex(actions[j]->reduceRule), newLabel}; + Reduction newReduction = {shift.first, actions[j]->reduceRule->getLeftSide(), actions[j]->reduceRule->getRightSize(), getNullableParts(actions[j]->reduceRule), newLabel}; toReduce.push(newReduction); } } @@ -221,10 +221,10 @@ void RNGLRParser::shifter(int i) { if (actions[j]->action == ParseAction::SHIFT) { nextShifts.push(std::make_pair(shiftTo, actions[j]->shiftState)); } else if (actions[j]->action == ParseAction::REDUCE && actions[j]->reduceRule->getRightSize() != 0) { - Reduction newReduction = {shift.first, actions[j]->reduceRule->getLeftSide(), actions[j]->reduceRule->getRightSize(), getNullableIndex(actions[j]->reduceRule), newLabel}; + Reduction newReduction = {shift.first, actions[j]->reduceRule->getLeftSide(), actions[j]->reduceRule->getRightSize(), getNullableParts(actions[j]->reduceRule), newLabel}; toReduce.push(newReduction); } 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("null", nullSymbol)}; + Reduction newReduction = {shiftTo, actions[j]->reduceRule->getLeftSide(), 0, getNullableParts(actions[j]->reduceRule), NULL}; toReduce.push(newReduction); } } @@ -234,9 +234,9 @@ void RNGLRParser::shifter(int i) { } } -void RNGLRParser::addChildren(NodeTree* parent, std::vector*>* children, int nullablePartsIndex) { - if (nullablePartsIndex != 0) - children->push_back(getNullableParts(nullablePartsIndex)); +void RNGLRParser::addChildren(NodeTree* parent, std::vector*>* children, NodeTree* nullableParts) { + if (nullableParts) + children->push_back(nullableParts); if (!belongsToFamily(parent, children)) { if (parent->getChildren().size() == 0) { parent->addChildren(children); @@ -334,9 +334,12 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state) { //If this has an appropriate ruduction to null, get the reduce trees out } else if (reducesToNull((*currStateTotal)[i])) { std::cout << (*currStateTotal)[i]->toString() << " REDUCES TO NULL" << std::endl; - //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) + //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) ParseRule* nullRule = (*currStateTotal)[i]->clone(); - nullRule->setRightSide(* new std::vector()); + std::vector oldRightSide = nullRule->getRightSide(); + oldRightSide.erase(oldRightSide.begin()+nullRule->getIndex(), oldRightSide.end()); + nullRule->setRightSide(oldRightSide); for (std::vector::size_type j = 0; j < lookahead->size(); j++) table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, nullRule)); } @@ -370,6 +373,10 @@ bool RNGLRParser::reducesToNull(ParseRule* rule) { } bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector 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::size_type i = 0; i < avoidList.size(); i++) if (*(rule->getLeftSide()) == *(avoidList[i])) return false; @@ -378,7 +385,7 @@ bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector avoidList) std::vector rightSide = rule->getRightSide(); bool reduces = true; - for (std::vector::size_type i = 0; i < rightSide.size(); i++) { + for (std::vector::size_type i = rule->getIndex(); i < rightSide.size(); i++) { if (*rightSide[i] == *nullSymbol) continue; if (rightSide[i]->isTerminal()) { @@ -402,25 +409,33 @@ bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector avoidList) return reduces; } -int RNGLRParser::getNullableIndex(ParseRule* rule) { - if (reducesToNull(rule)) - return 1; - else - return 0; -} - NodeTree* RNGLRParser::getNullableParts(ParseRule* rule) { - return getNullableParts(getNullableIndex(rule)); + //return new NodeTree("FAKE_PARTS_FOR_NO_CRASH", nullSymbol); + if (reducesToNull(rule)) { + std::cout << "Reduces to null so adding parts " << rule->toString() << std::endl; + //return new NodeTree("FAKE_PARTS_FOR_NO_CRASH", nullSymbol); + Symbol* symbol = rule->getLeftSide(); + NodeTree* symbolNode = new NodeTree(symbol->getName(), symbol); + if (rule->getRightSize() == 0) { + symbolNode->addChild(new NodeTree(nullSymbol->getName(), nullSymbol)); + } else { + //Do something recursive + //Be careful of cycles + ParseRule* iterate = rule->clone(); + while (!iterate->isAtEnd()) { + for (std::vector::size_type i = 0; i < loadedGrammer.size(); i++) + if (*(iterate->getAtNextIndex()) == *(loadedGrammer[i]->getLeftSide())) + symbolNode->addChild(getNullableParts(loadedGrammer[i])); + rule->advancePointer(); + } + } + return symbolNode; + } + return NULL; } NodeTree* RNGLRParser::getNullableParts(Symbol* symbol) { - return new NodeTree("null", nullSymbol); -} - -NodeTree* RNGLRParser::getNullableParts(int index) { - if (index == 0) - return new NodeTree("not_null", nullSymbol); - return new NodeTree("null", nullSymbol); + return new NodeTree("CRAZY_SYMBOL", nullSymbol); } std::vector*> RNGLRParser::getPathEdges(std::vector*> path) { @@ -429,4 +444,3 @@ std::vector*> RNGLRParser::getPathEdges(std::vector