Added first go at creating stateSets. This is a commit to save work, as it still segfaults.:
This commit is contained in:
@@ -17,6 +17,8 @@ class ParseRule {
|
|||||||
ParseRule(Symbol* leftHandle, int pointerIndex, std::vector<Symbol*> &rightSide);
|
ParseRule(Symbol* leftHandle, int pointerIndex, std::vector<Symbol*> &rightSide);
|
||||||
~ParseRule();
|
~ParseRule();
|
||||||
|
|
||||||
|
bool const operator==(const ParseRule &other);
|
||||||
|
|
||||||
ParseRule* clone();
|
ParseRule* clone();
|
||||||
|
|
||||||
void setLeftHandle(Symbol* leftHandle);
|
void setLeftHandle(Symbol* leftHandle);
|
||||||
@@ -24,6 +26,7 @@ class ParseRule {
|
|||||||
|
|
||||||
Symbol* getLeftSide();
|
Symbol* getLeftSide();
|
||||||
std::vector<Symbol*> getRightSide();
|
std::vector<Symbol*> getRightSide();
|
||||||
|
int getIndex();
|
||||||
|
|
||||||
bool advancePointer();
|
bool advancePointer();
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
@@ -21,7 +22,13 @@ class Parser {
|
|||||||
Parser();
|
Parser();
|
||||||
~Parser();
|
~Parser();
|
||||||
|
|
||||||
|
std::string intToString(int theInt);
|
||||||
|
|
||||||
void loadGrammer(std::string grammerInputString);
|
void loadGrammer(std::string grammerInputString);
|
||||||
|
void createStateSet();
|
||||||
|
void closure(std::vector<ParseRule*>* state);
|
||||||
|
void addState(std::vector< std::vector<ParseRule*>* >* stateSets, std::vector<ParseRule*>* state, Symbol*);
|
||||||
|
std::string stateSetToString();
|
||||||
int gotoTable(int state, Symbol* token);
|
int gotoTable(int state, Symbol* token);
|
||||||
ParseAction* actionTable(int state, Symbol* token);
|
ParseAction* actionTable(int state, Symbol* token);
|
||||||
void parseInput(std::string inputString);
|
void parseInput(std::string inputString);
|
||||||
@@ -33,6 +40,8 @@ class Parser {
|
|||||||
std::map<std::string, Symbol*> symbols;
|
std::map<std::string, Symbol*> symbols;
|
||||||
std::vector<ParseRule*> loadedGrammer;
|
std::vector<ParseRule*> loadedGrammer;
|
||||||
|
|
||||||
|
std::vector< std::vector<ParseRule*>* > stateSets;
|
||||||
|
|
||||||
std::stack<int> stateStack;
|
std::stack<int> stateStack;
|
||||||
std::stack<Symbol*> symbolStack;
|
std::stack<Symbol*> symbolStack;
|
||||||
|
|
||||||
|
|||||||
2
main.cpp
2
main.cpp
@@ -41,6 +41,8 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
Parser parser;
|
Parser parser;
|
||||||
parser.loadGrammer(inputFileString);
|
parser.loadGrammer(inputFileString);
|
||||||
|
parser.createStateSet();
|
||||||
|
std::cout << parser.stateSetToString() << std::endl;
|
||||||
|
|
||||||
std::cout << inputFileString << std::endl;
|
std::cout << inputFileString << std::endl;
|
||||||
std::cout << parser.grammerToString() << std::endl;
|
std::cout << parser.grammerToString() << std::endl;
|
||||||
|
|||||||
@@ -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() {
|
ParseRule* ParseRule::clone() {
|
||||||
return( new ParseRule(leftHandle, pointerIndex, rightSide) );
|
return( new ParseRule(leftHandle, pointerIndex, rightSide) );
|
||||||
}
|
}
|
||||||
@@ -35,6 +39,10 @@ std::vector<Symbol*> ParseRule::getRightSide() {
|
|||||||
return rightSide;
|
return rightSide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ParseRule::getIndex() {
|
||||||
|
return pointerIndex;
|
||||||
|
}
|
||||||
|
|
||||||
bool ParseRule::advancePointer() {
|
bool ParseRule::advancePointer() {
|
||||||
if (pointerIndex < rightSide.size()) {
|
if (pointerIndex < rightSide.size()) {
|
||||||
pointerIndex++;
|
pointerIndex++;
|
||||||
|
|||||||
@@ -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* Parser::getOrAddSymbol(std::string symbolString, bool isTerminal) {
|
||||||
Symbol* symbol;
|
Symbol* symbol;
|
||||||
if (symbols.find(symbolString) == symbols.end()) {
|
if (symbols.find(symbolString) == symbols.end()) {
|
||||||
@@ -51,6 +57,93 @@ void Parser::loadGrammer(std::string grammerInputString) {
|
|||||||
std::cout << "Parsed!\n";
|
std::cout << "Parsed!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parser::createStateSet() {
|
||||||
|
stateSets.push_back( new std::vector<ParseRule*> );
|
||||||
|
stateSets[0]->push_back(loadedGrammer[0]);
|
||||||
|
for (std::vector< std::vector<ParseRule*>* >::iterator i = stateSets.begin(); i != stateSets.end(); i++) {
|
||||||
|
closure(*i);
|
||||||
|
for (std::vector<ParseRule*>::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<ParseRule*>* state) {
|
||||||
|
//Add all the applicable rules.
|
||||||
|
for (std::vector<ParseRule*>::iterator i = state->begin(); i != state->end(); i++) {
|
||||||
|
for (std::vector<ParseRule*>::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<ParseRule*>::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<ParseRule*>* >* stateSets, std::vector<ParseRule*>* state, Symbol* symbol) {
|
||||||
|
std::vector<std::vector<ParseRule*>* > newStates;
|
||||||
|
//For each rule in the state we already have
|
||||||
|
for (std::vector<ParseRule*>::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<std::vector<ParseRule*>* >::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<ParseRule*>::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<ParseRule*>* newState = new std::vector<ParseRule*>;
|
||||||
|
newState->push_back(advancedRule);
|
||||||
|
newStates.push_back(newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Put all our new states in the set of states
|
||||||
|
for (std::vector< std::vector<ParseRule*> * >::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<ParseRule*> *>::iterator i = stateSets.begin(); i != stateSets.end(); i++) {
|
||||||
|
concat += "State " + intToString(currentNum) + ":\n";
|
||||||
|
for (std::vector<ParseRule*>::iterator j = (*i)->begin(); j != (*i)->end(); j++) {
|
||||||
|
concat += "\t" + (*j)->toString() + "\n";
|
||||||
|
}
|
||||||
|
concat += "\n";
|
||||||
|
}
|
||||||
|
return concat;
|
||||||
|
}
|
||||||
|
|
||||||
int Parser::gotoTable(int state, Symbol* token) {
|
int Parser::gotoTable(int state, Symbol* token) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user