Actually parses LR(0) grammers and sentences\! Only two problems is very inefficint gotoTable() and actionTable(), and it REJECTS the sentence after completing the Goal->Sentence(*) production. However, need to go to bed now. Does practially work though\! Yay\!

This commit is contained in:
Nathan Braswell
2013-05-29 20:43:35 -04:00
parent 315dc55409
commit 69713ffe1a
8 changed files with 96 additions and 21 deletions

View File

@@ -13,7 +13,9 @@
class ParseAction { class ParseAction {
public: public:
enum ActionType { INVALID, REDUCE, SHIFT, ACCEPT, REJECT }; 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(); ~ParseAction();
std::string toString(); std::string toString();
static std::string actionToString(ActionType action); static std::string actionToString(ActionType action);

View File

@@ -33,6 +33,7 @@ class ParseRule {
int getIndex(); int getIndex();
bool advancePointer(); bool advancePointer();
bool isAtEnd();
std::string toString(); std::string toString();
std::string toDOT(); std::string toDOT();

View File

@@ -40,6 +40,8 @@ class Parser {
std::vector< State* > stateSets; std::vector< State* > stateSets;
//std::vector< std::vector<ParseAction*> >
std::stack<int> stateStack; std::stack<int> stateStack;
std::stack<Symbol*> symbolStack; std::stack<Symbol*> symbolStack;

View File

@@ -7,18 +7,24 @@
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
std::ifstream inFile; std::ifstream programInFile, grammerInFile;
std::ofstream outFile; std::ofstream outFile;
inFile.open(argv[1]); programInFile.open(argv[1]);
if (!inFile.is_open()) { if (!programInFile.is_open()) {
std::cout << "Problem opening input file " << argv[1] << "\n"; std::cout << "Problem opening programInFile " << argv[1] << "\n";
return(1); 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()) { if (!outFile.is_open()) {
std::cout << "Probelm opening output file " << argv[2] << "\n"; std::cout << "Probelm opening output file " << argv[3] << "\n";
return(1); return(1);
} }
@@ -32,15 +38,20 @@ int main(int argc, char* argv[]) {
//Read the input file into a string //Read the input file into a string
std::string inputFileString; std::string programInputFileString, grammerInputFileString;
std::string line; std::string line;
while(inFile.good()) { while(grammerInFile.good()) {
getline(inFile, line); getline(grammerInFile, line);
inputFileString.append(line+"\n"); grammerInputFileString.append(line+"\n");
}
while(programInFile.good()) {
getline(programInFile, line);
programInputFileString.append(line+"\n");
} }
Parser parser; Parser parser;
parser.loadGrammer(inputFileString); parser.loadGrammer(grammerInputFileString);
std::cout << "Creating State Set from Main" << std::endl; std::cout << "Creating State Set from Main" << std::endl;
parser.createStateSet(); parser.createStateSet();
std::cout << "finished State Set from Main" << std::endl; 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 << parser.stateSetToString() << std::endl;
std::cout << "finished stateSetToString from Main" << 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.grammerToString() << std::endl;
std::cout << parser.grammerToDOT() << std::endl; std::cout << parser.grammerToDOT() << std::endl;
outFile << 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(); outFile.close();
return(0); return(0);

View File

@@ -1,8 +1,20 @@
#include "ParseAction.h" #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->action = action;
this->reduceRule = reduceRule; this->reduceRule = reduceRule;
this->shiftState = -1;
}
ParseAction::ParseAction(ActionType action, int shiftState) {
this->action = action;
this->reduceRule = NULL;
this->shiftState = shiftState; this->shiftState = shiftState;
} }

View File

@@ -71,6 +71,10 @@ bool ParseRule::advancePointer() {
return false; return false;
} }
bool ParseRule::isAtEnd() {
return pointerIndex == rightSide.size();
}
std::string ParseRule::toString() { std::string ParseRule::toString() {
std::string concat = leftHandle->toString() + " -> "; std::string concat = leftHandle->toString() + " -> ";
for (int i = 0; i < rightSide.size(); i++) { for (int i = 0; i < rightSide.size(); i++) {

View File

@@ -150,18 +150,57 @@ std::string Parser::stateSetToString() {
} }
int Parser::gotoTable(int state, Symbol* token) { int Parser::gotoTable(int state, Symbol* token) {
return 0; std::vector<ParseRule*> allInState = *(stateSets[state]->getTotal());
ParseRule* currentRule;
for (std::vector<ParseRule*>::size_type i = 0; i < allInState.size(); i++) {
currentRule = allInState[i];
if (*(currentRule->getAtNextIndex()) == *token) {
ParseRule* advancedCurrent = currentRule->clone();
advancedCurrent->advancePointer();
for (std::vector<State*>::size_type j = 0; j < stateSets.size(); j++) {
for (std::vector<ParseRule*>::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) { ParseAction* Parser::actionTable(int state, Symbol* token) {
return NULL; std::vector<ParseRule*>* allStateRules = stateSets[state]->getTotal();
ParseRule* currentRule;
for (std::vector<ParseRule*>::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<State*>::size_type j = 0; j < stateSets.size(); j++) {
for (std::vector<ParseRule*>::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) { void Parser::parseInput(std::string inputString) {
StringReader inputReader; StringReader inputReader;
inputReader.setString(inputString); inputReader.setString(inputString);
Symbol* token = new Symbol(inputReader.word(), true);
Symbol* token = new Symbol(reader.word(), false);
ParseAction* action; ParseAction* action;
stateStack.push(0); stateStack.push(0);
@@ -184,7 +223,7 @@ void Parser::parseInput(std::string inputString) {
} }
case ParseAction::SHIFT: case ParseAction::SHIFT:
symbolStack.push(token); symbolStack.push(token);
token = new Symbol(inputReader.word(), false); token = new Symbol(inputReader.word(), true);
stateStack.push(action->shiftState); stateStack.push(action->shiftState);
std::cout << "Shift " << symbolStack.top()->toString() << std::endl; std::cout << "Shift " << symbolStack.top()->toString() << std::endl;
break; break;

View File

@@ -14,6 +14,6 @@ const bool Symbol::operator==(const Symbol &other) {
} }
std::string Symbol::toString() { std::string Symbol::toString() {
return(name); return(name + "(" + (isTerminal ? "T" : "NT") + ")");
} }