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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user