From da6e5f3de96df2ee4ea024bef11f20fe6ed3b6c4 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Thu, 13 Jun 2013 19:11:31 -0400 Subject: [PATCH] Added a firstSet(Symbol*) function that takes in a Symbol* and returns a vector of Symbol* s that are the first set of the first Symbol*. --- include/Parser.h | 2 ++ main.cpp | 1 + src/Parser.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/include/Parser.h b/include/Parser.h index 376e2cb..f1ce373 100644 --- a/include/Parser.h +++ b/include/Parser.h @@ -23,6 +23,8 @@ class Parser { ~Parser(); void loadGrammer(std::string grammerInputString); + std::vector* firstSet(Symbol* token); + void printFirstSets(); void createStateSet(); void closure(State* state); void addStates(std::vector< State* >* stateSets, State* state); diff --git a/main.cpp b/main.cpp index e46ad53..1a140b1 100644 --- a/main.cpp +++ b/main.cpp @@ -69,6 +69,7 @@ int main(int argc, char* argv[]) { std::cout << programInputFileString << std::endl; NodeTree* parseTree = parser.parseInput(new Lexer(programInputFileString)); + parser.printFirstSets(); if (parseTree) { std::cout << parseTree->DOTGraphString() << std::endl; diff --git a/src/Parser.cpp b/src/Parser.cpp index c00beb4..65c9833 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -51,6 +51,44 @@ void Parser::loadGrammer(std::string grammerInputString) { std::cout << "Parsed!\n"; } +std::vector* Parser::firstSet(Symbol* token) { + std::vector* first = new std::vector(); + //First, if the symbol is a terminal, than it's first set is just itself. + if (token->isTerminal()) { + first->push_back(token); + return(first); + } + //Otherwise.... + //Ok, to make a first set, go through the grammer, if the token is part of the left side, add it's production's first token's first set. + //Theoretically, if that one includes mull, do the next one too. However, null productions have not yet been implemented. + Symbol* rightToken = NULL; + std::vector* recursiveFirstSet = NULL; + for (std::vector::size_type i = 0; i < loadedGrammer.size(); i++) { + if (*token == *(loadedGrammer[i]->getLeftSide())) { + rightToken = loadedGrammer[i]->getRightSide()[0]; //Get the first token of the right side of this rule + if (rightToken->isTerminal()) + first->push_back(rightToken); + else { + //Add the entire set + recursiveFirstSet = firstSet(rightToken); + first->insert(first->end(), recursiveFirstSet->begin(), recursiveFirstSet->end()); + } + } + } + return(first); +} + +void Parser::printFirstSets() { + std::vector* first = NULL; + for (std::vector::size_type i = 0; i < symbolIndexVec.size(); i++) { + first = firstSet(symbolIndexVec[i]); + std::cout << "First set of " << symbolIndexVec[i]->toString() << " is: "; + for (std::vector::size_type j = 0; j < first->size(); j++) + std::cout << (*first)[j]->toString() << " "; + std::cout << std::endl; + } +} + void Parser::createStateSet() { std::cout << "Begining creation of stateSet" << std::endl; stateSets.push_back( new State(0, loadedGrammer[0]) );