Made Symbol always stack, not heap, allocated. Finally fixed bugs with ASTTransformation.

This commit is contained in:
Nathan Braswell
2013-10-02 03:15:20 -04:00
parent 0110672f50
commit b9ffe33d0b
25 changed files with 375 additions and 278 deletions

View File

@@ -4,7 +4,7 @@ project(Kraken)
set( MY_INCLUDES ${PROJECT_SOURCE_DIR}/include) set( MY_INCLUDES ${PROJECT_SOURCE_DIR}/include)
set( MY_SOURCES main.cpp src/Parser.cpp src/LALRParser.cpp src/GraphStructuredStack.cpp src/RNGLRParser.cpp src/ParseAction.cpp src/ParseRule.cpp src/Symbol.cpp src/StringReader.cpp src/State.cpp src/util.cpp src/Lexer.cpp src/RegEx.cpp src/RegExState.cpp src/Table.cpp ) set( MY_SOURCES main.cpp src/Parser.cpp src/LALRParser.cpp src/GraphStructuredStack.cpp src/RNGLRParser.cpp src/ParseAction.cpp src/ParseRule.cpp src/Symbol.cpp src/StringReader.cpp src/State.cpp src/util.cpp src/Lexer.cpp src/RegEx.cpp src/RegExState.cpp src/Table.cpp src/ASTData.cpp src/ASTTransformation.cpp )
include_directories( ${MY_INCLUDES} ) include_directories( ${MY_INCLUDES} )

View File

@@ -1,27 +1,30 @@
#ifndef ASTDATA_H #ifndef ASTDATA_H
#define ASTDATA_H #define ASTDATA_H
#include <vector>
#include "Symbol.h"
#ifndef NULL #ifndef NULL
#define NULL 0 #define NULL 0
#endif #endif
#include "Symbol.h" enum ASTType {translation_unit, interpreter_directive, identifier,
import, function, code_block,
typed_parameter, expression, boolean_expression, statement,
if_statement, return_statement, assignment_statement, function_call,
value};
enum ValueType {none, boolean, integer, floating, double_percision, char_string };
#include <vector>
class ASTData { class ASTData {
public: public:
enum ASTType {translation_unit, interpreter_directive, identifier,
import, interpreter_directive, function, code_block,
typed_parameter, expression, boolean_expression, statement,
if_statement, return_statement, assignment_statement, function_call,
value};
enum ValueType {none, boolean, integer, floating, double_percision, char_string }
ASTData(ASTType type, ValueType valueType = none); ASTData(ASTType type, ValueType valueType = none);
ASTData(ASTType type, Symbol* symbol, ValueType valueType = none); ASTData(ASTType type, Symbol symbol, ValueType valueType = none);
~ASTData();
std::string toString();
ASTType type; ASTType type;
Symbol* symbol; ValueType valueType;
Symbol symbol;
private: private:
}; };

View File

@@ -1,16 +1,16 @@
#ifndef ASTTRANSFORMATION_H #ifndef ASTTRANSFORMATION_H
#define ASTTRANSFORMATION_H #define ASTTRANSFORMATION_H
#include "ASTData.h"
#include "NodeTransformation.h" #include "NodeTransformation.h"
class ASTTransformation: public Transformation<Symbol*,ASTData> { class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
public: public:
ASTTransformation(); ASTTransformation();
~ASTTransformation(); ~ASTTransformation();
virtual NodeTree<Symbol*>* transform(NodeTree<ASTData>* from); virtual NodeTree<ASTData>* transform(NodeTree<Symbol>* from);
private: private:
//Nothing //Nothing
}; };
#endif
#endif

View File

@@ -0,0 +1,53 @@
#ifndef COLLAPSETRANSFORMATION_H
#define COLLAPSETRANSFORMATION_H
#include <queue>
#include <vector>
#include "NodeTransformation.h"
template<class T>
class CollapseTransformation: public NodeTransformation<T,T> {
public:
CollapseTransformation(T toCollapse);
~CollapseTransformation();
virtual NodeTree<T>* transform(NodeTree<T>* from);
private:
T toCollapse;
};
#endif
template<class T>
CollapseTransformation<T>::CollapseTransformation(T toCollapse) {
this->toCollapse = toCollapse;
}
template<class T>
CollapseTransformation<T>::~CollapseTransformation() {
//
}
template<class T>
NodeTree<T>* CollapseTransformation<T>::transform(NodeTree<T>* from) {
std::queue<NodeTree<T>*> toProcess;
toProcess.push(from);
while(!toProcess.empty()) {
NodeTree<T>* node = toProcess.front();
toProcess.pop();
std::vector<NodeTree<T>*> children = node->getChildren();
for (int i = 0; i < children.size(); i++) {
if (children[i]->getData() == toCollapse) {
node->removeChild(children[i]);
std::vector<NodeTree<T>*> newChildren = children[i]->getChildren();
node->addChildren(newChildren);
for (int j = 0; j < newChildren.size(); j++)
toProcess.push(newChildren[j]);
}
else
toProcess.push(children[i]);
}
}
return from;
}

View File

@@ -23,13 +23,13 @@ class GraphStructuredStack {
std::vector<std::vector<NodeTree<int>*> >* getReachablePaths(NodeTree<int>* start, int lenght); std::vector<std::vector<NodeTree<int>*> >* getReachablePaths(NodeTree<int>* start, int lenght);
void recursivePathFind(NodeTree<int>* start, int length, std::vector<NodeTree<int>*> currentPath, std::vector<std::vector<NodeTree<int>*> >* paths); void recursivePathFind(NodeTree<int>* start, int length, std::vector<NodeTree<int>*> currentPath, std::vector<std::vector<NodeTree<int>*> >* paths);
bool hasEdge(NodeTree<int>* start, NodeTree<int>* end); bool hasEdge(NodeTree<int>* start, NodeTree<int>* end);
NodeTree<Symbol*>* getEdge(NodeTree<int>* start, NodeTree<int>* end); NodeTree<Symbol>* getEdge(NodeTree<int>* start, NodeTree<int>* end);
void addEdge(NodeTree<int>* start, NodeTree<int>* end, NodeTree<Symbol*>* edge); void addEdge(NodeTree<int>* start, NodeTree<int>* end, NodeTree<Symbol>* edge);
std::string toString(); std::string toString();
private: private:
std::vector<std::vector<NodeTree<int>*>*> gss; std::vector<std::vector<NodeTree<int>*>*> gss;
std::map< std::pair< NodeTree<int>*, NodeTree<int>* >, NodeTree<Symbol*>* > edges; std::map< std::pair< NodeTree<int>*, NodeTree<int>* >, NodeTree<Symbol>* > edges;
}; };
#endif #endif

View File

