Fixed some problems with grammer loading of null rules and rules non-terminals and terminals that had the same name

This commit is contained in:
Nathan Braswell
2013-08-04 14:24:20 -04:00
parent d5b33efb22
commit 9460bacf1c
3 changed files with 23 additions and 18 deletions

View File

@@ -34,7 +34,7 @@ class Parser {
protected:
std::vector<Symbol*>* firstSet(Symbol* token);
std::vector<Symbol*>* firstSet(Symbol* token, std::vector<Symbol*> &avoidList);
std::vector<Symbol*>* firstSet(Symbol* token, std::vector<Symbol*> avoidList);
std::vector<Symbol*>* 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<std::string, Symbol*> symbols;
std::map<std::pair<std::string, bool>, Symbol*> symbols;
std::vector<ParseRule*> loadedGrammer;
std::vector< State* > stateSets;

View File

@@ -13,11 +13,12 @@ Parser::~Parser() {
Symbol* Parser::getOrAddSymbol(std::string symbolString, bool isTerminal) {
Symbol* symbol;
if (symbols.find(symbolString) == symbols.end()) {
std::pair<std::string, bool> 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<Symbol*>* Parser::firstSet(Symbol* token) {
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) {
@@ -114,7 +119,7 @@ std::vector<Symbol*>* Parser::firstSet(Symbol* token, std::vector<Symbol*> &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<Symbol*>::size_type k = 0; k < recursiveFirstSet->size(); k++) {
if ((*(*recursiveFirstSet)[j]) == *nullSymbol) {
if ((*(*recursiveFirstSet)[k]) == *nullSymbol) {
recFirstSetHasNull = true;
}
}

View File

@@ -74,6 +74,7 @@ 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() << " 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<ParseRule*>* currStateTotal = state->getTotal();