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

@@ -1,27 +1,30 @@
#ifndef ASTDATA_H
#define ASTDATA_H
#include <vector>
#include "Symbol.h"
#ifndef NULL
#define NULL 0
#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 {
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, Symbol* symbol, ValueType valueType = none);
ASTData(ASTType type, Symbol symbol, ValueType valueType = none);
~ASTData();
std::string toString();
ASTType type;
Symbol* symbol;
ValueType valueType;
Symbol symbol;
private:
};

View File

@@ -1,16 +1,16 @@
#ifndef ASTTRANSFORMATION_H
#define ASTTRANSFORMATION_H
#include "ASTData.h"
#include "NodeTransformation.h"
class ASTTransformation: public Transformation<Symbol*,ASTData> {
class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
public:
ASTTransformation();
~ASTTransformation();
virtual NodeTree<Symbol*>* transform(NodeTree<ASTData>* from);
virtual NodeTree<ASTData>* transform(NodeTree<Symbol>* from);
private:
//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);
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);
NodeTree<Symbol*>* getEdge(NodeTree<int>* start, NodeTree<int>* end);
void addEdge(NodeTree<int>* start, NodeTree<int>* end, NodeTree<Symbol*>* edge);
NodeTree<Symbol>* getEdge(NodeTree<int>* start, NodeTree<int>* end);
void addEdge(NodeTree<int>* start, NodeTree<int>* end, NodeTree<Symbol>* edge);
std::string toString();
private:
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

View File

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

View File

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

View File

@@ -28,6 +28,7 @@ class NodeTree {
void addChild(NodeTree<T>* child);
void addChildren(std::vector<NodeTree<T>*>* children);
void addChildren(std::vector<NodeTree<T>*> children);
int findChild(NodeTree<T>* child);
void removeChild(NodeTree<T>* child);
void removeChild(int index);
@@ -63,8 +64,6 @@ int NodeTree<T>::idCounter;
template<class T>
NodeTree<T>::NodeTree() {
name = "UnnamedNode";
data = NULL;
id = idCounter++;
}
@@ -93,6 +92,7 @@ const bool NodeTree<T>::operator==(NodeTree &other) {
return true;
}
//Used when making a map of NodeTrees
template<class T>
const bool NodeTree<T>::operator<(const NodeTree &other) const {
return data < other.getData();
@@ -136,6 +136,12 @@ void NodeTree<T>::addChildren(std::vector<NodeTree<T>*>* children) {
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>
int NodeTree<T>::findChild(NodeTree<T>* child) {
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>
std::string NodeTree<T>::getDOTName() {
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
else
DOTName = "\"" + replaceExEscape(name, "\"", " \\\"") + "_" + intToString(id) + "\"";
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)
// 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
// else
// DOTName = "\"" + replaceExEscape(name, "\"", " \\\"") + "_" + intToString(id) + "\"";
return(replaceExEscape(DOTName, "\n", "\\n"));
}

View File

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

View File

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

View File

@@ -15,47 +15,47 @@ class RNGLRParser: public Parser {
public:
RNGLRParser();
~RNGLRParser();
NodeTree<Symbol*>* parseInput(std::string inputString);
NodeTree<Symbol>* parseInput(std::string inputString);
private:
void reducer(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 addStateReductionsToTable(State* state);
bool fullyReducesToNull(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 arePacked(std::vector<NodeTree<Symbol*>*> nodes);
bool isPacked(NodeTree<Symbol*>* node);
void setPacked(NodeTree<Symbol*>* node, bool isPacked);
bool belongsToFamily(NodeTree<Symbol>* node, std::vector<NodeTree<Symbol>*>* nodes);
bool arePacked(std::vector<NodeTree<Symbol>*> nodes);
bool isPacked(NodeTree<Symbol>* node);
void setPacked(NodeTree<Symbol>* node, bool isPacked);
NodeTree<Symbol*>* getNullableParts(ParseRule* rule);
NodeTree<Symbol*>* getNullableParts(ParseRule* rule, std::vector<NodeTree<Symbol*>*> avoidList);
NodeTree<Symbol*>* getNullableParts(Symbol* symbol);
NodeTree<Symbol>* getNullableParts(ParseRule* rule);
NodeTree<Symbol>* getNullableParts(ParseRule* rule, std::vector<NodeTree<Symbol>*> avoidList);
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;
//start node, lefthand side of the reduction, reduction length
struct Reduction {
NodeTree<int>* from;
Symbol* symbol;
Symbol symbol;
int length;
NodeTree<Symbol*>* nullableParts;
NodeTree<Symbol*>* label;
NodeTree<Symbol>* nullableParts;
NodeTree<Symbol>* label;
} ;
std::queue<Reduction> toReduce;
//Node coming from, state going to
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::map<NodeTree<Symbol*>, bool> packedMap;
std::vector<NodeTree<Symbol>*> nullableParts;
std::map<NodeTree<Symbol>, bool> packedMap;
};
#endif

View File

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

View File

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

View File

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