Added followSets(Symbol*) function to compute follow sets.
This commit is contained in:
@@ -25,6 +25,8 @@ class Parser {
|
|||||||
void loadGrammer(std::string grammerInputString);
|
void loadGrammer(std::string grammerInputString);
|
||||||
std::vector<Symbol*>* firstSet(Symbol* token);
|
std::vector<Symbol*>* firstSet(Symbol* token);
|
||||||
void printFirstSets();
|
void printFirstSets();
|
||||||
|
std::vector<Symbol*>* followSet(Symbol* token);
|
||||||
|
void printFollowSets();
|
||||||
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
@@ -70,6 +70,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();
|
parser.printFirstSets();
|
||||||
|
parser.printFollowSets();
|
||||||
|
|
||||||
if (parseTree) {
|
if (parseTree) {
|
||||||
std::cout << parseTree->DOTGraphString() << std::endl;
|
std::cout << parseTree->DOTGraphString() << std::endl;
|
||||||
|
|||||||
@@ -89,6 +89,56 @@ void Parser::printFirstSets() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Symbol*>* Parser::followSet(Symbol* token) {
|
||||||
|
std::vector<Symbol*>* follow = new std::vector<Symbol*>();
|
||||||
|
//First, if the symbol is a terminal, than it's follow set is the empty set.
|
||||||
|
if (token->isTerminal()) {
|
||||||
|
return(follow);
|
||||||
|
}
|
||||||
|
//Otherwise....
|
||||||
|
//Ok, to make a follow set, go through the grammer looking for the terminal in the right side. If it exists
|
||||||
|
//Then add to it's follow set the first set of the next token, or if it is at the end, the follow set of the left side.
|
||||||
|
//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*>* recursiveFollowSet = NULL;
|
||||||
|
std::vector<Symbol*> rightSide;
|
||||||
|
for (std::vector<ParseRule*>::size_type i = 0; i < loadedGrammer.size(); i++) {
|
||||||
|
rightSide = loadedGrammer[i]->getRightSide();
|
||||||
|
for (std::vector<Symbol*>::size_type j = 0; j < rightSide.size(); j++) {
|
||||||
|
if (*token == *(rightSide[j])) {
|
||||||
|
//If this is the first grammer rule, that is the goal rule, add $EOF$ and move on
|
||||||
|
if (i == 0) {
|
||||||
|
follow->push_back(new Symbol("$EOF$", false));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j < rightSide.size()-1) {
|
||||||
|
if (rightSide[j+1]->isTerminal())
|
||||||
|
follow->push_back(rightSide[j+1]);
|
||||||
|
else {
|
||||||
|
recursiveFollowSet = firstSet(rightSide[j+1]);
|
||||||
|
follow->insert(follow->begin(), recursiveFollowSet->begin(), recursiveFollowSet->end());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
recursiveFollowSet = followSet(loadedGrammer[i]->getLeftSide());
|
||||||
|
follow->insert(follow->begin(), recursiveFollowSet->begin(), recursiveFollowSet->end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(follow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parser::printFollowSets() {
|
||||||
|
std::vector<Symbol*>* follow = NULL;
|
||||||
|
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) {
|
||||||
|
follow = followSet(symbolIndexVec[i]);
|
||||||
|
std::cout << "Follow set of " << symbolIndexVec[i]->toString() << " is: ";
|
||||||
|
for (std::vector<Symbol*>::size_type j = 0; j < follow->size(); j++)
|
||||||
|
std::cout << (*follow)[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