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*.
This commit is contained in:
@@ -23,6 +23,8 @@ class Parser {
|
|||||||
~Parser();
|
~Parser();
|
||||||
|
|
||||||
void loadGrammer(std::string grammerInputString);
|
void loadGrammer(std::string grammerInputString);
|
||||||
|
std::vector<Symbol*>* firstSet(Symbol* token);
|
||||||
|
void printFirstSets();
|
||||||
void createStateSet();
|
void createStateSet();
|
||||||
void closure(State* state);
|
void closure(State* state);
|
||||||
void addStates(std::vector< State* >* stateSets, State* state);
|
void addStates(std::vector< State* >* stateSets, State* state);
|
||||||
|
|||||||
1
main.cpp
1
main.cpp
@@ -69,6 +69,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
std::cout << programInputFileString << std::endl;
|
std::cout << programInputFileString << std::endl;
|
||||||
NodeTree* parseTree = parser.parseInput(new Lexer(programInputFileString));
|
NodeTree* parseTree = parser.parseInput(new Lexer(programInputFileString));
|
||||||
|
parser.printFirstSets();
|
||||||
|
|
||||||
if (parseTree) {
|
if (parseTree) {
|
||||||
std::cout << parseTree->DOTGraphString() << std::endl;
|
std::cout << parseTree->DOTGraphString() << std::endl;
|
||||||
|
|||||||
@@ -51,6 +51,44 @@ void Parser::loadGrammer(std::string grammerInputString) {
|
|||||||
std::cout << "Parsed!\n";
|
std::cout << "Parsed!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Symbol*>* Parser::firstSet(Symbol* token) {
|
||||||
|
std::vector<Symbol*>* first = new std::vector<Symbol*>();
|
||||||
|
//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<Symbol*>* recursiveFirstSet = NULL;
|
||||||
|
for (std::vector<ParseRule*>::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<Symbol*>* first = NULL;
|
||||||
|
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) {
|
||||||
|
first = firstSet(symbolIndexVec[i]);
|
||||||
|
std::cout << "First set of " << symbolIndexVec[i]->toString() << " is: ";
|
||||||
|
for (std::vector<Symbol*>::size_type j = 0; j < first->size(); j++)
|
||||||
|
std::cout << (*first)[j]->toString() << " ";
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Parser::createStateSet() {
|
void Parser::createStateSet() {
|
||||||
std::cout << "Begining creation of stateSet" << std::endl;
|
std::cout << "Begining creation of stateSet" << std::endl;
|
||||||
stateSets.push_back( new State(0, loadedGrammer[0]) );
|
stateSets.push_back( new State(0, loadedGrammer[0]) );
|
||||||
|
|||||||
Reference in New Issue
Block a user