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:
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
41
main.cpp
41
main.cpp
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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++) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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") + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user