From 9460bacf1c9dd7ed260ad163ce1c41d881acdc1c Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sun, 4 Aug 2013 14:24:20 -0400 Subject: [PATCH] Fixed some problems with grammer loading of null rules and rules non-terminals and terminals that had the same name --- include/Parser.h | 4 ++-- src/Parser.cpp | 35 ++++++++++++++++++++--------------- src/RNGLRParser.cpp | 2 +- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/include/Parser.h b/include/Parser.h index 97f5dec..f2297a4 100644 --- a/include/Parser.h +++ b/include/Parser.h @@ -34,7 +34,7 @@ class Parser { protected: std::vector* firstSet(Symbol* token); - std::vector* firstSet(Symbol* token, std::vector &avoidList); + std::vector* firstSet(Symbol* token, std::vector avoidList); std::vector* incrementiveFollowSet(ParseRule* rule); virtual void closure(State* state); virtual void addStates(std::vector< State* >* stateSets, State* state); @@ -43,7 +43,7 @@ class Parser { StringReader reader; Lexer lexer; - std::map symbols; + std::map, Symbol*> symbols; std::vector loadedGrammer; std::vector< State* > stateSets; diff --git a/src/Parser.cpp b/src/Parser.cpp index 06f1e19..8927265 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -13,11 +13,12 @@ Parser::~Parser() { Symbol* Parser::getOrAddSymbol(std::string symbolString, bool isTerminal) { Symbol* symbol; - if (symbols.find(symbolString) == symbols.end()) { + std::pair entry = std::make_pair(symbolString, isTerminal); + if (symbols.find(entry) == symbols.end()) { symbol = new Symbol(symbolString, isTerminal); - symbols[symbolString] = symbol; + symbols[entry] = symbol; } else { - symbol = symbols[symbolString]; + symbol = symbols[entry]; } return(symbol); } @@ -36,18 +37,9 @@ void Parser::loadGrammer(std::string grammerInputString) { //Add the right side, adding new Symbols to symbol map. currToken = reader.word(); while (currToken != ";") { - if (currToken[0] == '\"') { - //Remove the quotes - currToken = currToken.substr(1,currToken.length()-2); - lexer.addRegEx(currToken); - currentRule->appendToRight(getOrAddSymbol(currToken, true)); //If first character is a ", then is a terminal - } else { - currentRule->appendToRight(getOrAddSymbol(currToken, false)); - } - currToken = reader.word(); //If there are multiple endings to this rule, finish this rule and start a new one with same left handle - if (currToken == "|") { + while (currToken == "|") { //If we haven't added anything, that means that this is a null rule if (currentRule->getRightSide().size() == 0) currentRule->appendToRight(nullSymbol); @@ -57,6 +49,19 @@ void Parser::loadGrammer(std::string grammerInputString) { currentRule->setLeftHandle(leftSide); currToken = reader.word(); } + + if (currToken == ";") + break; + + if (currToken[0] == '\"') { + //Remove the quotes + currToken = currToken.substr(1,currToken.length()-2); + lexer.addRegEx(currToken); + currentRule->appendToRight(getOrAddSymbol(currToken, true)); //If first character is a ", then is a terminal + } else { + currentRule->appendToRight(getOrAddSymbol(currToken, false)); + } + currToken = reader.word(); } //Add new rule to grammer //If we haven't added anything, that means that this is a null rule @@ -78,7 +83,7 @@ std::vector* Parser::firstSet(Symbol* token) { return firstSet(token, avoidList); } -std::vector* Parser::firstSet(Symbol* token, std::vector &avoidList) { +std::vector* Parser::firstSet(Symbol* token, std::vector avoidList) { //If we've already done this token, don't do it again for (std::vector::size_type i = 0; i < avoidList.size(); i++) if (*(avoidList[i]) == *token) { @@ -114,7 +119,7 @@ std::vector* Parser::firstSet(Symbol* token, std::vector &avoi //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::size_type k = 0; k < recursiveFirstSet->size(); k++) { - if ((*(*recursiveFirstSet)[j]) == *nullSymbol) { + if ((*(*recursiveFirstSet)[k]) == *nullSymbol) { recFirstSetHasNull = true; } } diff --git a/src/RNGLRParser.cpp b/src/RNGLRParser.cpp index c032908..1fedad0 100644 --- a/src/RNGLRParser.cpp +++ b/src/RNGLRParser.cpp @@ -74,6 +74,7 @@ NodeTree* 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() << " next: " << input[i+1]->toString() << std::endl; break; } while (toReduce.size() != 0) { @@ -176,7 +177,6 @@ void RNGLRParser::shifter(int i) { //Have to use own add states function in order to construct RN table instead of LALR table void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state) { - std::cout << "RNGLR ADD STATES" << std::endl; std::vector< State* > newStates; //For each rule in the state we already have std::vector* currStateTotal = state->getTotal();