diff --git a/include/ParseAction.h b/include/ParseAction.h index 270be4d..c421b44 100644 --- a/include/ParseAction.h +++ b/include/ParseAction.h @@ -13,7 +13,9 @@ class ParseAction { public: enum ActionType { INVALID, REDUCE, SHIFT, ACCEPT, REJECT }; - ParseAction(ActionType action, ParseRule* reduceRule = NULL, int shiftState = 0); + ParseAction(ActionType action); + ParseAction(ActionType action, ParseRule* reduceRule); + ParseAction(ActionType action, int shiftState); ~ParseAction(); std::string toString(); static std::string actionToString(ActionType action); diff --git a/include/ParseRule.h b/include/ParseRule.h index e2edbd7..e4a3470 100644 --- a/include/ParseRule.h +++ b/include/ParseRule.h @@ -33,6 +33,7 @@ class ParseRule { int getIndex(); bool advancePointer(); + bool isAtEnd(); std::string toString(); std::string toDOT(); diff --git a/include/Parser.h b/include/Parser.h index 936e2b9..84785ea 100644 --- a/include/Parser.h +++ b/include/Parser.h @@ -40,6 +40,8 @@ class Parser { std::vector< State* > stateSets; + //std::vector< std::vector > + std::stack stateStack; std::stack symbolStack; diff --git a/main.cpp b/main.cpp index 9130dcd..8c3120a 100644 --- a/main.cpp +++ b/main.cpp @@ -7,18 +7,24 @@ int main(int argc, char* argv[]) { - std::ifstream inFile; + std::ifstream programInFile, grammerInFile; std::ofstream outFile; - inFile.open(argv[1]); - if (!inFile.is_open()) { - std::cout << "Problem opening input file " << argv[1] << "\n"; + programInFile.open(argv[1]); + if (!programInFile.is_open()) { + std::cout << "Problem opening programInFile " << argv[1] << "\n"; return(1); } - outFile.open(argv[2]); + grammerInFile.open(argv[2]); + if (!grammerInFile.is_open()) { + std::cout << "Problem opening grammerInFile " << argv[2] << "\n"; + return(1); + } + + outFile.open(argv[3]); if (!outFile.is_open()) { - std::cout << "Probelm opening output file " << argv[2] << "\n"; + std::cout << "Probelm opening output file " << argv[3] << "\n"; return(1); } @@ -32,15 +38,20 @@ int main(int argc, char* argv[]) { //Read the input file into a string - std::string inputFileString; + std::string programInputFileString, grammerInputFileString; std::string line; - while(inFile.good()) { - getline(inFile, line); - inputFileString.append(line+"\n"); + while(grammerInFile.good()) { + getline(grammerInFile, line); + grammerInputFileString.append(line+"\n"); + } + + while(programInFile.good()) { + getline(programInFile, line); + programInputFileString.append(line+"\n"); } Parser parser; - parser.loadGrammer(inputFileString); + parser.loadGrammer(grammerInputFileString); std::cout << "Creating State Set from Main" << std::endl; parser.createStateSet(); std::cout << "finished State Set from Main" << std::endl; @@ -48,13 +59,17 @@ int main(int argc, char* argv[]) { std::cout << parser.stateSetToString() << std::endl; std::cout << "finished stateSetToString from Main" << std::endl; - std::cout << inputFileString << std::endl; + std::cout << grammerInputFileString << std::endl; std::cout << parser.grammerToString() << std::endl; std::cout << parser.grammerToDOT() << std::endl; outFile << parser.grammerToDOT() << std::endl; - inFile.close(); + std::cout << programInputFileString << std::endl; + parser.parseInput(programInputFileString); + + programInFile.close(); + grammerInFile.close(); outFile.close(); return(0); diff --git a/src/ParseAction.cpp b/src/ParseAction.cpp index 62342d5..6296d58 100644 --- a/src/ParseAction.cpp +++ b/src/ParseAction.cpp @@ -1,8 +1,20 @@ #include "ParseAction.h" -ParseAction::ParseAction(ActionType action, ParseRule* reduceRule, int shiftState) { +ParseAction::ParseAction(ActionType action) { + this->action = action; + this->reduceRule = NULL; + this->shiftState = -1; +} + +ParseAction::ParseAction(ActionType action, ParseRule* reduceRule) { this->action = action; this->reduceRule = reduceRule; + this->shiftState = -1; +} + +ParseAction::ParseAction(ActionType action, int shiftState) { + this->action = action; + this->reduceRule = NULL; this->shiftState = shiftState; } diff --git a/src/ParseRule.cpp b/src/ParseRule.cpp index 1e2d1a4..cf69511 100644 --- a/src/ParseRule.cpp +++ b/src/ParseRule.cpp @@ -71,6 +71,10 @@ bool ParseRule::advancePointer() { return false; } +bool ParseRule::isAtEnd() { + return pointerIndex == rightSide.size(); +} + std::string ParseRule::toString() { std::string concat = leftHandle->toString() + " -> "; for (int i = 0; i < rightSide.size(); i++) { diff --git a/src/Parser.cpp b/src/Parser.cpp index f86a77c..c649c58 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -150,18 +150,57 @@ std::string Parser::stateSetToString() { } int Parser::gotoTable(int state, Symbol* token) { - return 0; + std::vector allInState = *(stateSets[state]->getTotal()); + ParseRule* currentRule; + for (std::vector::size_type i = 0; i < allInState.size(); i++) { + currentRule = allInState[i]; + if (*(currentRule->getAtNextIndex()) == *token) { + ParseRule* advancedCurrent = currentRule->clone(); + advancedCurrent->advancePointer(); + for (std::vector::size_type j = 0; j < stateSets.size(); j++) { + for (std::vector::size_type k = 0; k < stateSets[j]->basis.size(); k++ ) { + if ( *(stateSets[j]->basis[k]) == *advancedCurrent) + return(j); + } + } + } + } + return(-1); } ParseAction* Parser::actionTable(int state, Symbol* token) { - return NULL; + std::vector* allStateRules = stateSets[state]->getTotal(); + ParseRule* currentRule; + for (std::vector::size_type i = 0; i < allStateRules->size(); i++) { + currentRule = (*allStateRules)[i]; + //If the current rule in the state is completed, then do a reduce action + if (currentRule->isAtEnd()) { + if (*currentRule == *(stateSets[0]->basis[0])) + return new ParseAction(ParseAction::ACCEPT); + return new ParseAction(ParseAction::REDUCE, currentRule); + } + //If the current rule in the state is not completed, see if it has the next correct token + std::cout << currentRule->getAtNextIndex()->toString() << " comp to " << token->toString() << std::endl; + if ( *(currentRule->getAtNextIndex()) == *token){ + //If it does have the correct next token, then find the state that has this rule advanced as basis, that is the state we shift to + //Goes to n^2 here, really need that table + ParseRule* advancedCurrent = currentRule->clone(); + advancedCurrent->advancePointer(); + for (std::vector::size_type j = 0; j < stateSets.size(); j++) { + for (std::vector::size_type k = 0; k < stateSets[j]->basis.size(); k++ ) { + if ( *(stateSets[j]->basis[k]) == *advancedCurrent) + return new ParseAction(ParseAction::SHIFT, j); + } + } + } + } + return new ParseAction(ParseAction::REJECT); } void Parser::parseInput(std::string inputString) { StringReader inputReader; inputReader.setString(inputString); - - Symbol* token = new Symbol(reader.word(), false); + Symbol* token = new Symbol(inputReader.word(), true); ParseAction* action; stateStack.push(0); @@ -184,7 +223,7 @@ void Parser::parseInput(std::string inputString) { } case ParseAction::SHIFT: symbolStack.push(token); - token = new Symbol(inputReader.word(), false); + token = new Symbol(inputReader.word(), true); stateStack.push(action->shiftState); std::cout << "Shift " << symbolStack.top()->toString() << std::endl; break; diff --git a/src/Symbol.cpp b/src/Symbol.cpp index 4da17da..8230462 100644 --- a/src/Symbol.cpp +++ b/src/Symbol.cpp @@ -14,6 +14,6 @@ const bool Symbol::operator==(const Symbol &other) { } std::string Symbol::toString() { - return(name); + return(name + "(" + (isTerminal ? "T" : "NT") + ")"); }