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 {
|
||||
public:
|
||||
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();
|
||||
std::string toString();
|
||||
static std::string actionToString(ActionType action);
|
||||
|
||||
@@ -33,6 +33,7 @@ class ParseRule {
|
||||
int getIndex();
|
||||
|
||||
bool advancePointer();
|
||||
bool isAtEnd();
|
||||
|
||||
std::string toString();
|
||||
std::string toDOT();
|
||||
|
||||
@@ -40,6 +40,8 @@ class Parser {
|
||||
|
||||
std::vector< State* > stateSets;
|
||||
|
||||
//std::vector< std::vector<ParseAction*> >
|
||||
|
||||
std::stack<int> stateStack;
|
||||
std::stack<Symbol*> symbolStack;
|
||||
|
||||
|
||||
41
main.cpp
41
main.cpp
@@ -7,18 +7,24 @@
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
std::ifstream inFile;
|
||||
std::ifstream programInFile, grammerInFile;
|
||||
std::ofstream outFile;
|
||||
|
||||
inFile.open(argv[1]);
|
||||
if (!inFile.is_open()) {
|
||||
std::cout << "Problem opening input file " << argv[1] << "\n";
|
||||
programInFile.open(argv[1]);
|
||||
if (!programInFile.is_open()) {
|
||||
std::cout << "Problem opening programInFile " << argv[1] << "\n";
|
||||
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()) {
|
||||
std::cout << "Probelm opening output file " << argv[2] << "\n";
|
||||
std::cout << "Probelm opening output file " << argv[3] << "\n";
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -32,15 +38,20 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
|
||||
//Read the input file into a string
|
||||
std::string inputFileString;
|
||||
std::string programInputFileString, grammerInputFileString;
|
||||
std::string line;
|
||||
while(inFile.good()) {
|
||||
getline(inFile, line);
|
||||
inputFileString.append(line+"\n");
|
||||
while(grammerInFile.good()) {
|
||||
getline(grammerInFile, line);
|
||||
grammerInputFileString.append(line+"\n");
|
||||
}
|
||||
|
||||
while(programInFile.good()) {
|
||||
getline(programInFile, line);
|
||||
programInputFileString.append(line+"\n");
|
||||
}
|
||||
|
||||
Parser parser;
|
||||
parser.loadGrammer(inputFileString);
|
||||
parser.loadGrammer(grammerInputFileString);
|
||||
std::cout << "Creating State Set from Main" << std::endl;
|
||||
parser.createStateSet();
|
||||
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 << "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.grammerToDOT() << std::endl;
|
||||
|
||||
outFile << parser.grammerToDOT() << std::endl;
|
||||
|
||||
inFile.close();
|
||||
std::cout << programInputFileString << std::endl;
|
||||
parser.parseInput(programInputFileString);
|
||||
|
||||
programInFile.close();
|
||||
grammerInFile.close();
|
||||
outFile.close();
|
||||
|
||||
return(0);
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
#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->reduceRule = reduceRule;
|
||||
this->shiftState = -1;
|
||||
}
|
||||
|
||||
ParseAction::ParseAction(ActionType action, int shiftState) {
|
||||
this->action = action;
|
||||
this->reduceRule = NULL;
|
||||
this->shiftState = shiftState;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,10 @@ bool ParseRule::advancePointer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParseRule::isAtEnd() {
|
||||
return pointerIndex == rightSide.size();
|
||||
}
|
||||
|
||||
std::string ParseRule::toString() {
|
||||
std::string concat = leftHandle->toString() + " -> ";
|
||||
for (int i = 0; i < rightSide.size(); i++) {
|
||||
|
||||
@@ -150,18 +150,57 @@ std::string Parser::stateSetToString() {
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
StringReader inputReader;
|
||||
inputReader.setString(inputString);
|
||||
|
||||
Symbol* token = new Symbol(reader.word(), false);
|
||||
Symbol* token = new Symbol(inputReader.word(), true);
|
||||
ParseAction* action;
|
||||
|
||||
stateStack.push(0);
|
||||
@@ -184,7 +223,7 @@ void Parser::parseInput(std::string inputString) {
|
||||
}
|
||||
case ParseAction::SHIFT:
|
||||
symbolStack.push(token);
|
||||
token = new Symbol(inputReader.word(), false);
|
||||
token = new Symbol(inputReader.word(), true);
|
||||
stateStack.push(action->shiftState);
|
||||
std::cout << "Shift " << symbolStack.top()->toString() << std::endl;
|
||||
break;
|
||||
|
||||
@@ -14,6 +14,6 @@ const bool Symbol::operator==(const Symbol &other) {
|
||||
}
|
||||
|
||||
std::string Symbol::toString() {
|
||||
return(name);
|
||||
return(name + "(" + (isTerminal ? "T" : "NT") + ")");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user