@@ -12,7 +12,7 @@ class LALRParser: public Parser {
//Defaults in parser are mostly LALR, so we only need to //Defaults in parser are mostly LALR, so we only need to
//implement the actual parsing function //implement the actual parsing function
NodeTree<Symbol*>* parseInput(std::string inputString); NodeTree<Symbol>* parseInput(std::string inputString);
private: private:
//Nothing //Nothing

View File

@@ -15,7 +15,7 @@ class Lexer {
~Lexer(); ~Lexer();
void addRegEx(std::string regExString); void addRegEx(std::string regExString);
void setInput(std::string inputString); void setInput(std::string inputString);
Symbol* next(); Symbol next();
private: private:
std::vector<RegEx*> regExs; std::vector<RegEx*> regExs;
std::string input; std::string input;

View File

@@ -28,6 +28,7 @@ class NodeTree {
void addChild(NodeTree<T>* child); void addChild(NodeTree<T>* child);
void addChildren(std::vector<NodeTree<T>*>* children); void addChildren(std::vector<NodeTree<T>*>* children);
void addChildren(std::vector<NodeTree<T>*> children);
int findChild(NodeTree<T>* child); int findChild(NodeTree<T>* child);
void removeChild(NodeTree<T>* child); void removeChild(NodeTree<T>* child);
void removeChild(int index); void removeChild(int index);
@@ -63,8 +64,6 @@ int NodeTree<T>::idCounter;
template<class T> template<class T>
NodeTree<T>::NodeTree() { NodeTree<T>::NodeTree() {
name = "UnnamedNode"; name = "UnnamedNode";
data = NULL;
id = idCounter++; id = idCounter++;
} }
@@ -93,6 +92,7 @@ const bool NodeTree<T>::operator==(NodeTree &other) {
return true; return true;
} }
//Used when making a map of NodeTrees
template<class T> template<class T>
const bool NodeTree<T>::operator<(const NodeTree &other) const { const bool NodeTree<T>::operator<(const NodeTree &other) const {
return data < other.getData(); return data < other.getData();
@@ -136,6 +136,12 @@ void NodeTree<T>::addChildren(std::vector<NodeTree<T>*>* children) {
addChild((*children)[i]); addChild((*children)[i]);
} }
template<class T>
void NodeTree<T>::addChildren(std::vector<NodeTree<T>*> children) {
for (typename std::vector<NodeTree<T>*>::size_type i = 0; i < children.size(); i++)
addChild(children[i]);
}
template<class T> template<class T>
int NodeTree<T>::findChild(NodeTree<T>* child) { int NodeTree<T>::findChild(NodeTree<T>* child) {
for (int i = 0; i < children.size(); i++) { for (int i = 0; i < children.size(); i++) {
@@ -231,10 +237,11 @@ std::string NodeTree<T>::DOTGraphStringHelper(std::vector<NodeTree<T>*> avoidLis
template<class T> template<class T>
std::string NodeTree<T>::getDOTName() { std::string NodeTree<T>::getDOTName() {
std::string DOTName = ""; std::string DOTName = "";
if (data != NULL) DOTName = "\"" + replaceExEscape(name + "-" + data.toString(), "\"", "\\\"") + "_" + intToString(id) + "\""; //Note that terminals already have a quote in the front of their name, so we don't need to add one
DOTName = "\"" + replaceExEscape(name + "-" + data->toString(), "\"", "\\\"") + "_" + intToString(id) + "\""; //Note that terminals already have a quote in the front of their name, so we don't need to add one // if (data != NULL)
else // DOTName = "\"" + replaceExEscape(name + "-" + data->toString(), "\"", "\\\"") + "_" + intToString(id) + "\""; //Note that terminals already have a quote in the front of their name, so we don't need to add one
DOTName = "\"" + replaceExEscape(name, "\"", " \\\"") + "_" + intToString(id) + "\""; // else
// DOTName = "\"" + replaceExEscape(name, "\"", " \\\"") + "_" + intToString(id) + "\"";
return(replaceExEscape(DOTName, "\n", "\\n")); return(replaceExEscape(DOTName, "\n", "\\n"));
} }

View File

@@ -14,7 +14,7 @@
class ParseRule { class ParseRule {
public: public:
ParseRule(); ParseRule();
ParseRule(Symbol* leftHandle, int pointerIndex, std::vector<Symbol*> &rightSide, std::vector<Symbol*>* lookahead); ParseRule(Symbol leftHandle, int pointerIndex, std::vector<Symbol> &rightSide, std::vector<Symbol>* lookahead);
~ParseRule(); ~ParseRule();
const bool equalsExceptLookahead(const ParseRule &other); const bool equalsExceptLookahead(const ParseRule &other);
bool const operator==(const ParseRule &other); bool const operator==(const ParseRule &other);
@@ -22,32 +22,32 @@ class ParseRule {
ParseRule* clone(); ParseRule* clone();
void setLeftHandle(Symbol* leftHandle); void setLeftHandle(Symbol leftHandle);
void appendToRight(Symbol* appendee); void appendToRight(Symbol appendee);
Symbol* getLeftSide(); Symbol getLeftSide();
void setRightSide(std::vector<Symbol*> rightSide); void setRightSide(std::vector<Symbol> rightSide);
std::vector<Symbol*> getRightSide(); std::vector<Symbol> getRightSide();
Symbol* getAtNextIndex(); Symbol getAtNextIndex();
Symbol* getAtIndex(); Symbol getAtIndex();
int getRightSize(); int getRightSize();
int getIndex(); int getIndex();
bool advancePointer(); bool advancePointer();
bool isAtEnd(); bool isAtEnd();
void setLookahead(std::vector<Symbol*>* lookahead); void setLookahead(std::vector<Symbol>* lookahead);
void addLookahead(std::vector<Symbol*>* lookahead); void addLookahead(std::vector<Symbol>* lookahead);
std::vector<Symbol*>* getLookahead(); std::vector<Symbol>* getLookahead();
std::string toString(); std::string toString();
std::string toDOT(); std::string toDOT();
private: private:
int pointerIndex; int pointerIndex;
Symbol* leftHandle; Symbol leftHandle;
std::vector<Symbol*>* lookahead; std::vector<Symbol>* lookahead;
std::vector<Symbol*> rightSide; std::vector<Symbol> rightSide;
}; };

View File

@@ -27,16 +27,16 @@ class Parser {
virtual void loadGrammer(std::string grammerInputString); virtual void loadGrammer(std::string grammerInputString);
virtual void createStateSet(); virtual void createStateSet();
virtual std::string stateSetToString(); virtual std::string stateSetToString();
virtual NodeTree<Symbol*>* parseInput(std::string inputString) = 0; virtual NodeTree<Symbol>* parseInput(std::string inputString) = 0;
virtual std::string grammerToString(); virtual std::string grammerToString();
virtual std::string grammerToDOT(); virtual std::string grammerToDOT();
std::string tableToString(); std::string tableToString();
protected: protected:
std::vector<Symbol*>* firstSet(Symbol* token); std::vector<Symbol>* firstSet(Symbol token);
std::vector<Symbol*>* firstSet(Symbol* token, std::vector<Symbol*> avoidList); std::vector<Symbol>* firstSet(Symbol token, std::vector<Symbol> avoidList);
std::vector<Symbol*>* incrementiveFollowSet(ParseRule* rule); std::vector<Symbol>* incrementiveFollowSet(ParseRule* rule);
virtual void closure(State* state); virtual void closure(State* state);
virtual void addStates(std::vector< State* >* stateSets, State* state, std::queue<State*>* toDo); virtual void addStates(std::vector< State* >* stateSets, State* state, std::queue<State*>* toDo);
int stateNum(State* state); int stateNum(State* state);
@@ -44,24 +44,24 @@ class Parser {
StringReader reader; StringReader reader;
Lexer lexer; Lexer lexer;
std::map<std::pair<std::string, bool>, Symbol*> symbols; std::map<std::pair<std::string, bool>, Symbol> symbols;
std::vector<ParseRule*> loadedGrammer; std::vector<ParseRule*> loadedGrammer;
std::vector< State* > stateSets; std::vector< State* > stateSets;
//The EOFSymbol, a pointer because of use in table, etc //The EOFSymbol, a pointer because of use in table, etc
Symbol* EOFSymbol; Symbol EOFSymbol;
//The nullSymbol, ditto with above. Also used in comparisons //The nullSymbol, ditto with above. Also used in comparisons
Symbol* nullSymbol; Symbol nullSymbol;
Table table; Table table;
std::stack<int> stateStack; std::stack<int> stateStack;
std::stack<Symbol*> symbolStack; std::stack<Symbol> symbolStack;
Symbol* getOrAddSymbol(std::string symbolString, bool isTerminal); Symbol getOrAddSymbol(std::string symbolString, bool isTerminal);
NodeTree<Symbol*>* reduceTreeCombine(Symbol* newSymbol, std::vector<Symbol*> &symbols); NodeTree<Symbol>* reduceTreeCombine(Symbol newSymbol, std::vector<Symbol> &symbols);
}; };
#endif #endif

View File

@@ -15,47 +15,47 @@ class RNGLRParser: public Parser {
public: public:
RNGLRParser(); RNGLRParser();
~RNGLRParser(); ~RNGLRParser();
NodeTree<Symbol*>* parseInput(std::string inputString); NodeTree<Symbol>* parseInput(std::string inputString);
private: private:
void reducer(int i); void reducer(int i);
void shifter(int i); void shifter(int i);
void addChildren(NodeTree<Symbol*>* parent, std::vector<NodeTree<Symbol*>*>* children, NodeTree<Symbol*>* nullableParts); void addChildren(NodeTree<Symbol>* parent, std::vector<NodeTree<Symbol>*>* children, NodeTree<Symbol>* nullableParts);
void addStates(std::vector< State* >* stateSets, State* state, std::queue<State*>* toDo); void addStates(std::vector< State* >* stateSets, State* state, std::queue<State*>* toDo);
void addStateReductionsToTable(State* state); void addStateReductionsToTable(State* state);
bool fullyReducesToNull(ParseRule* rule); bool fullyReducesToNull(ParseRule* rule);
bool reducesToNull(ParseRule* rule); bool reducesToNull(ParseRule* rule);
bool reducesToNull(ParseRule* rule, std::vector<Symbol*> avoidList); bool reducesToNull(ParseRule* rule, std::vector<Symbol> avoidList);
bool belongsToFamily(NodeTree<Symbol*>* node, std::vector<NodeTree<Symbol*>*>* nodes); bool belongsToFamily(NodeTree<Symbol>* node, std::vector<NodeTree<Symbol>*>* nodes);
bool arePacked(std::vector<NodeTree<Symbol*>*> nodes); bool arePacked(std::vector<NodeTree<Symbol>*> nodes);
bool isPacked(NodeTree<Symbol*>* node); bool isPacked(NodeTree<Symbol>* node);
void setPacked(NodeTree<Symbol*>* node, bool isPacked); void setPacked(NodeTree<Symbol>* node, bool isPacked);
NodeTree<Symbol*>* getNullableParts(ParseRule* rule); NodeTree<Symbol>* getNullableParts(ParseRule* rule);
NodeTree<Symbol*>* getNullableParts(ParseRule* rule, std::vector<NodeTree<Symbol*>*> avoidList); NodeTree<Symbol>* getNullableParts(ParseRule* rule, std::vector<NodeTree<Symbol>*> avoidList);
NodeTree<Symbol*>* getNullableParts(Symbol* symbol); NodeTree<Symbol>* getNullableParts(Symbol symbol);
std::vector<NodeTree<Symbol*>*> getPathEdges(std::vector<NodeTree<int>*> path); std::vector<NodeTree<Symbol>*> getPathEdges(std::vector<NodeTree<int>*> path);
std::vector<Symbol*> input; std::vector<Symbol> input;
GraphStructuredStack gss; GraphStructuredStack gss;
//start node, lefthand side of the reduction, reduction length //start node, lefthand side of the reduction, reduction length
struct Reduction { struct Reduction {
NodeTree<int>* from; NodeTree<int>* from;
Symbol* symbol; Symbol symbol;
int length; int length;
NodeTree<Symbol*>* nullableParts; NodeTree<Symbol>* nullableParts;
NodeTree<Symbol*>* label; NodeTree<Symbol>* label;
} ; } ;
std::queue<Reduction> toReduce; std::queue<Reduction> toReduce;
//Node coming from, state going to //Node coming from, state going to
std::queue< std::pair<NodeTree<int>*, int> > toShift; std::queue< std::pair<NodeTree<int>*, int> > toShift;
std::vector<std::pair<NodeTree<Symbol*>*, int> > SPPFStepNodes; std::vector<std::pair<NodeTree<Symbol>*, int> > SPPFStepNodes;
std::vector<NodeTree<Symbol*>*> nullableParts; std::vector<NodeTree<Symbol>*> nullableParts;
std::map<NodeTree<Symbol*>, bool> packedMap; std::map<NodeTree<Symbol>, bool> packedMap;
}; };
#endif #endif

View File

@@ -1,5 +1,5 @@
#ifndef ASTTRANSFORMATION_H #ifndef REMOVALTRANSFORMATION_H
#define ASTTRANSFORMATION_H #define REMOVALTRANSFORMATION_H
#include <queue> #include <queue>
#include <vector> #include <vector>
@@ -38,7 +38,7 @@ NodeTree<T>* RemovalTransformation<T>::transform(NodeTree<T>* from) {
toProcess.pop(); toProcess.pop();
std::vector<NodeTree<T>*> children = node->getChildren(); std::vector<NodeTree<T>*> children = node->getChildren();
for (int i = 0; i < children.size(); i++) { for (int i = 0; i < children.size(); i++) {
if (*(children[i]->getData()) == *toRemove) if (children[i]->getData() == toRemove)
node->removeChild(children[i]); node->removeChild(children[i]);
else else
toProcess.push(children[i]); toProcess.push(children[i]);

View File

@@ -10,28 +10,28 @@
#include <vector> #include <vector>
#include <string> #include <string>
//Circular references
//class NodeTree;
class Symbol { class Symbol {
public: public:
Symbol();
Symbol(std::string name, bool isTerminal); Symbol(std::string name, bool isTerminal);
Symbol(std::string name, bool isTerminal, std::string value); Symbol(std::string name, bool isTerminal, std::string value);
Symbol(std::string name, bool isTerminal, NodeTree<Symbol*>* tree); Symbol(std::string name, bool isTerminal, NodeTree<Symbol>* tree);
~Symbol(); ~Symbol();
bool const operator==(const Symbol &other); bool const operator==(const Symbol &other)const;
bool const operator!=(const Symbol &other); bool const operator!=(const Symbol &other)const;
std::string getName(); bool const operator<(const Symbol &other)const;
std::string toString();
Symbol* clone(); std::string getName() const;
void setSubTree(NodeTree<Symbol*>* tree); std::string toString() const;
NodeTree<Symbol*>* getSubTree(); Symbol clone();
void setSubTree(NodeTree<Symbol>* tree);
NodeTree<Symbol>* getSubTree();
bool isTerminal(); bool isTerminal();
private: private:
std::string name; std::string name;
std::string value; std::string value;
bool terminal; bool terminal;
NodeTree<Symbol*>* subTree; NodeTree<Symbol>* subTree;
}; };
#endif #endif

View File

@@ -11,19 +11,19 @@ class Table {
public: public:
Table(); Table();
~Table(); ~Table();
void setSymbols(Symbol* EOFSymbol, Symbol* nullSymbol); void setSymbols(Symbol EOFSymbol, Symbol nullSymbol);
void add(int stateNum, Symbol* tranSymbol, ParseAction* action); void add(int stateNum, Symbol tranSymbol, ParseAction* action);
void remove(int stateNum, Symbol* tranSymbol); void remove(int stateNum, Symbol tranSymbol);
std::vector<ParseAction*>* get(int state, Symbol* token); std::vector<ParseAction*>* get(int state, Symbol token);
ParseAction* getShift(int state, Symbol* token); ParseAction* getShift(int state, Symbol token);
std::string toString(); std::string toString();
private: private:
std::vector< std::vector< std::vector<ParseAction*>* >* > table; std::vector< std::vector< std::vector<ParseAction*>* >* > table;
std::vector<Symbol*> symbolIndexVec; std::vector<Symbol> symbolIndexVec;
//The EOFSymbol, a pointer because of use in table, etc //The EOFSymbol, a pointer because of use in table, etc
Symbol* EOFSymbol; Symbol EOFSymbol;
//The nullSymbol, ditto with above. Also used in comparisons //The nullSymbol, ditto with above. Also used in comparisons
Symbol* nullSymbol; Symbol nullSymbol;
}; };
#endif #endif

View File

@@ -1,6 +1,7 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <vector>
#include "NodeTree.h" #include "NodeTree.h"
#include "Symbol.h" #include "Symbol.h"
@@ -10,12 +11,15 @@
#include "NodeTransformation.h" #include "NodeTransformation.h"
#include "RemovalTransformation.h" #include "RemovalTransformation.h"
#include "CollapseTransformation.h"
#include "ASTTransformation.h"
#include "ASTData.h"
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
std::ifstream programInFile, grammerInFile; std::ifstream programInFile, grammerInFile;
std::ofstream outFile, outFileTransformed; std::ofstream outFile, outFileTransformed, outFileAST;
programInFile.open(argv[1]); programInFile.open(argv[1]);
if (!programInFile.is_open()) { if (!programInFile.is_open()) {
@@ -41,6 +45,12 @@ int main(int argc, char* argv[]) {
return(1); return(1);
} }
outFileAST.open((std::string(argv[3]) + ".AST.dot").c_str());
if (!outFileAST.is_open()) {
std::cout << "Probelm opening second output file " << std::string(argv[3]) + ".AST.dot" << "\n";
return(1);
}
//Read the input file into a string //Read the input file into a string
std::string programInputFileString, grammerInputFileString; std::string programInputFileString, grammerInputFileString;
std::string line; std::string line;
@@ -77,7 +87,7 @@ int main(int argc, char* argv[]) {
std::cout << "\nParsing" << std::endl; std::cout << "\nParsing" << std::endl;
std::cout << programInputFileString << std::endl; std::cout << programInputFileString << std::endl;
NodeTree<Symbol*>* parseTree = parser.parseInput(programInputFileString); NodeTree<Symbol>* parseTree = parser.parseInput(programInputFileString);
if (parseTree) { if (parseTree) {
//std::cout << parseTree->DOTGraphString() << std::endl; //std::cout << parseTree->DOTGraphString() << std::endl;
@@ -86,21 +96,46 @@ int main(int argc, char* argv[]) {
std::cout << "ParseTree returned from parser is NULL!" << std::endl; std::cout << "ParseTree returned from parser is NULL!" << std::endl;
} }
NodeTransformation<Symbol*, Symbol*>* removeWS = new RemovalTransformation<Symbol*>(new Symbol("WS", false)); //Pre AST Transformations
NodeTree<Symbol*>* noWhiteSpace = removeWS->transform(parseTree); std::vector<NodeTransformation<Symbol, Symbol>*> preASTTransforms;
delete removeWS; //Remove Transformations
preASTTransforms.push_back(new RemovalTransformation<Symbol>(Symbol("WS", false)));
preASTTransforms.push_back(new RemovalTransformation<Symbol>(Symbol("\\(", true)));
preASTTransforms.push_back(new RemovalTransformation<Symbol>(Symbol("\\)", true)));
//preASTTransforms.push_back(new RemovalTransformation<Symbol>(Symbol("/", true)));
preASTTransforms.push_back(new RemovalTransformation<Symbol>(Symbol("::", true)));
preASTTransforms.push_back(new RemovalTransformation<Symbol>(Symbol(";", true)));
preASTTransforms.push_back(new RemovalTransformation<Symbol>(Symbol("{", true)));
preASTTransforms.push_back(new RemovalTransformation<Symbol>(Symbol("}", true)));
//Collapse Transformations
preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("opt_typed_parameter_list", false)));
preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("opt_parameter_list", false)));
for (int i = 0; i < preASTTransforms.size(); i++) {
parseTree = preASTTransforms[i]->transform(parseTree);
}
preASTTransforms.erase(preASTTransforms.begin(), preASTTransforms.end());
if (noWhiteSpace) { NodeTree<ASTData>* AST = ASTTransformation().transform(parseTree);
outFileTransformed << noWhiteSpace->DOTGraphString() << std::endl; //NodeTree<ASTData>* AST = (new ASTTransformation())->transform(parseTree);
if (parseTree) {
outFileTransformed << parseTree->DOTGraphString() << std::endl;
} else { } else {
std::cout << "Tree returned from transformation is NULL!" << std::endl; std::cout << "Tree returned from transformation is NULL!" << std::endl;
} }
if (AST) {
outFileTransformed << AST->DOTGraphString() << std::endl;
} else {
std::cout << "Tree returned from ASTTransformation is NULL!" << std::endl;
}
programInFile.close(); programInFile.close();
grammerInFile.close(); grammerInFile.close();
outFile.close(); outFile.close();
outFileTransformed.close(); outFileTransformed.close();
outFileAST.close();
return(0); return(0);
} }

View File

@@ -3,10 +3,9 @@
ASTData::ASTData(ASTType type, ValueType valueType) { ASTData::ASTData(ASTType type, ValueType valueType) {
this->type = type; this->type = type;
this->valueType = valueType; this->valueType = valueType;
this->symbol = NULL;
} }
ASTData::ASTData(ASTType type, Symbol* symbol, ValueType valueType) { ASTData::ASTData(ASTType type, Symbol symbol, ValueType valueType) {
this->type = type; this->type = type;
this->valueType = valueType; this->valueType = valueType;
this->symbol = symbol; this->symbol = symbol;
@@ -15,3 +14,7 @@ ASTData::ASTData(ASTType type, Symbol* symbol, ValueType valueType) {
ASTData::~ASTData() { ASTData::~ASTData() {
} }
std::string ASTData::toString() {
return "ASTData!";
}

View File

@@ -8,6 +8,6 @@ ASTTransformation::~ASTTransformation() {
// //
} }
virtual NodeTree<Symbol*>* ASTTransformation::transform(NodeTree<ASTData>* from) { NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
return NULL; return NULL;
} }

View File

@@ -107,11 +107,11 @@ bool GraphStructuredStack::hasEdge(NodeTree<int>* start, NodeTree<int>* end) {
return start->findChild(end) != -1; return start->findChild(end) != -1;
} }
NodeTree<Symbol*>* GraphStructuredStack::getEdge(NodeTree<int>* start, NodeTree<int>* end) { NodeTree<Symbol>* GraphStructuredStack::getEdge(NodeTree<int>* start, NodeTree<int>* end) {
return edges[std::make_pair(start, end)]; return edges[std::make_pair(start, end)];
} }
void GraphStructuredStack::addEdge(NodeTree<int>* start, NodeTree<int>* end, NodeTree<Symbol*>* edge) { void GraphStructuredStack::addEdge(NodeTree<int>* start, NodeTree<int>* end, NodeTree<Symbol>* edge) {
start->addChild(end); start->addChild(end);
end->addParent(start); end->addParent(start);
edges[std::make_pair(start, end)] = edge; edges[std::make_pair(start, end)] = edge;

View File

@@ -7,14 +7,14 @@ LALRParser::~LALRParser() {
//Nothing to do in this version //Nothing to do in this version
} }
NodeTree<Symbol*>* LALRParser::parseInput(std::string inputString) { NodeTree<Symbol>* LALRParser::parseInput(std::string inputString) {
lexer.setInput(inputString); lexer.setInput(inputString);
Symbol* token = lexer.next(); Symbol token = lexer.next();
std::vector<ParseAction*>* actionList; std::vector<ParseAction*>* actionList;
ParseAction* action; ParseAction* action;
stateStack.push(0); stateStack.push(0);
symbolStack.push(new Symbol("INVALID", false)); symbolStack.push(Symbol("INVALID", false));
while (true) { while (true) {
std::cout << "In state: " << intToString(stateStack.top()) << std::endl; std::cout << "In state: " << intToString(stateStack.top()) << std::endl;
@@ -28,18 +28,18 @@ NodeTree<Symbol*>* LALRParser::parseInput(std::string inputString) {
int rightSideLength = action->reduceRule->getRightSide().size(); int rightSideLength = action->reduceRule->getRightSide().size();
//Keep track of symbols popped for parse tree //Keep track of symbols popped for parse tree
std::vector<Symbol*> poppedSymbols; std::vector<Symbol> poppedSymbols;
for (int i = 0; i < rightSideLength; i++) { for (int i = 0; i < rightSideLength; i++) {
poppedSymbols.push_back(symbolStack.top()); poppedSymbols.push_back(symbolStack.top());
stateStack.pop(); stateStack.pop();
symbolStack.pop(); symbolStack.pop();
} }
std::reverse(poppedSymbols.begin(), poppedSymbols.end()); //To put in order std::reverse(poppedSymbols.begin(), poppedSymbols.end()); //To put in order
//Assign the new tree to the new Symbol //Assign the new tree to the Symbol
Symbol* newSymbol = action->reduceRule->getLeftSide()->clone(); Symbol newSymbol = action->reduceRule->getLeftSide();
newSymbol->setSubTree(reduceTreeCombine(newSymbol, poppedSymbols)); newSymbol.setSubTree(reduceTreeCombine(newSymbol, poppedSymbols));
symbolStack.push(newSymbol); symbolStack.push(newSymbol);
std::cout << "top of state is " << intToString(stateStack.top()) << " symbolStack top is " << symbolStack.top()->toString() << std::endl; std::cout << "top of state is " << intToString(stateStack.top()) << " symbolStack top is " << symbolStack.top().toString() << std::endl;
actionList = table.get(stateStack.top(), symbolStack.top()); actionList = table.get(stateStack.top(), symbolStack.top());
action = (*(actionList))[actionList->size()-1]; action = (*(actionList))[actionList->size()-1];
@@ -50,7 +50,7 @@ NodeTree<Symbol*>* LALRParser::parseInput(std::string inputString) {
break; break;
} }
case ParseAction::SHIFT: case ParseAction::SHIFT:
std::cout << "Shift " << token->toString() << std::endl; std::cout << "Shift " << token.toString() << std::endl;
symbolStack.push(token); symbolStack.push(token);
token = lexer.next(); token = lexer.next();
@@ -58,11 +58,11 @@ NodeTree<Symbol*>* LALRParser::parseInput(std::string inputString) {
break; break;
case ParseAction::ACCEPT: case ParseAction::ACCEPT:
std::cout << "ACCEPTED!" << std::endl; std::cout << "ACCEPTED!" << std::endl;
return(symbolStack.top()->getSubTree()); return(symbolStack.top().getSubTree());
break; break;
case ParseAction::REJECT: case ParseAction::REJECT:
std::cout << "REJECTED!" << std::endl; std::cout << "REJECTED!" << std::endl;
std::cout << "REJECTED Symbol was " << token->toString() << std::endl; std::cout << "REJECTED Symbol was " << token.toString() << std::endl;
return(NULL); return(NULL);
break; break;
default: default:

View File

@@ -22,11 +22,11 @@ void Lexer::addRegEx(std::string regExString) {
regExs.push_back(new RegEx(regExString)); regExs.push_back(new RegEx(regExString));
} }
Symbol* Lexer::next() { Symbol Lexer::next() {
//std::cout << "Current at is \"" << input.substr(currentPosition,input.length()-1) << "\" currentPos is " << currentPosition << " out of " << input.length() <<std::endl; //std::cout << "Current at is \"" << input.substr(currentPosition,input.length()-1) << "\" currentPos is " << currentPosition << " out of " << input.length() <<std::endl;
//If we're at the end, return an eof //If we're at the end, return an eof
if (currentPosition >= input.length()-1) if (currentPosition >= input.length()-1)
return new Symbol("$EOF$", true); return Symbol("$EOF$", true);
int longestMatch = -1; int longestMatch = -1;
RegEx* longestRegEx = NULL; RegEx* longestRegEx = NULL;
std::string remainingString = input.substr(currentPosition,input.length()-1); std::string remainingString = input.substr(currentPosition,input.length()-1);
@@ -42,10 +42,10 @@ Symbol* Lexer::next() {
std::string eatenString = input.substr(currentPosition, longestMatch+1); std::string eatenString = input.substr(currentPosition, longestMatch+1);
currentPosition += longestMatch + 1; currentPosition += longestMatch + 1;
//std::cout << "Current at is \"" << input.substr(currentPosition,input.length()-1) << "\" currentPos is " << currentPosition <<std::endl; //std::cout << "Current at is \"" << input.substr(currentPosition,input.length()-1) << "\" currentPos is " << currentPosition <<std::endl;
return new Symbol(longestRegEx->getPattern(), true, eatenString); return Symbol(longestRegEx->getPattern(), true, eatenString);
} else { } else {
//std::cout << "Found no applicable regex" << std::endl; //std::cout << "Found no applicable regex" << std::endl;
//std::cout << "Remaining is ||" << input.substr(currentPosition,input.length()-1) << "||" << std::endl; //std::cout << "Remaining is ||" << input.substr(currentPosition,input.length()-1) << "||" << std::endl;
return NULL; return Symbol();
} }
} }

View File

@@ -2,11 +2,10 @@
ParseRule::ParseRule() { ParseRule::ParseRule() {
pointerIndex = 0; pointerIndex = 0;
leftHandle = NULL;
lookahead = NULL; lookahead = NULL;
} }
ParseRule::ParseRule(Symbol* leftHandle, int pointerIndex, std::vector<Symbol*> &rightSide, std::vector<Symbol*>* lookahead) { ParseRule::ParseRule(Symbol leftHandle, int pointerIndex, std::vector<Symbol> &rightSide, std::vector<Symbol>* lookahead) {
this->leftHandle = leftHandle; this->leftHandle = leftHandle;
this->pointerIndex = pointerIndex; this->pointerIndex = pointerIndex;
this->rightSide = rightSide; this->rightSide = rightSide;
@@ -33,35 +32,35 @@ ParseRule* ParseRule::clone() {
return( new ParseRule(leftHandle, pointerIndex, rightSide, lookahead) ); return( new ParseRule(leftHandle, pointerIndex, rightSide, lookahead) );
} }
void ParseRule::setLeftHandle(Symbol* leftHandle) { void ParseRule::setLeftHandle(Symbol leftHandle) {
this->leftHandle = leftHandle; this->leftHandle = leftHandle;
} }
void ParseRule::appendToRight(Symbol* appendee) { void ParseRule::appendToRight(Symbol appendee) {
rightSide.push_back(appendee); rightSide.push_back(appendee);
} }
Symbol* ParseRule::getLeftSide() { Symbol ParseRule::getLeftSide() {
return leftHandle; return leftHandle;
} }
void ParseRule::setRightSide(std::vector<Symbol*> rightSide) { void ParseRule::setRightSide(std::vector<Symbol> rightSide) {
this->rightSide = rightSide; this->rightSide = rightSide;
} }
std::vector<Symbol*> ParseRule::getRightSide() { std::vector<Symbol> ParseRule::getRightSide() {
return rightSide; return rightSide;
} }
Symbol* ParseRule::getAtNextIndex() { Symbol ParseRule::getAtNextIndex() {
if (pointerIndex >= rightSide.size()) if (pointerIndex >= rightSide.size())
return NULL; return Symbol();
return rightSide[pointerIndex]; return rightSide[pointerIndex];
} }
Symbol* ParseRule::getAtIndex() { Symbol ParseRule::getAtIndex() {
if (pointerIndex < 1) if (pointerIndex < 1)
return NULL; return Symbol();
return rightSide[pointerIndex-1]; return rightSide[pointerIndex-1];
} }
@@ -85,15 +84,15 @@ bool ParseRule::isAtEnd() {
return pointerIndex == rightSide.size(); return pointerIndex == rightSide.size();
} }
void ParseRule::setLookahead(std::vector<Symbol*>* lookahead) { void ParseRule::setLookahead(std::vector<Symbol>* lookahead) {
this->lookahead = lookahead; this->lookahead = lookahead;
} }
void ParseRule::addLookahead(std::vector<Symbol*>* lookahead) { void ParseRule::addLookahead(std::vector<Symbol>* lookahead) {
for (std::vector<Symbol*>::size_type i = 0; i < lookahead->size(); i++) { for (std::vector<Symbol>::size_type i = 0; i < lookahead->size(); i++) {
bool alreadyIn = false; bool alreadyIn = false;
for (std::vector<Symbol*>::size_type j = 0; j < this->lookahead->size(); j++) { for (std::vector<Symbol>::size_type j = 0; j < this->lookahead->size(); j++) {
if (*((*lookahead)[i]) == *((*(this->lookahead))[j])) { if ((*lookahead)[i] == (*(this->lookahead))[j]) {
alreadyIn = true; alreadyIn = true;
break; break;
} }
@@ -103,23 +102,23 @@ void ParseRule::addLookahead(std::vector<Symbol*>* lookahead) {
} }
} }
std::vector<Symbol*>* ParseRule::getLookahead() { std::vector<Symbol>* ParseRule::getLookahead() {
return lookahead; return lookahead;
} }
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++) {
if (i == pointerIndex) if (i == pointerIndex)
concat += "(*) "; concat += "(*) ";
concat += rightSide[i]->toString() + " "; concat += rightSide[i].toString() + " ";
} }
if (pointerIndex >= rightSide.size()) if (pointerIndex >= rightSide.size())
concat += "(*)"; concat += "(*)";
if (lookahead != NULL) { if (lookahead != NULL) {
concat += "**"; concat += "**";
for (std::vector<Symbol*>::size_type i = 0; i < lookahead->size(); i++) for (std::vector<Symbol>::size_type i = 0; i < lookahead->size(); i++)
concat += (*lookahead)[i]->toString(); concat += (*lookahead)[i].toString();
concat += "**"; concat += "**";
} }
return(concat); return(concat);
@@ -128,7 +127,7 @@ std::string ParseRule::toString() {
std::string ParseRule::toDOT() { std::string ParseRule::toDOT() {
std::string concat = ""; std::string concat = "";
for (int i = 0; i < rightSide.size(); i++) { for (int i = 0; i < rightSide.size(); i++) {
concat += leftHandle->toString() + " -> " + rightSide[i]->toString() + ";\n"; concat += leftHandle.toString() + " -> " + rightSide[i].toString() + ";\n";
} }
return(concat); return(concat);
} }

View File

@@ -1,21 +1,17 @@
#include "Parser.h" #include "Parser.h"
Parser::Parser() { Parser::Parser() : EOFSymbol("$EOF$", true), nullSymbol("$NULL$", true){
EOFSymbol = new Symbol("$EOF$", true);
nullSymbol = new Symbol("$NULL$", true);
table.setSymbols(EOFSymbol, nullSymbol); table.setSymbols(EOFSymbol, nullSymbol);
} }
Parser::~Parser() { Parser::~Parser() {
delete EOFSymbol;
delete nullSymbol;
} }
Symbol* Parser::getOrAddSymbol(std::string symbolString, bool isTerminal) { Symbol Parser::getOrAddSymbol(std::string symbolString, bool isTerminal) {
Symbol* symbol; Symbol symbol;
std::pair<std::string, bool> entry = std::make_pair(symbolString, isTerminal); std::pair<std::string, bool> entry = std::make_pair(symbolString, isTerminal);
if (symbols.find(entry) == symbols.end()) { if (symbols.find(entry) == symbols.end()) {
symbol = new Symbol(symbolString, isTerminal); symbol = Symbol(symbolString, isTerminal);
symbols[entry] = symbol; symbols[entry] = symbol;
} else { } else {
symbol = symbols[entry]; symbol = symbols[entry];
@@ -31,10 +27,10 @@ void Parser::loadGrammer(std::string grammerInputString) {
while(currToken != "") { while(currToken != "") {
//Load the left of the rule //Load the left of the rule
ParseRule* currentRule = new ParseRule(); ParseRule* currentRule = new ParseRule();
Symbol* leftSide = getOrAddSymbol(currToken, false); //Left handle is never a terminal Symbol leftSide = getOrAddSymbol(currToken, false); //Left handle is never a terminal
currentRule->setLeftHandle(leftSide); currentRule->setLeftHandle(leftSide);
reader.word(); //Remove the = reader.word(); //Remove the =
//Add the right side, adding new Symbols to symbol map. //Add the right side, adding Symbols to symbol map.
currToken = reader.word(); currToken = reader.word();
while (currToken != ";") { while (currToken != ";") {
@@ -84,7 +80,7 @@ void Parser::createStateSet() {
//Set the first state's basis to be the goal rule with lookahead EOF //Set the first state's basis to be the goal rule with lookahead EOF
ParseRule* goalRule = loadedGrammer[0]->clone(); ParseRule* goalRule = loadedGrammer[0]->clone();
std::vector<Symbol*>* goalRuleLookahead = new std::vector<Symbol*>(); std::vector<Symbol>* goalRuleLookahead = new std::vector<Symbol>();
goalRuleLookahead->push_back(EOFSymbol); goalRuleLookahead->push_back(EOFSymbol);
goalRule->setLookahead(goalRuleLookahead); goalRule->setLookahead(goalRuleLookahead);
State* zeroState = new State(0, goalRule); State* zeroState = new State(0, goalRule);
@@ -111,38 +107,38 @@ int Parser::stateNum(State* state) {
return -1; return -1;
} }
std::vector<Symbol*>* Parser::firstSet(Symbol* token) { std::vector<Symbol>* Parser::firstSet(Symbol token) {
std::vector<Symbol*> avoidList; std::vector<Symbol> avoidList;
return firstSet(token, avoidList); return firstSet(token, avoidList);
} }
std::vector<Symbol*>* Parser::firstSet(Symbol* token, std::vector<Symbol*> avoidList) { std::vector<Symbol>* Parser::firstSet(Symbol token, std::vector<Symbol> avoidList) {
//If we've already done this token, don't do it again //If we've already done this token, don't do it again
for (std::vector<Symbol*>::size_type i = 0; i < avoidList.size(); i++) for (std::vector<Symbol>::size_type i = 0; i < avoidList.size(); i++)
if (*(avoidList[i]) == *token) { if (avoidList[i] == token) {
return new std::vector<Symbol*>(); return new std::vector<Symbol>();
} }
avoidList.push_back(token); avoidList.push_back(token);
std::vector<Symbol*>* first = new std::vector<Symbol*>(); std::vector<Symbol>* first = new std::vector<Symbol>();
//First, if the symbol is a terminal, than it's first set is just itself. //First, if the symbol is a terminal, than it's first set is just itself.
if (token->isTerminal()) { if (token.isTerminal()) {
first->push_back(token); first->push_back(token);
return(first); return(first);
} }
//Otherwise.... //Otherwise....
//Ok, to make a first set, go through the grammer, if the token it's left side, add it's production's first token's first set. //Ok, to make a first set, go through the grammer, if the token it's left side, add it's production's first token's first set.
//If that one includes mull, do the next one too (if it exists). //If that one includes mull, do the next one too (if it exists).
Symbol* rightToken = NULL; Symbol rightToken;
std::vector<Symbol*>* recursiveFirstSet = NULL; std::vector<Symbol>* recursiveFirstSet = NULL;
for (std::vector<ParseRule*>::size_type i = 0; i < loadedGrammer.size(); i++) { for (std::vector<ParseRule*>::size_type i = 0; i < loadedGrammer.size(); i++) {
if (*token == *(loadedGrammer[i]->getLeftSide())) { if (token == loadedGrammer[i]->getLeftSide()) {
//Loop through the rule adding first sets for each token if the previous token contained NULL //Loop through the rule adding first sets for each token if the previous token contained NULL
bool recFirstSetHasNull = false; bool recFirstSetHasNull = false;
int j = 0; int j = 0;
do { do {
rightToken = loadedGrammer[i]->getRightSide()[j]; //Get token of the right side of this rule rightToken = loadedGrammer[i]->getRightSide()[j]; //Get token of the right side of this rule
if (rightToken->isTerminal()) { if (rightToken.isTerminal()) {
recursiveFirstSet = new std::vector<Symbol*>(); recursiveFirstSet = new std::vector<Symbol>();
recursiveFirstSet->push_back(rightToken); recursiveFirstSet->push_back(rightToken);
} else { } else {
//Add the entire set //Add the entire set
@@ -151,8 +147,8 @@ std::vector<Symbol*>* Parser::firstSet(Symbol* token, std::vector<Symbol*> avoid
first->insert(first->end(), recursiveFirstSet->begin(), recursiveFirstSet->end()); first->insert(first->end(), recursiveFirstSet->begin(), recursiveFirstSet->end());
//Check to see if the current recursiveFirstSet contains NULL, if so, then go through again with the next token. (if there is one) //Check to see if the current recursiveFirstSet contains NULL, if so, then go through again with the next token. (if there is one)
recFirstSetHasNull = false; recFirstSetHasNull = false;
for (std::vector<Symbol*>::size_type k = 0; k < recursiveFirstSet->size(); k++) { for (std::vector<Symbol>::size_type k = 0; k < recursiveFirstSet->size(); k++) {
if ((*(*recursiveFirstSet)[k]) == *nullSymbol) { if ((*recursiveFirstSet)[k] == nullSymbol) {
recFirstSetHasNull = true; recFirstSetHasNull = true;
} }
} }
@@ -165,20 +161,20 @@ std::vector<Symbol*>* Parser::firstSet(Symbol* token, std::vector<Symbol*> avoid
} }
//Return the correct lookahead. This followSet is built based on the current rule's lookahead if at end, or the next Symbol's first set. //Return the correct lookahead. This followSet is built based on the current rule's lookahead if at end, or the next Symbol's first set.
std::vector<Symbol*>* Parser::incrementiveFollowSet(ParseRule* rule) { std::vector<Symbol>* Parser::incrementiveFollowSet(ParseRule* rule) {
//Advance the pointer past the current Symbol (the one we want the followset for) to the next symbol (which might be in our follow set, or might be the end) //Advance the pointer past the current Symbol (the one we want the followset for) to the next symbol (which might be in our follow set, or might be the end)
rule = rule->clone(); rule = rule->clone();
rule->advancePointer(); rule->advancePointer();
//Get the first set of the next Symbol. If it contains nullSymbol, keep doing for the next one //Get the first set of the next Symbol. If it contains nullSymbol, keep doing for the next one
std::vector<Symbol*>* followSet = new std::vector<Symbol*>(); std::vector<Symbol>* followSet = new std::vector<Symbol>();
std::vector<Symbol*>* symbolFirstSet; std::vector<Symbol>* symbolFirstSet;
bool symbolFirstSetHasNull = true; bool symbolFirstSetHasNull = true;
while (symbolFirstSetHasNull && !rule->isAtEnd()) { while (symbolFirstSetHasNull && !rule->isAtEnd()) {
symbolFirstSetHasNull = false; symbolFirstSetHasNull = false;
symbolFirstSet = firstSet(rule->getAtNextIndex()); symbolFirstSet = firstSet(rule->getAtNextIndex());
for (std::vector<Symbol*>::size_type i = 0; i < symbolFirstSet->size(); i++) { for (std::vector<Symbol>::size_type i = 0; i < symbolFirstSet->size(); i++) {
if (*((*symbolFirstSet)[i]) == *nullSymbol) { if ((*symbolFirstSet)[i] == nullSymbol) {
symbolFirstSetHasNull = true; symbolFirstSetHasNull = true;
symbolFirstSet->erase(symbolFirstSet->begin()+i); symbolFirstSet->erase(symbolFirstSet->begin()+i);
break; break;
@@ -192,11 +188,11 @@ std::vector<Symbol*>* Parser::incrementiveFollowSet(ParseRule* rule) {
symbolFirstSet = rule->getLookahead(); symbolFirstSet = rule->getLookahead();
followSet->insert(followSet->end(), symbolFirstSet->begin(), symbolFirstSet->end()); followSet->insert(followSet->end(), symbolFirstSet->begin(), symbolFirstSet->end());
} }
std::vector<Symbol*>* followSetReturn = new std::vector<Symbol*>(); std::vector<Symbol>* followSetReturn = new std::vector<Symbol>();
for (std::vector<Symbol*>::size_type i = 0; i < followSet->size(); i++) { for (std::vector<Symbol>::size_type i = 0; i < followSet->size(); i++) {
bool alreadyIn = false; bool alreadyIn = false;
for (std::vector<Symbol*>::size_type j = 0; j < followSetReturn->size(); j++) for (std::vector<Symbol>::size_type j = 0; j < followSetReturn->size(); j++)
if (*((*followSet)[i]) == *((*followSetReturn)[j])) { if ((*followSet)[i] == (*followSetReturn)[j]) {
alreadyIn = true; alreadyIn = true;
break; break;
} }
@@ -216,7 +212,7 @@ void Parser::closure(State* state) {
for (std::vector<ParseRule*>::size_type j = 0; j < loadedGrammer.size(); j++) { for (std::vector<ParseRule*>::size_type j = 0; j < loadedGrammer.size(); j++) {
//If the current symbol in the rule is not null (rule completed) and it equals a grammer's left side //If the current symbol in the rule is not null (rule completed) and it equals a grammer's left side
ParseRule* currentGramRule = loadedGrammer[j]->clone(); ParseRule* currentGramRule = loadedGrammer[j]->clone();
if ( !currentStateRule->isAtEnd() && *(currentStateRule->getAtNextIndex()) == *(currentGramRule->getLeftSide())) { if ( !currentStateRule->isAtEnd() && currentStateRule->getAtNextIndex() == currentGramRule->getLeftSide()) {
//std::cout << (*stateTotal)[i]->getAtNextIndex()->toString() << " has an applicable production " << loadedGrammer[j]->toString() << std::endl; //std::cout << (*stateTotal)[i]->getAtNextIndex()->toString() << " has an applicable production " << loadedGrammer[j]->toString() << std::endl;
//Now, add the correct lookahead. This followSet is built based on the current rule's lookahead if at end, or the next Symbol's first set. //Now, add the correct lookahead. This followSet is built based on the current rule's lookahead if at end, or the next Symbol's first set.
//std::cout << "Setting lookahead for " << currentGramRule->toString() << " in state " << state->toString() << std::endl; //std::cout << "Setting lookahead for " << currentGramRule->toString() << " in state " << state->toString() << std::endl;
@@ -259,7 +255,7 @@ void Parser::addStates(std::vector< State* >* stateSets, State* state, std::queu
//If not, create it. //If not, create it.
bool symbolAlreadyInState = false; bool symbolAlreadyInState = false;
for (std::vector< State* >::size_type j = 0; j < newStates.size(); j++) { for (std::vector< State* >::size_type j = 0; j < newStates.size(); j++) {
if (*(newStates[j]->basis[0]->getAtIndex()) == *(advancedRule->getAtIndex())) { if (newStates[j]->basis[0]->getAtIndex() == advancedRule->getAtIndex()) {
symbolAlreadyInState = true; symbolAlreadyInState = true;
//So now check to see if this exact rule is in this state //So now check to see if this exact rule is in this state
if (!newStates[j]->containsRule(advancedRule)) if (!newStates[j]->containsRule(advancedRule))
@@ -276,21 +272,21 @@ void Parser::addStates(std::vector< State* >* stateSets, State* state, std::queu
//Also add any completed rules as reduces in the action table //Also add any completed rules as reduces in the action table
//See if reduce //See if reduce
//Also, this really only needs to be done for the state's basis, but we're already iterating through, so... //Also, this really only needs to be done for the state's basis, but we're already iterating through, so...
std::vector<Symbol*>* lookahead = (*currStateTotal)[i]->getLookahead(); std::vector<Symbol>* lookahead = (*currStateTotal)[i]->getLookahead();
if ((*currStateTotal)[i]->isAtEnd()) { if ((*currStateTotal)[i]->isAtEnd()) {
for (std::vector<Symbol*>::size_type j = 0; j < lookahead->size(); j++) for (std::vector<Symbol>::size_type j = 0; j < lookahead->size(); j++)
table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i])); table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i]));
} else if (*((*currStateTotal)[i]->getAtNextIndex()) == *nullSymbol) { } else if ((*currStateTotal)[i]->getAtNextIndex() == nullSymbol) {
//If is a rule that produces only NULL, add in the approprite reduction, but use a new rule with a right side of length 0. (so we don't pop off stack) //If is a rule that produces only NULL, add in the approprite reduction, but use a new rule with a right side of length 0. (so we don't pop off stack)
ParseRule* nullRule = (*currStateTotal)[i]->clone(); ParseRule* nullRule = (*currStateTotal)[i]->clone();
nullRule->setRightSide(* new std::vector<Symbol*>()); nullRule->setRightSide(* new std::vector<Symbol>());
for (std::vector<Symbol*>::size_type j = 0; j < lookahead->size(); j++) for (std::vector<Symbol>::size_type j = 0; j < lookahead->size(); j++)
table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, nullRule)); table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, nullRule));
} }
} }
//Put all our new states in the set of states only if they're not already there. //Put all our new states in the set of states only if they're not already there.
bool stateAlreadyInAllStates = false; bool stateAlreadyInAllStates = false;
Symbol* currStateSymbol; Symbol currStateSymbol;
for (std::vector< State * >::size_type i = 0; i < newStates.size(); i++) { for (std::vector< State * >::size_type i = 0; i < newStates.size(); i++) {
stateAlreadyInAllStates = false; stateAlreadyInAllStates = false;
currStateSymbol = (*(newStates[i]->getBasis()))[0]->getAtIndex(); currStateSymbol = (*(newStates[i]->getBasis()))[0]->getAtIndex();
@@ -327,13 +323,13 @@ std::string Parser::tableToString() {
//parseInput is now pure virtual //parseInput is now pure virtual
NodeTree<Symbol*>* Parser::reduceTreeCombine(Symbol* newSymbol, std::vector<Symbol*> &symbols) { NodeTree<Symbol>* Parser::reduceTreeCombine(Symbol newSymbol, std::vector<Symbol> &symbols) {
NodeTree<Symbol*>* newTree = new NodeTree<Symbol*>(newSymbol->getName(), newSymbol); NodeTree<Symbol>* newTree = new NodeTree<Symbol>(newSymbol.getName(), newSymbol);
for (std::vector<Symbol*>::size_type i = 0; i < symbols.size(); i++) { for (std::vector<Symbol>::size_type i = 0; i < symbols.size(); i++) {
if (symbols[i]->isTerminal()) if (symbols[i].isTerminal())
newTree->addChild(new NodeTree<Symbol*>(symbols[i]->getName(), symbols[i])); newTree->addChild(new NodeTree<Symbol>(symbols[i].getName(), symbols[i]));
else else
newTree->addChild(symbols[i]->getSubTree()); newTree->addChild(symbols[i].getSubTree());
} }
return(newTree); return(newTree);
} }

View File

@@ -8,7 +8,7 @@ RNGLRParser::~RNGLRParser() {
// //
} }
NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) { NodeTree<Symbol>* RNGLRParser::parseInput(std::string inputString) {
//Check for no tokens //Check for no tokens
bool accepting = false; bool accepting = false;
@@ -24,23 +24,17 @@ NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
} else { } else {
std::cout << "Rejected, no input (with no accepting state)" << std::endl; std::cout << "Rejected, no input (with no accepting state)" << std::endl;
} }
return new NodeTree<Symbol*>(); return new NodeTree<Symbol>();
} }
lexer.setInput(inputString); lexer.setInput(inputString);
//Now fully lex our input because this algorithm was designed in that manner and simplifies this first implementation. //Now fully lex our input because this algorithm was designed in that manner and simplifies this first implementation.
//It could be converted to on-line later. //It could be converted to on-line later.
Symbol* currentToken = lexer.next(); Symbol currentToken = lexer.next();
input.push_back(currentToken); input.push_back(currentToken);
while (*currentToken != *EOFSymbol) { while (currentToken != EOFSymbol) {
//std::cout << EOFSymbol->toString() << " " << currentToken->toString() << std::endl;
currentToken = lexer.next(); currentToken = lexer.next();
if (currentToken != NULL) { input.push_back(currentToken);
input.push_back(currentToken);
} else {
std::cout << "Rejected, lexer unable to fully tokenize sentence" << std::endl;
return new NodeTree<Symbol*>();
}
} }
std::cout << "\nDone with Lexing\n" << std::endl; std::cout << "\nDone with Lexing\n" << std::endl;
@@ -78,11 +72,11 @@ NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
// std::cout << "Checking if frontier " << i << " is empty" << std::endl; // std::cout << "Checking if frontier " << i << " is empty" << std::endl;
if (gss.frontierIsEmpty(i)) { if (gss.frontierIsEmpty(i)) {
std::cout << "Frontier " << i << " is empty." << std::endl; std::cout << "Frontier " << i << " is empty." << std::endl;
std::cout << "Failed on " << input[i]->toString() << std::endl; std::cout << "Failed on " << input[i].toString() << std::endl;
std::cout << "Nearby is:" << std::endl; std::cout << "Nearby is:" << std::endl;
int range = 5; int range = 5;
for (int j = (i-range >= 0 ? i-range : 0); j < (i+range < input.size() ? i+range : input.size()); j++) for (int j = (i-range >= 0 ? i-range : 0); j < (i+range < input.size() ? i+range : input.size()); j++)
std::cout << input[j]->toString() << " "; std::cout << input[j].toString() << " ";
std::cout << std::endl; std::cout << std::endl;
break; break;
} }
@@ -124,7 +118,7 @@ void RNGLRParser::reducer(int i) {
std::vector<NodeTree<int>*> currentPath = (*paths)[j]; std::vector<NodeTree<int>*> currentPath = (*paths)[j];
//Get the edges for the current path //Get the edges for the current path
std::vector<NodeTree<Symbol*>*> pathEdges = getPathEdges(currentPath); std::vector<NodeTree<Symbol>*> pathEdges = getPathEdges(currentPath);
std::reverse(pathEdges.begin(), pathEdges.end()); std::reverse(pathEdges.begin(), pathEdges.end());
//If the reduction length is 0, label as passed in is null //If the reduction length is 0, label as passed in is null
if (reduction.length != 0) if (reduction.length != 0)
@@ -132,24 +126,24 @@ void RNGLRParser::reducer(int i) {
//The end of the current path //The end of the current path
NodeTree<int>* currentReached = currentPath[currentPath.size()-1]; NodeTree<int>* currentReached = currentPath[currentPath.size()-1];
std::cout << "Getting the shfit state for state " << currentReached->getData() << " and symbol " << reduction.symbol->toString() << std::endl; std::cout << "Getting the shfit state for state " << currentReached->getData() << " and symbol " << reduction.symbol.toString() << std::endl;
int toState = table.getShift(currentReached->getData(), reduction.symbol)->shiftState; int toState = table.getShift(currentReached->getData(), reduction.symbol)->shiftState;
//If reduction length is 0, then we make the new label the appropriate nullable parts //If reduction length is 0, then we make the new label the appropriate nullable parts
NodeTree<Symbol*>* newLabel = NULL; NodeTree<Symbol>* newLabel = NULL;
if (reduction.length == 0) { if (reduction.length == 0) {
newLabel = reduction.nullableParts; newLabel = reduction.nullableParts;
} else { } else {
//Otherwise, we create the new label if we haven't already //Otherwise, we create the new label if we haven't already
int reachedFrontier = gss.getContainingFrontier(currentReached); int reachedFrontier = gss.getContainingFrontier(currentReached);
for (std::vector<std::pair<NodeTree<Symbol*>*, int> >::size_type k = 0; k < SPPFStepNodes.size(); k++) { for (std::vector<std::pair<NodeTree<Symbol>*, int> >::size_type k = 0; k < SPPFStepNodes.size(); k++) {
if ( SPPFStepNodes[k].second == reachedFrontier && *(SPPFStepNodes[k].first->getData()) == *(reduction.symbol)) { if ( SPPFStepNodes[k].second == reachedFrontier && SPPFStepNodes[k].first->getData() == reduction.symbol) {
newLabel = SPPFStepNodes[k].first; newLabel = SPPFStepNodes[k].first;
break; break;
} }
} }
if (!newLabel) { if (!newLabel) {
newLabel = new NodeTree<Symbol*>("frontier: " + intToString(reachedFrontier), reduction.symbol); newLabel = new NodeTree<Symbol>("frontier: " + intToString(reachedFrontier), reduction.symbol);
SPPFStepNodes.push_back(std::make_pair(newLabel, reachedFrontier)); SPPFStepNodes.push_back(std::make_pair(newLabel, reachedFrontier));
} }
} }
@@ -198,7 +192,7 @@ void RNGLRParser::reducer(int i) {
void RNGLRParser::shifter(int i) { void RNGLRParser::shifter(int i) {
if (i != input.size()-1) { if (i != input.size()-1) {
std::queue< std::pair<NodeTree<int>*, int> > nextShifts; std::queue< std::pair<NodeTree<int>*, int> > nextShifts;
NodeTree<Symbol*>* newLabel = new NodeTree<Symbol*>("frontier: " + intToString(i), input[i]); NodeTree<Symbol>* newLabel = new NodeTree<Symbol>("frontier: " + intToString(i), input[i]);
while (!toShift.empty()) { while (!toShift.empty()) {
std::pair<NodeTree<int>*, int> shift = toShift.front(); std::pair<NodeTree<int>*, int> shift = toShift.front();
toShift.pop(); toShift.pop();
@@ -239,7 +233,7 @@ void RNGLRParser::shifter(int i) {
} }
} }
void RNGLRParser::addChildren(NodeTree<Symbol*>* parent, std::vector<NodeTree<Symbol*>*>* children, NodeTree<Symbol*>* nullableParts) { void RNGLRParser::addChildren(NodeTree<Symbol>* parent, std::vector<NodeTree<Symbol>*>* children, NodeTree<Symbol>* nullableParts) {
if (nullableParts) if (nullableParts)
children->push_back(nullableParts); children->push_back(nullableParts);
@@ -248,14 +242,14 @@ void RNGLRParser::addChildren(NodeTree<Symbol*>* parent, std::vector<NodeTree<Sy
parent->addChildren(children); parent->addChildren(children);
} else { } else {
if (!arePacked(parent->getChildren())) { if (!arePacked(parent->getChildren())) {
NodeTree<Symbol*>* subParent = new NodeTree<Symbol*>("AmbiguityPackInner", NULL); NodeTree<Symbol>* subParent = new NodeTree<Symbol>("AmbiguityPackInner", Symbol("AmbiguityPackInner", true));
setPacked(subParent, true); setPacked(subParent, true);
std::vector<NodeTree<Symbol*>*> tmp = parent->getChildren(); std::vector<NodeTree<Symbol>*> tmp = parent->getChildren();
subParent->addChildren(&tmp); subParent->addChildren(&tmp);
parent->clearChildren(); parent->clearChildren();
parent->addChild(subParent); parent->addChild(subParent);
} }
NodeTree<Symbol*>* t = new NodeTree<Symbol*>("AmbiguityPackOuter", NULL); NodeTree<Symbol>* t = new NodeTree<Symbol>("AmbiguityPackOuter", Symbol("AmbiguityPackInner", true));
setPacked(t, true); setPacked(t, true);
parent->addChild(t); parent->addChild(t);
t->addChildren(children); t->addChildren(children);
@@ -263,12 +257,12 @@ void RNGLRParser::addChildren(NodeTree<Symbol*>* parent, std::vector<NodeTree<Sy
} }
} }
bool RNGLRParser::belongsToFamily(NodeTree<Symbol*>* node, std::vector<NodeTree<Symbol*>*>* nodes) { bool RNGLRParser::belongsToFamily(NodeTree<Symbol>* node, std::vector<NodeTree<Symbol>*>* nodes) {
//std::cout << "Checking " << node->getData()->toString() << "'s family" << std::endl; //std::cout << "Checking " << node->getData()->toString() << "'s family" << std::endl;
std::vector<NodeTree<Symbol*>*> children = node->getChildren(); std::vector<NodeTree<Symbol>*> children = node->getChildren();
for (std::vector<NodeTree<Symbol*>*>::size_type i = 0; i < nodes->size(); i++) { for (std::vector<NodeTree<Symbol>*>::size_type i = 0; i < nodes->size(); i++) {
bool containsOne = false; bool containsOne = false;
for (std::vector<NodeTree<Symbol*>*>::size_type j = 0; j < children.size(); j++) { for (std::vector<NodeTree<Symbol>*>::size_type j = 0; j < children.size(); j++) {
//Not sure where null comes from. For right now, just check to be sure we don't segfault //Not sure where null comes from. For right now, just check to be sure we don't segfault
if ((*nodes)[i] == children[j] || ( (*nodes)[i] != NULL && children[j] != NULL && (*(*nodes)[i]) == *(children[j]) )) { if ((*nodes)[i] == children[j] || ( (*nodes)[i] != NULL && children[j] != NULL && (*(*nodes)[i]) == *(children[j]) )) {
containsOne = true; containsOne = true;
@@ -282,18 +276,18 @@ bool RNGLRParser::belongsToFamily(NodeTree<Symbol*>* node, std::vector<NodeTree<
return true; return true;
} }
bool RNGLRParser::arePacked(std::vector<NodeTree<Symbol*>*> nodes) { bool RNGLRParser::arePacked(std::vector<NodeTree<Symbol>*> nodes) {
bool packed = true; bool packed = true;
for (std::vector<NodeTree<Symbol*>*>::size_type i = 0; i < nodes.size(); i++) for (std::vector<NodeTree<Symbol>*>::size_type i = 0; i < nodes.size(); i++)
packed &= packedMap[*(nodes[i])]; packed &= packedMap[*(nodes[i])];
return packed; return packed;
} }
bool RNGLRParser::isPacked(NodeTree<Symbol*>* node) { bool RNGLRParser::isPacked(NodeTree<Symbol>* node) {
return packedMap[*node]; return packedMap[*node];
} }
void RNGLRParser::setPacked(NodeTree<Symbol*>* node, bool isPacked) { void RNGLRParser::setPacked(NodeTree<Symbol>* node, bool isPacked) {
packedMap[*node] = isPacked; packedMap[*node] = isPacked;
} }
@@ -315,7 +309,7 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state, std:
//If not, create it. //If not, create it.
bool symbolAlreadyInState = false; bool symbolAlreadyInState = false;
for (std::vector< State* >::size_type j = 0; j < newStates.size(); j++) { for (std::vector< State* >::size_type j = 0; j < newStates.size(); j++) {
if (*(newStates[j]->basis[0]->getAtIndex()) == *(advancedRule->getAtIndex())) { if (newStates[j]->basis[0]->getAtIndex() == advancedRule->getAtIndex()) {
symbolAlreadyInState = true; symbolAlreadyInState = true;
//Add rule to state, combining with idenical rule except lookahead if exists //Add rule to state, combining with idenical rule except lookahead if exists
newStates[j]->addRuleCombineLookahead(advancedRule); newStates[j]->addRuleCombineLookahead(advancedRule);
@@ -331,7 +325,7 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state, std:
} }
//Put all our new states in the set of states only if they're not already there. //Put all our new states in the set of states only if they're not already there.
bool stateAlreadyInAllStates = false; bool stateAlreadyInAllStates = false;
Symbol* currStateSymbol; Symbol currStateSymbol;
for (std::vector< State * >::size_type i = 0; i < newStates.size(); i++) { for (std::vector< State * >::size_type i = 0; i < newStates.size(); i++) {
stateAlreadyInAllStates = false; stateAlreadyInAllStates = false;
currStateSymbol = (*(newStates[i]->getBasis()))[0]->getAtIndex(); currStateSymbol = (*(newStates[i]->getBasis()))[0]->getAtIndex();
@@ -367,9 +361,9 @@ void RNGLRParser::addStateReductionsToTable(State* state) {
for (std::vector<ParseRule*>::size_type i = 0; i < currStateTotal->size(); i++) { for (std::vector<ParseRule*>::size_type i = 0; i < currStateTotal->size(); i++) {
//See if reduce //See if reduce
//Also, this really only needs to be done for the state's basis, but we're already iterating through, so... //Also, this really only needs to be done for the state's basis, but we're already iterating through, so...
std::vector<Symbol*>* lookahead = (*currStateTotal)[i]->getLookahead(); std::vector<Symbol>* lookahead = (*currStateTotal)[i]->getLookahead();
if ((*currStateTotal)[i]->isAtEnd()) { if ((*currStateTotal)[i]->isAtEnd()) {
for (std::vector<Symbol*>::size_type j = 0; j < lookahead->size(); j++) for (std::vector<Symbol>::size_type j = 0; j < lookahead->size(); j++)
table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i])); table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i]));
//If this has an appropriate ruduction to null, get the reduce trees out //If this has an appropriate ruduction to null, get the reduce trees out
} else if (reducesToNull((*currStateTotal)[i])) { } else if (reducesToNull((*currStateTotal)[i])) {
@@ -377,7 +371,7 @@ void RNGLRParser::addStateReductionsToTable(State* state) {
//It used to be that if is a rule that produces only NULL, add in the approprite reduction, but use a new rule with a right side that is equal to //It used to be that if is a rule that produces only NULL, add in the approprite reduction, but use a new rule with a right side that is equal to
//the part that we've already gone through in the rule. (so we don't pop extra off stack) //the part that we've already gone through in the rule. (so we don't pop extra off stack)
//Now we use the same rule and make sure that the index location is used //Now we use the same rule and make sure that the index location is used
for (std::vector<Symbol*>::size_type j = 0; j < lookahead->size(); j++) for (std::vector<Symbol>::size_type j = 0; j < lookahead->size(); j++)
table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i])); table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i]));
} }
} }
@@ -388,33 +382,33 @@ bool RNGLRParser::fullyReducesToNull(ParseRule* rule) {
} }
bool RNGLRParser::reducesToNull(ParseRule* rule) { bool RNGLRParser::reducesToNull(ParseRule* rule) {
std::vector<Symbol*> avoidList; std::vector<Symbol> avoidList;
return reducesToNull(rule, avoidList); return reducesToNull(rule, avoidList);
} }
bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector<Symbol*> avoidList) { bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector<Symbol> avoidList) {
//If the rule is completed and not null, it doesn't reduce to null, it's just completed. //If the rule is completed and not null, it doesn't reduce to null, it's just completed.
if (rule->isAtEnd() && rule->getRightSize() != 0) if (rule->isAtEnd() && rule->getRightSize() != 0)
return false; return false;
for (std::vector<Symbol*>::size_type i = 0; i < avoidList.size(); i++) for (std::vector<Symbol>::size_type i = 0; i < avoidList.size(); i++)
if (*(rule->getLeftSide()) == *(avoidList[i])) if (rule->getLeftSide() == avoidList[i])
return false; return false;
avoidList.push_back(rule->getLeftSide()); avoidList.push_back(rule->getLeftSide());
std::vector<Symbol*> rightSide = rule->getRightSide(); std::vector<Symbol> rightSide = rule->getRightSide();
bool reduces = true; bool reduces = true;
for (std::vector<Symbol*>::size_type i = rule->getIndex(); i < rightSide.size(); i++) { for (std::vector<Symbol>::size_type i = rule->getIndex(); i < rightSide.size(); i++) {
if (*rightSide[i] == *nullSymbol) if (rightSide[i] == nullSymbol)
continue; continue;
if (rightSide[i]->isTerminal()) { if (rightSide[i].isTerminal()) {
reduces = false; reduces = false;
break; break;
} }
bool subSymbolReduces = false; bool subSymbolReduces = false;
for (std::vector<ParseRule*>::size_type j = 0; j < loadedGrammer.size(); j++) { for (std::vector<ParseRule*>::size_type j = 0; j < loadedGrammer.size(); j++) {
if (*(loadedGrammer[j]->getLeftSide()) == *(rightSide[i])) { if (loadedGrammer[j]->getLeftSide() == rightSide[i]) {
if(reducesToNull(loadedGrammer[j], avoidList)) { if(reducesToNull(loadedGrammer[j], avoidList)) {
subSymbolReduces = true; subSymbolReduces = true;
break; break;
@@ -429,32 +423,32 @@ bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector<Symbol*> avoidList)
return reduces; return reduces;
} }
NodeTree<Symbol*>* RNGLRParser::getNullableParts(ParseRule* rule) { NodeTree<Symbol>* RNGLRParser::getNullableParts(ParseRule* rule) {
return getNullableParts(rule, std::vector<NodeTree<Symbol*>*>()); return getNullableParts(rule, std::vector<NodeTree<Symbol>*>());
} }
NodeTree<Symbol*>* RNGLRParser::getNullableParts(ParseRule* rule, std::vector<NodeTree<Symbol*>*> avoidList) { NodeTree<Symbol>* RNGLRParser::getNullableParts(ParseRule* rule, std::vector<NodeTree<Symbol>*> avoidList) {
if (reducesToNull(rule)) { if (reducesToNull(rule)) {
//std::cout << "Reduces to null so adding parts " << rule->toString() << std::endl; //std::cout << "Reduces to null so adding parts " << rule->toString() << std::endl;
Symbol* symbol = rule->getLeftSide(); Symbol symbol = rule->getLeftSide();
NodeTree<Symbol*>* symbolNode = new NodeTree<Symbol*>(symbol->getName(), symbol); NodeTree<Symbol>* symbolNode = new NodeTree<Symbol>(symbol.getName(), symbol);
if (*(rule->getAtNextIndex()) == *nullSymbol) { if (rule->getAtNextIndex() == nullSymbol) {
symbolNode->addChild(new NodeTree<Symbol*>(nullSymbol->getName(), nullSymbol)); symbolNode->addChild(new NodeTree<Symbol>(nullSymbol.getName(), nullSymbol));
} else { } else {
//Find recursively //Find recursively
ParseRule* iterate = rule->clone(); ParseRule* iterate = rule->clone();
while (!iterate->isAtEnd()) { while (!iterate->isAtEnd()) {
//Check to see if we've done this symbol already, if so use it //Check to see if we've done this symbol already, if so use it
for (std::vector<NodeTree<Symbol*>*>::size_type i = 0; i < avoidList.size(); i++) { for (std::vector<NodeTree<Symbol>*>::size_type i = 0; i < avoidList.size(); i++) {
if (*(iterate->getAtNextIndex()) == *(avoidList[i]->getData())) { if (iterate->getAtNextIndex() == avoidList[i]->getData()) {
symbolNode->addChild(avoidList[i]); symbolNode->addChild(avoidList[i]);
break; break;
} }
} }
//We haven't so do it recursively //We haven't so do it recursively
for (std::vector<ParseRule*>::size_type i = 0; i < loadedGrammer.size(); i++) { for (std::vector<ParseRule*>::size_type i = 0; i < loadedGrammer.size(); i++) {
if (fullyReducesToNull(loadedGrammer[i]) && *(iterate->getAtNextIndex()) == *(loadedGrammer[i]->getLeftSide())) { if (fullyReducesToNull(loadedGrammer[i]) && iterate->getAtNextIndex() == loadedGrammer[i]->getLeftSide()) {
NodeTree<Symbol*>* symbolTree = getNullableParts(loadedGrammer[i], avoidList); NodeTree<Symbol>* symbolTree = getNullableParts(loadedGrammer[i], avoidList);
avoidList.push_back(symbolTree); avoidList.push_back(symbolTree);
symbolNode->addChild(symbolTree); symbolNode->addChild(symbolTree);
} }
@@ -467,12 +461,12 @@ NodeTree<Symbol*>* RNGLRParser::getNullableParts(ParseRule* rule, std::vector<No
return NULL; return NULL;
} }
NodeTree<Symbol*>* RNGLRParser::getNullableParts(Symbol* symbol) { NodeTree<Symbol>* RNGLRParser::getNullableParts(Symbol symbol) {
return new NodeTree<Symbol*>("CRAZY_SYMBOL", nullSymbol); return new NodeTree<Symbol>("CRAZY_SYMBOL", nullSymbol);
} }
std::vector<NodeTree<Symbol*>*> RNGLRParser::getPathEdges(std::vector<NodeTree<int>*> path) { std::vector<NodeTree<Symbol>*> RNGLRParser::getPathEdges(std::vector<NodeTree<int>*> path) {
std::vector<NodeTree<Symbol*>*> pathEdges; std::vector<NodeTree<Symbol>*> pathEdges;
for (std::vector<NodeTree<int>*>::size_type i = 0; i < path.size()-1; i++) for (std::vector<NodeTree<int>*>::size_type i = 0; i < path.size()-1; i++)
pathEdges.push_back(gss.getEdge(path[i], path[i+1])); pathEdges.push_back(gss.getEdge(path[i], path[i+1]));
return pathEdges; return pathEdges;

View File

@@ -1,5 +1,12 @@
#include "Symbol.h" #include "Symbol.h"
Symbol::Symbol() {
this->name = "UninitlizedSymbol";
this->terminal = false;
this->subTree = NULL;
value = "NoValue";
}
Symbol::Symbol(std::string name, bool isTerminal) { Symbol::Symbol(std::string name, bool isTerminal) {
this->name = name; this->name = name;
this->terminal = isTerminal; this->terminal = isTerminal;
@@ -14,7 +21,7 @@ Symbol::Symbol(std::string name, bool isTerminal, std::string value) {
this->value = value; this->value = value;
} }
Symbol::Symbol(std::string name, bool isTerminal, NodeTree<Symbol*>* tree) { Symbol::Symbol(std::string name, bool isTerminal, NodeTree<Symbol>* tree) {
this->name = name; this->name = name;
this->terminal = isTerminal; this->terminal = isTerminal;
this->subTree = tree; this->subTree = tree;
@@ -24,31 +31,31 @@ Symbol::~Symbol() {
} }
const bool Symbol::operator==(const Symbol &other) { const bool Symbol::operator==(const Symbol &other) const {
return( name == other.name && terminal == other.terminal); return( name == other.name && terminal == other.terminal);
} }
const bool Symbol::operator!=(const Symbol &other) { const bool Symbol::operator!=(const Symbol &other) const {
return(!this->operator==(other)); return(!this->operator==(other));
} }
std::string Symbol::getName() { const bool Symbol::operator<(const Symbol &other) const {
return name < other.getName();
}
std::string Symbol::getName() const {
return(name); return(name);
} }
std::string Symbol::toString() { std::string Symbol::toString() const {
return(name + (terminal ? " " + value : "")); return(name + (terminal ? " " + value : ""));
} }
Symbol* Symbol::clone() { void Symbol::setSubTree(NodeTree<Symbol>* tree) {
return new Symbol(name, terminal, subTree);
}
void Symbol::setSubTree(NodeTree<Symbol*>* tree) {
subTree = tree; subTree = tree;
} }
NodeTree<Symbol*>* Symbol::getSubTree() { NodeTree<Symbol>* Symbol::getSubTree() {
return subTree; return subTree;
} }

View File

@@ -8,12 +8,12 @@ Table::~Table() {
// //
} }
void Table::setSymbols(Symbol* EOFSymbol, Symbol* nullSymbol) { void Table::setSymbols(Symbol EOFSymbol, Symbol nullSymbol) {
this->EOFSymbol = EOFSymbol; this->EOFSymbol = EOFSymbol;
this->nullSymbol = nullSymbol; this->nullSymbol = nullSymbol;
} }
void Table::add(int stateNum, Symbol* tranSymbol, ParseAction* action) { void Table::add(int stateNum, Symbol tranSymbol, ParseAction* action) {
//If this is the first time we're adding to the table, add the EOF character //If this is the first time we're adding to the table, add the EOF character
if (symbolIndexVec.size() == 0) if (symbolIndexVec.size() == 0)
@@ -28,8 +28,8 @@ void Table::add(int stateNum, Symbol* tranSymbol, ParseAction* action) {
//find out what index this symbol is on //find out what index this symbol is on
int symbolIndex = -1; int symbolIndex = -1;
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) { for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++) {
if ( *(symbolIndexVec[i]) == *tranSymbol ) { if ( symbolIndexVec[i] == tranSymbol ) {
//Has been found //Has been found
symbolIndex = i; symbolIndex = i;
break; break;
@@ -79,11 +79,11 @@ void Table::add(int stateNum, Symbol* tranSymbol, ParseAction* action) {
} }
} }
void Table::remove(int stateNum, Symbol* tranSymbol) { void Table::remove(int stateNum, Symbol tranSymbol) {
//find out what index this symbol is on //find out what index this symbol is on
int symbolIndex = -1; int symbolIndex = -1;
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) { for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++) {
if ( *(symbolIndexVec[i]) == *tranSymbol ) { if ( symbolIndexVec[i] == tranSymbol ) {
//Has been found //Has been found
symbolIndex = i; symbolIndex = i;
break; break;
@@ -92,21 +92,21 @@ void Table::remove(int stateNum, Symbol* tranSymbol) {
(*(table[stateNum]))[symbolIndex] = NULL; (*(table[stateNum]))[symbolIndex] = NULL;
} }
std::vector<ParseAction*>* Table::get(int state, Symbol* token) { std::vector<ParseAction*>* Table::get(int state, Symbol token) {
int symbolIndex = -1; int symbolIndex = -1;
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) { for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++) {
if ( *(symbolIndexVec[i]) == *token) { if ( symbolIndexVec[i] == token) {
symbolIndex = i; symbolIndex = i;
break; break;
} }
} }
if (symbolIndex == -1) { if (symbolIndex == -1) {
std::cout << "Unrecognized symbol: " << token->toString() << ", cannot get from table!" << std::endl; std::cout << "Unrecognized symbol: " << token.toString() << ", cannot get from table!" << std::endl;
return NULL; return NULL;
} }
std::cout << "Get for state: " << state << ", and Symbol: " << token->toString() << std::endl; std::cout << "Get for state: " << state << ", and Symbol: " << token.toString() << std::endl;
if (state < 0 || state >= table.size()) { if (state < 0 || state >= table.size()) {
std::cout << "State bad: " << state << std::endl; std::cout << "State bad: " << state << std::endl;
return NULL; return NULL;
@@ -115,7 +115,7 @@ std::vector<ParseAction*>* Table::get(int state, Symbol* token) {
std::vector<ParseAction*>* action = NULL; std::vector<ParseAction*>* action = NULL;
if (symbolIndex < 0 || symbolIndex >= table[state]->size()) { if (symbolIndex < 0 || symbolIndex >= table[state]->size()) {
std::cout << "Symbol bad for this state: " << token->toString() << ". This is a reject." << std::endl; std::cout << "Symbol bad for this state: " << token.toString() << ". This is a reject." << std::endl;
} else { } else {
action = (*(table[state]))[symbolIndex]; action = (*(table[state]))[symbolIndex];
} }
@@ -144,7 +144,7 @@ std::vector<ParseAction*>* Table::get(int state, Symbol* token) {
return (action); return (action);
} }
ParseAction* Table::getShift(int state, Symbol* token) { ParseAction* Table::getShift(int state, Symbol token) {
std::vector<ParseAction*>* actions = get(state, token); std::vector<ParseAction*>* actions = get(state, token);
ParseAction* shift = NULL; ParseAction* shift = NULL;
for (int i = 0; i < actions->size(); i++) { for (int i = 0; i < actions->size(); i++) {
@@ -158,8 +158,8 @@ ParseAction* Table::getShift(int state, Symbol* token) {
std::string Table::toString() { std::string Table::toString() {
std::string concat = ""; std::string concat = "";
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++)
concat += "\t" + symbolIndexVec[i]->toString(); concat += "\t" + symbolIndexVec[i].toString();
concat += "\n"; concat += "\n";
for (std::vector< std::vector< std::vector< ParseRule* >* >* >::size_type i = 0; i < table.size(); i++) { for (std::vector< std::vector< std::vector< ParseRule* >* >* >::size_type i = 0; i < table.size(); i++) {