diff --git a/include/ParseRule.h b/include/ParseRule.h index ee778fa..ba5cca9 100644 --- a/include/ParseRule.h +++ b/include/ParseRule.h @@ -33,8 +33,6 @@ class ParseRule { int getRightSize(); int getIndex(); - std::vector*>* nullReductions(); - bool advancePointer(); bool isAtEnd(); diff --git a/include/RNGLRParser.h b/include/RNGLRParser.h index b7f2a2e..0edb3c1 100644 --- a/include/RNGLRParser.h +++ b/include/RNGLRParser.h @@ -11,6 +11,8 @@ class RNGLRParser: public Parser { void reducer(int i); void shifter(int i); void addStates(std::vector< State* >* stateSets, State* state); + bool reducesToNull(ParseRule* rule); + bool reducesToNull(ParseRule* rule, std::vector avoidList); private: std::vector input; GraphStructuredStack gss; diff --git a/src/Lexer.cpp b/src/Lexer.cpp index 5fba74f..1dda671 100644 --- a/src/Lexer.cpp +++ b/src/Lexer.cpp @@ -23,9 +23,9 @@ void Lexer::addRegEx(std::string regExString) { } Symbol* Lexer::next() { - std::cout << "Current at is \"" << input.substr(currentPosition,input.length()-1) << "\" currentPos is " << currentPosition <= input.length()-1) return new Symbol("$EOF$", true); int longestMatch = -1; RegEx* longestRegEx = NULL; @@ -44,7 +44,7 @@ Symbol* Lexer::next() { return new Symbol(longestRegEx->getPattern(), true); } else { std::cout << "Found no applicable regex" << std::endl; - std::cout << "Remaining is " << input.substr(currentPosition,input.length()-1) << std::endl; - return new Symbol("$NO_APPLICABLE_REGEX$", true); + std::cout << "Remaining is ||" << input.substr(currentPosition,input.length()-1) << "||" << std::endl; + return NULL; } } \ No newline at end of file diff --git a/src/ParseRule.cpp b/src/ParseRule.cpp index c8991ab..41254c3 100644 --- a/src/ParseRule.cpp +++ b/src/ParseRule.cpp @@ -73,10 +73,6 @@ int ParseRule::getIndex() { return pointerIndex; } -std::vector*>* ParseRule::nullReductions() { - //Return a vector of null reduction trees -} - bool ParseRule::advancePointer() { if (pointerIndex < rightSide.size()) { pointerIndex++; diff --git a/src/RNGLRParser.cpp b/src/RNGLRParser.cpp index 7e3bb3e..c032908 100644 --- a/src/RNGLRParser.cpp +++ b/src/RNGLRParser.cpp @@ -33,7 +33,12 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { while (*currentToken != *EOFSymbol) { std::cout << EOFSymbol->toString() << " " << currentToken->toString() << std::endl; currentToken = lexer.next(); - input.push_back(currentToken); + if (currentToken != NULL) { + input.push_back(currentToken); + } else { + std::cout << "Rejected, lexer unable to fully tokenize sentence" << std::endl; + return new NodeTree(); + } } std::cout << "\n\n\nDone with Lexing\n\n\n" << std::endl; @@ -210,8 +215,8 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state) { table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i])); // } else if (*((*currStateTotal)[i]->getAtNextIndex()) == *nullSymbol) { //If this has an appropriate ruduction to null, get the reduce trees out - } else if (std::vector*>* reduceTrees = (*currStateTotal)[i]->nullReductions(), reduceTrees) { - std::cout << "REDUCE TREES" << std::endl; + } 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) ParseRule* nullRule = (*currStateTotal)[i]->clone(); nullRule->setRightSide(* new std::vector()); @@ -240,4 +245,43 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state) { table.add(stateNum(state), currStateSymbol, new ParseAction(ParseAction::SHIFT, stateSets->size()-1)); } } -} \ No newline at end of file +} + +bool RNGLRParser::reducesToNull(ParseRule* rule) { + std::vector avoidList; + return reducesToNull(rule, avoidList); +} + +bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector avoidList) { + for (std::vector::size_type i = 0; i < avoidList.size(); i++) + if (*(rule->getLeftSide()) == *(avoidList[i])) + return false; + + avoidList.push_back(rule->getLeftSide()); + + std::vector rightSide = rule->getRightSide(); + bool reduces = true; + for (std::vector::size_type i = 0; i < rightSide.size(); i++) { + if (*rightSide[i] == *nullSymbol) + continue; + if (rightSide[i]->isTerminal()) { + reduces = false; + break; + } + bool subSymbolReduces = false; + for (std::vector::size_type j = 0; j < loadedGrammer.size(); j++) { + if (*(loadedGrammer[j]->getLeftSide()) == *(rightSide[i])) { + if(reducesToNull(loadedGrammer[j], avoidList)) { + subSymbolReduces = true; + break; + } + } + } + if (!subSymbolReduces) { + reduces = false; + break; + } + } + return reduces; +} +