From 1aec4ee6a71b0d1cc1d447d1018f063db88142c5 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Fri, 24 May 2013 00:00:41 -0400 Subject: [PATCH] Added first go at creating stateSets. This is a commit to save work, as it still segfaults.: --- include/ParseRule.h | 3 ++ include/Parser.h | 9 +++++ main.cpp | 2 + src/ParseRule.cpp | 8 ++++ src/Parser.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+) diff --git a/include/ParseRule.h b/include/ParseRule.h index 9f2ab4b..d8b45fb 100644 --- a/include/ParseRule.h +++ b/include/ParseRule.h @@ -17,6 +17,8 @@ class ParseRule { ParseRule(Symbol* leftHandle, int pointerIndex, std::vector &rightSide); ~ParseRule(); + bool const operator==(const ParseRule &other); + ParseRule* clone(); void setLeftHandle(Symbol* leftHandle); @@ -24,6 +26,7 @@ class ParseRule { Symbol* getLeftSide(); std::vector getRightSide(); + int getIndex(); bool advancePointer(); diff --git a/include/Parser.h b/include/Parser.h index 4a94b2a..d370276 100644 --- a/include/Parser.h +++ b/include/Parser.h @@ -14,6 +14,7 @@ #include #include #include +#include #include class Parser { @@ -21,7 +22,13 @@ class Parser { Parser(); ~Parser(); + std::string intToString(int theInt); + void loadGrammer(std::string grammerInputString); + void createStateSet(); + void closure(std::vector* state); + void addState(std::vector< std::vector* >* stateSets, std::vector* state, Symbol*); + std::string stateSetToString(); int gotoTable(int state, Symbol* token); ParseAction* actionTable(int state, Symbol* token); void parseInput(std::string inputString); @@ -33,6 +40,8 @@ class Parser { std::map symbols; std::vector loadedGrammer; + std::vector< std::vector* > stateSets; + std::stack stateStack; std::stack symbolStack; diff --git a/main.cpp b/main.cpp index 31e07c1..56b32b4 100644 --- a/main.cpp +++ b/main.cpp @@ -41,6 +41,8 @@ int main(int argc, char* argv[]) { Parser parser; parser.loadGrammer(inputFileString); + parser.createStateSet(); + std::cout << parser.stateSetToString() << std::endl; std::cout << inputFileString << std::endl; std::cout << parser.grammerToString() << std::endl; diff --git a/src/ParseRule.cpp b/src/ParseRule.cpp index f493cc1..b54cb9f 100644 --- a/src/ParseRule.cpp +++ b/src/ParseRule.cpp @@ -15,6 +15,10 @@ ParseRule::~ParseRule() { } +const bool ParseRule::operator==(const ParseRule &other) { + return( leftHandle == other.leftHandle && rightSide == other.rightSide && pointerIndex == other.pointerIndex ); +} + ParseRule* ParseRule::clone() { return( new ParseRule(leftHandle, pointerIndex, rightSide) ); } @@ -35,6 +39,10 @@ std::vector ParseRule::getRightSide() { return rightSide; } +int ParseRule::getIndex() { + return pointerIndex; +} + bool ParseRule::advancePointer() { if (pointerIndex < rightSide.size()) { pointerIndex++; diff --git a/src/Parser.cpp b/src/Parser.cpp index dbccab0..88ee345 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -8,6 +8,12 @@ Parser::~Parser() { } +std::string Parser::intToString(int theInt) { + std::stringstream converter; + converter << theInt; + return converter.str(); +} + Symbol* Parser::getOrAddSymbol(std::string symbolString, bool isTerminal) { Symbol* symbol; if (symbols.find(symbolString) == symbols.end()) { @@ -51,6 +57,93 @@ void Parser::loadGrammer(std::string grammerInputString) { std::cout << "Parsed!\n"; } +void Parser::createStateSet() { + stateSets.push_back( new std::vector ); + stateSets[0]->push_back(loadedGrammer[0]); + for (std::vector< std::vector* >::iterator i = stateSets.begin(); i != stateSets.end(); i++) { + closure(*i); + for (std::vector::iterator j = (*i)->begin(); j != (*i)->end(); j++) { + addState(&stateSets, *i, (*j)->getRightSide()[(*j)->getIndex()]); + //Closure will be called in the outer loop + } + } +} + +void Parser::closure(std::vector* state) { + //Add all the applicable rules. + for (std::vector::iterator i = state->begin(); i != state->end(); i++) { + for (std::vector::iterator j = loadedGrammer.begin(); j != loadedGrammer.end(); j++) { + if ((*i)->getRightSide()[(*i)->getIndex()] == (*j)->getLeftSide()) { + //Check to make sure not already in + bool isAlreadyInState = false; + for (std::vector::iterator k = state->begin(); k != state->end(); k++) { + if ((*k) == (*i)) { + isAlreadyInState = true; + break; + } + } + if (!isAlreadyInState) + state->push_back(*j); + } + } + } +} + +//Adds state if it doesn't already exist. +void Parser::addState(std::vector< std::vector* >* stateSets, std::vector* state, Symbol* symbol) { + std::vector* > newStates; + //For each rule in the state we already have + for (std::vector::iterator i = state->begin(); i != state->end(); i++) { + //Clone the current rule + ParseRule* advancedRule = (*i)->clone(); + //Try to advance the pointer + if (advancedRule->advancePointer()) { + //If sucessful, check to see if this the advanced symbol is the basis for any of our new states + bool symbolAlreadyInState = false; + for (std::vector* >::iterator j = newStates.begin(); j != newStates.end(); j++) { + if ((**j)[0]->getRightSide()[(**j)[0]->getIndex()] == advancedRule->getRightSide()[advancedRule->getIndex()]) { + symbolAlreadyInState = true; + //So now check to see if this exact rule is in this state + bool ruleAlreadyInState = false; + for (std::vector::iterator k = (*j)->begin(); k != (*j)->end(); k++) { + if (*(*k) == (*advancedRule) ) { + ruleAlreadyInState = true; + break; + } + } + if (!ruleAlreadyInState) { + (*j)->push_back(advancedRule); + } + //We found a state with the same symbol, so stop searching + break; + } + } + if (!symbolAlreadyInState) { + std::vector* newState = new std::vector; + newState->push_back(advancedRule); + newStates.push_back(newState); + } + } + } + //Put all our new states in the set of states + for (std::vector< std::vector * >::iterator i = newStates.begin(); i != newStates.end(); i++) { + stateSets->push_back((*i)); + } +} + +std::string Parser::stateSetToString() { + std::string concat = ""; + int currentNum = 0; + for (std::vector< std::vector *>::iterator i = stateSets.begin(); i != stateSets.end(); i++) { + concat += "State " + intToString(currentNum) + ":\n"; + for (std::vector::iterator j = (*i)->begin(); j != (*i)->end(); j++) { + concat += "\t" + (*j)->toString() + "\n"; + } + concat += "\n"; + } + return concat; +} + int Parser::gotoTable(int state, Symbol* token) { return 0; }