From 35a0677d077c48d9dcf3590e295d3b9d7061a6c4 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Thu, 22 Aug 2013 15:41:30 -0400 Subject: [PATCH] Still in progress --- include/Parser.h | 3 ++- include/RNGLRParser.h | 2 +- include/State.h | 1 + src/Parser.cpp | 15 ++++++++++----- src/RNGLRParser.cpp | 7 ++++++- src/State.cpp | 13 +++++++++++++ 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/include/Parser.h b/include/Parser.h index f2297a4..fa3773f 100644 --- a/include/Parser.h +++ b/include/Parser.h @@ -11,6 +11,7 @@ #include "NodeTree.h" #include "Table.h" +#include #include #include #include @@ -37,7 +38,7 @@ class Parser { 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); + virtual void addStates(std::vector< State* >* stateSets, State* state, std::queue* toDo); int stateNum(State* state); diff --git a/include/RNGLRParser.h b/include/RNGLRParser.h index a46eda1..35ef95a 100644 --- a/include/RNGLRParser.h +++ b/include/RNGLRParser.h @@ -22,7 +22,7 @@ class RNGLRParser: public Parser { void shifter(int i); void addChildren(NodeTree* parent, std::vector*>* children, NodeTree* nullableParts); - void addStates(std::vector< State* >* stateSets, State* state); + void addStates(std::vector< State* >* stateSets, State* state, std::queue* toDo); void addStateReductionsToTable(State* state); bool fullyReducesToNull(ParseRule* rule); bool reducesToNull(ParseRule* rule); diff --git a/include/State.h b/include/State.h index 7a6a52c..c638170 100644 --- a/include/State.h +++ b/include/State.h @@ -27,6 +27,7 @@ class State { std::vector* getTotal(); bool containsRule(ParseRule* rule); void addRuleCombineLookahead(ParseRule* rule); + void addRuleCombineLookaheadWithLookahead(ParseRule* rule); std::string toString(); void combineStates(State &other); diff --git a/src/Parser.cpp b/src/Parser.cpp index d3481fb..1a81821 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -87,13 +87,17 @@ void Parser::createStateSet() { std::vector* goalRuleLookahead = new std::vector(); goalRuleLookahead->push_back(EOFSymbol); goalRule->setLookahead(goalRuleLookahead); - stateSets.push_back( new State(0, goalRule)); + State* zeroState = new State(0, goalRule); + stateSets.push_back(zeroState); + std::queue* toDo = new std::queue(); + toDo->push(zeroState); //std::cout << "Begining for main set for loop" << std::endl; - for (std::vector< State* >::size_type i = 0; i < stateSets.size(); i++) { + while (toDo->front()) { //closure - closure(stateSets[i]); + closure(toDo->front()); //Add the new states - addStates(&stateSets, stateSets[i]); + addStates(&stateSets, toDo->front(), toDo); + toDo->pop(); } table.remove(1, EOFSymbol); } @@ -239,7 +243,7 @@ void Parser::closure(State* state) { } //Adds state if it doesn't already exist. -void Parser::addStates(std::vector< State* >* stateSets, State* state) { +void Parser::addStates(std::vector< State* >* stateSets, State* state, std::queue* toDo) { std::vector< State* > newStates; //For each rule in the state we already have std::vector* currStateTotal = state->getTotal(); @@ -302,6 +306,7 @@ void Parser::addStates(std::vector< State* >* stateSets, State* state) { if (!stateAlreadyInAllStates) { //If the state does not already exist, add it and add it as the shift/goto in the action table stateSets->push_back(newStates[i]); + toDo->push(newStates[i]); table.add(stateNum(state), currStateSymbol, new ParseAction(ParseAction::SHIFT, stateSets->size()-1)); } } diff --git a/src/RNGLRParser.cpp b/src/RNGLRParser.cpp index 9dee76a..9ab4e77 100644 --- a/src/RNGLRParser.cpp +++ b/src/RNGLRParser.cpp @@ -294,7 +294,7 @@ void RNGLRParser::setPacked(NodeTree* node, bool isPacked) { //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) { +void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state, std::queue* toDo) { std::vector< State* > newStates; //For each rule in the state we already have std::vector* currStateTotal = state->getTotal(); @@ -314,6 +314,7 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state) { symbolAlreadyInState = true; //Add rule to state, combining with idenical rule except lookahead if exists newStates[j]->addRuleCombineLookahead(advancedRule); + //newStates[j]->addRuleCombineLookaheadWithLookahead(advancedRule); //We found a state with the same symbol, so stop searching break; } @@ -334,6 +335,9 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state) { if (newStates[i]->basisEqualsExceptLookahead(*((*stateSets)[j]))) { stateAlreadyInAllStates = true; //If it does exist, we should add it as the shift/goto in the action table + if (*((*stateSets)[j]) != *(newStates[i])) + toDo->push((*stateSets)[j]); + (*stateSets)[j]->combineStates(*(newStates[i])); addStateReductionsToTable((*stateSets)[j]); table.add(stateNum(state), currStateSymbol, new ParseAction(ParseAction::SHIFT, j)); @@ -343,6 +347,7 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state) { if (!stateAlreadyInAllStates) { //If the state does not already exist, add it and add it as the shift/goto in the action table stateSets->push_back(newStates[i]); + toDo->push(newStates[i]); table.add(stateNum(state), currStateSymbol, new ParseAction(ParseAction::SHIFT, stateSets->size()-1)); } } diff --git a/src/State.cpp b/src/State.cpp index b77caf1..ca62820 100644 --- a/src/State.cpp +++ b/src/State.cpp @@ -117,6 +117,19 @@ void State::addRuleCombineLookahead(ParseRule* rule) { basis.push_back(rule); } +void State::addRuleCombineLookaheadWithLookahead(ParseRule* rule) { + getTotal(); + bool alreadyIn = false; + for (std::vector::size_type i = 0; i < total.size(); i++) { + if (*rule == (*(total[i]))) { + total[i]->addLookahead(rule->getLookahead()); + alreadyIn = true; + } + } + if (!alreadyIn) + basis.push_back(rule); +} + std::string State::toString() { std::string concat = ""; concat += "State " + intToString(number) + " with " + intToString(parents.size()) + " parents:\n";