Made Symbol always stack, not heap, allocated. Finally fixed bugs with ASTTransformation.
This commit is contained in:
@@ -4,7 +4,7 @@ project(Kraken)
|
||||
|
||||
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} )
|
||||
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
#ifndef ASTDATA_H
|
||||
#define ASTDATA_H
|
||||
|
||||
#include <vector>
|
||||
#include "Symbol.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#include "Symbol.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class ASTData {
|
||||
public:
|
||||
enum ASTType {translation_unit, interpreter_directive, identifier,
|
||||
import, interpreter_directive, function, code_block,
|
||||
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 }
|
||||
enum ValueType {none, boolean, integer, floating, double_percision, char_string };
|
||||
|
||||
|
||||
class ASTData {
|
||||
public:
|
||||
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:
|
||||
|
||||
};
|
||||
|
||||
@@ -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
|
||||
53
include/CollapseTransformation.h
Normal file
53
include/CollapseTransformation.h
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
49
main.cpp
49
main.cpp
@@ -1,6 +1,7 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include "NodeTree.h"
|
||||
#include "Symbol.h"
|
||||
@@ -10,12 +11,15 @@
|
||||
|
||||
#include "NodeTransformation.h"
|
||||
#include "RemovalTransformation.h"
|
||||
#include "CollapseTransformation.h"
|
||||
#include "ASTTransformation.h"
|
||||
#include "ASTData.h"
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
std::ifstream programInFile, grammerInFile;
|
||||
std::ofstream outFile, outFileTransformed;
|
||||
std::ofstream outFile, outFileTransformed, outFileAST;
|
||||
|
||||
programInFile.open(argv[1]);
|
||||
if (!programInFile.is_open()) {
|
||||
@@ -41,6 +45,12 @@ int main(int argc, char* argv[]) {
|
||||
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
|
||||
std::string programInputFileString, grammerInputFileString;
|
||||
std::string line;
|
||||
@@ -77,7 +87,7 @@ int main(int argc, char* argv[]) {
|
||||
std::cout << "\nParsing" << std::endl;
|
||||
|
||||
std::cout << programInputFileString << std::endl;
|
||||
NodeTree<Symbol*>* parseTree = parser.parseInput(programInputFileString);
|
||||
NodeTree<Symbol>* parseTree = parser.parseInput(programInputFileString);
|
||||
|
||||
if (parseTree) {
|
||||
//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;
|
||||
}
|
||||
|
||||
NodeTransformation<Symbol*, Symbol*>* removeWS = new RemovalTransformation<Symbol*>(new Symbol("WS", false));
|
||||
NodeTree<Symbol*>* noWhiteSpace = removeWS->transform(parseTree);
|
||||
delete removeWS;
|
||||
//Pre AST Transformations
|
||||
std::vector<NodeTransformation<Symbol, Symbol>*> preASTTransforms;
|
||||
//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) {
|
||||
outFileTransformed << noWhiteSpace->DOTGraphString() << std::endl;
|
||||
NodeTree<ASTData>* AST = ASTTransformation().transform(parseTree);
|
||||
//NodeTree<ASTData>* AST = (new ASTTransformation())->transform(parseTree);
|
||||
|
||||
if (parseTree) {
|
||||
outFileTransformed << parseTree->DOTGraphString() << std::endl;
|
||||
} else {
|
||||
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();
|
||||
grammerInFile.close();
|
||||
outFile.close();
|
||||
outFileTransformed.close();
|
||||
outFileAST.close();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
ASTData::ASTData(ASTType type, ValueType valueType) {
|
||||
this->type = type;
|
||||
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->valueType = valueType;
|
||||
this->symbol = symbol;
|
||||
@@ -15,3 +14,7 @@ ASTData::ASTData(ASTType type, Symbol* symbol, ValueType valueType) {
|
||||
|
||||
ASTData::~ASTData() {
|
||||
}
|
||||
|
||||
std::string ASTData::toString() {
|
||||
return "ASTData!";
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@ ASTTransformation::~ASTTransformation() {
|
||||
//
|
||||
}
|
||||
|
||||
virtual NodeTree<Symbol*>* ASTTransformation::transform(NodeTree<ASTData>* from) {
|
||||
NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -107,11 +107,11 @@ bool GraphStructuredStack::hasEdge(NodeTree<int>* start, NodeTree<int>* end) {
|
||||
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)];
|
||||
}
|
||||
|
||||
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);
|
||||
end->addParent(start);
|
||||
edges[std::make_pair(start, end)] = edge;
|
||||
|
||||
@@ -7,14 +7,14 @@ LALRParser::~LALRParser() {
|
||||
//Nothing to do in this version
|
||||
}
|
||||
|
||||
NodeTree<Symbol*>* LALRParser::parseInput(std::string inputString) {
|
||||
NodeTree<Symbol>* LALRParser::parseInput(std::string inputString) {
|
||||
lexer.setInput(inputString);
|
||||
Symbol* token = lexer.next();
|
||||
Symbol token = lexer.next();
|
||||
std::vector<ParseAction*>* actionList;
|
||||
ParseAction* action;
|
||||
|
||||
stateStack.push(0);
|
||||
symbolStack.push(new Symbol("INVALID", false));
|
||||
symbolStack.push(Symbol("INVALID", false));
|
||||
|
||||
while (true) {
|
||||
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();
|
||||
//Keep track of symbols popped for parse tree
|
||||
std::vector<Symbol*> poppedSymbols;
|
||||
std::vector<Symbol> poppedSymbols;
|
||||
for (int i = 0; i < rightSideLength; i++) {
|
||||
poppedSymbols.push_back(symbolStack.top());
|
||||
stateStack.pop();
|
||||
symbolStack.pop();
|
||||
}
|
||||
std::reverse(poppedSymbols.begin(), poppedSymbols.end()); //To put in order
|
||||
//Assign the new tree to the new Symbol
|
||||
Symbol* newSymbol = action->reduceRule->getLeftSide()->clone();
|
||||
newSymbol->setSubTree(reduceTreeCombine(newSymbol, poppedSymbols));
|
||||
//Assign the new tree to the Symbol
|
||||
Symbol newSymbol = action->reduceRule->getLeftSide();
|
||||
newSymbol.setSubTree(reduceTreeCombine(newSymbol, poppedSymbols));
|
||||
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());
|
||||
action = (*(actionList))[actionList->size()-1];
|
||||
@@ -50,7 +50,7 @@ NodeTree<Symbol*>* LALRParser::parseInput(std::string inputString) {
|
||||
break;
|
||||
}
|
||||
case ParseAction::SHIFT:
|
||||
std::cout << "Shift " << token->toString() << std::endl;
|
||||
std::cout << "Shift " << token.toString() << std::endl;
|
||||
|
||||
symbolStack.push(token);
|
||||
token = lexer.next();
|
||||
@@ -58,11 +58,11 @@ NodeTree<Symbol*>* LALRParser::parseInput(std::string inputString) {
|
||||
break;
|
||||
case ParseAction::ACCEPT:
|
||||
std::cout << "ACCEPTED!" << std::endl;
|
||||
return(symbolStack.top()->getSubTree());
|
||||
return(symbolStack.top().getSubTree());
|
||||
break;
|
||||
case ParseAction::REJECT:
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -22,11 +22,11 @@ void Lexer::addRegEx(std::string 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;
|
||||
//If we're at the end, return an eof
|
||||
if (currentPosition >= input.length()-1)
|
||||
return new Symbol("$EOF$", true);
|
||||
return Symbol("$EOF$", true);
|
||||
int longestMatch = -1;
|
||||
RegEx* longestRegEx = NULL;
|
||||
std::string remainingString = input.substr(currentPosition,input.length()-1);
|
||||
@@ -42,10 +42,10 @@ Symbol* Lexer::next() {
|
||||
std::string eatenString = input.substr(currentPosition, longestMatch+1);
|
||||
currentPosition += longestMatch + 1;
|
||||
//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 {
|
||||
//std::cout << "Found no applicable regex" << std::endl;
|
||||
//std::cout << "Remaining is ||" << input.substr(currentPosition,input.length()-1) << "||" << std::endl;
|
||||
return NULL;
|
||||
return Symbol();
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,10 @@
|
||||
|
||||
ParseRule::ParseRule() {
|
||||
pointerIndex = 0;
|
||||
leftHandle = 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->pointerIndex = pointerIndex;
|
||||
this->rightSide = rightSide;
|
||||
@@ -33,35 +32,35 @@ ParseRule* ParseRule::clone() {
|
||||
return( new ParseRule(leftHandle, pointerIndex, rightSide, lookahead) );
|
||||
}
|
||||
|
||||
void ParseRule::setLeftHandle(Symbol* leftHandle) {
|
||||
void ParseRule::setLeftHandle(Symbol leftHandle) {
|
||||
this->leftHandle = leftHandle;
|
||||
}
|
||||
|
||||
void ParseRule::appendToRight(Symbol* appendee) {
|
||||
void ParseRule::appendToRight(Symbol appendee) {
|
||||
rightSide.push_back(appendee);
|
||||
}
|
||||
|
||||
Symbol* ParseRule::getLeftSide() {
|
||||
Symbol ParseRule::getLeftSide() {
|
||||
return leftHandle;
|
||||
}
|
||||
|
||||
void ParseRule::setRightSide(std::vector<Symbol*> rightSide) {
|
||||
void ParseRule::setRightSide(std::vector<Symbol> rightSide) {
|
||||
this->rightSide = rightSide;
|
||||
}
|
||||
|
||||
std::vector<Symbol*> ParseRule::getRightSide() {
|
||||
std::vector<Symbol> ParseRule::getRightSide() {
|
||||
return rightSide;
|
||||
}
|
||||
|
||||
Symbol* ParseRule::getAtNextIndex() {
|
||||
Symbol ParseRule::getAtNextIndex() {
|
||||
if (pointerIndex >= rightSide.size())
|
||||
return NULL;
|
||||
return Symbol();
|
||||
return rightSide[pointerIndex];
|
||||
}
|
||||
|
||||
Symbol* ParseRule::getAtIndex() {
|
||||
Symbol ParseRule::getAtIndex() {
|
||||
if (pointerIndex < 1)
|
||||
return NULL;
|
||||
return Symbol();
|
||||
return rightSide[pointerIndex-1];
|
||||
}
|
||||
|
||||
@@ -85,15 +84,15 @@ bool ParseRule::isAtEnd() {
|
||||
return pointerIndex == rightSide.size();
|
||||
}
|
||||
|
||||
void ParseRule::setLookahead(std::vector<Symbol*>* lookahead) {
|
||||
void ParseRule::setLookahead(std::vector<Symbol>* lookahead) {
|
||||
this->lookahead = lookahead;
|
||||
}
|
||||
|
||||
void ParseRule::addLookahead(std::vector<Symbol*>* lookahead) {
|
||||
for (std::vector<Symbol*>::size_type i = 0; i < lookahead->size(); i++) {
|
||||
void ParseRule::addLookahead(std::vector<Symbol>* lookahead) {
|
||||
for (std::vector<Symbol>::size_type i = 0; i < lookahead->size(); i++) {
|
||||
bool alreadyIn = false;
|
||||
for (std::vector<Symbol*>::size_type j = 0; j < this->lookahead->size(); j++) {
|
||||
if (*((*lookahead)[i]) == *((*(this->lookahead))[j])) {
|
||||
for (std::vector<Symbol>::size_type j = 0; j < this->lookahead->size(); j++) {
|
||||
if ((*lookahead)[i] == (*(this->lookahead))[j]) {
|
||||
alreadyIn = true;
|
||||
break;
|
||||
}
|
||||
@@ -103,23 +102,23 @@ void ParseRule::addLookahead(std::vector<Symbol*>* lookahead) {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Symbol*>* ParseRule::getLookahead() {
|
||||
std::vector<Symbol>* ParseRule::getLookahead() {
|
||||
return lookahead;
|
||||
}
|
||||
|
||||
std::string ParseRule::toString() {
|
||||
std::string concat = leftHandle->toString() + " -> ";
|
||||
std::string concat = leftHandle.toString() + " -> ";
|
||||
for (int i = 0; i < rightSide.size(); i++) {
|
||||
if (i == pointerIndex)
|
||||
concat += "(*) ";
|
||||
concat += rightSide[i]->toString() + " ";
|
||||
concat += rightSide[i].toString() + " ";
|
||||
}
|
||||
if (pointerIndex >= rightSide.size())
|
||||
concat += "(*)";
|
||||
if (lookahead != NULL) {
|
||||
concat += "**";
|
||||
for (std::vector<Symbol*>::size_type i = 0; i < lookahead->size(); i++)
|
||||
concat += (*lookahead)[i]->toString();
|
||||
for (std::vector<Symbol>::size_type i = 0; i < lookahead->size(); i++)
|
||||
concat += (*lookahead)[i].toString();
|
||||
concat += "**";
|
||||
}
|
||||
return(concat);
|
||||
@@ -128,7 +127,7 @@ std::string ParseRule::toString() {
|
||||
std::string ParseRule::toDOT() {
|
||||
std::string concat = "";
|
||||
for (int i = 0; i < rightSide.size(); i++) {
|
||||
concat += leftHandle->toString() + " -> " + rightSide[i]->toString() + ";\n";
|
||||
concat += leftHandle.toString() + " -> " + rightSide[i].toString() + ";\n";
|
||||
}
|
||||
return(concat);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
#include "Parser.h"
|
||||
|
||||
Parser::Parser() {
|
||||
EOFSymbol = new Symbol("$EOF$", true);
|
||||
nullSymbol = new Symbol("$NULL$", true);
|
||||
Parser::Parser() : EOFSymbol("$EOF$", true), nullSymbol("$NULL$", true){
|
||||
table.setSymbols(EOFSymbol, nullSymbol);
|
||||
}
|
||||
|
||||
Parser::~Parser() {
|
||||
delete EOFSymbol;
|
||||
delete nullSymbol;
|
||||
}
|
||||
|
||||
Symbol* Parser::getOrAddSymbol(std::string symbolString, bool isTerminal) {
|
||||
Symbol* symbol;
|
||||
Symbol Parser::getOrAddSymbol(std::string symbolString, bool isTerminal) {
|
||||
Symbol symbol;
|
||||
std::pair<std::string, bool> entry = std::make_pair(symbolString, isTerminal);
|
||||
if (symbols.find(entry) == symbols.end()) {
|
||||
symbol = new Symbol(symbolString, isTerminal);
|
||||
symbol = Symbol(symbolString, isTerminal);
|
||||
symbols[entry] = symbol;
|
||||
} else {
|
||||
symbol = symbols[entry];
|
||||
@@ -31,10 +27,10 @@ void Parser::loadGrammer(std::string grammerInputString) {
|
||||
while(currToken != "") {
|
||||
//Load the left of the rule
|
||||
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);
|
||||
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();
|
||||
while (currToken != ";") {
|
||||
|
||||
@@ -84,7 +80,7 @@ void Parser::createStateSet() {
|
||||
|
||||
//Set the first state's basis to be the goal rule with lookahead EOF
|
||||
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);
|
||||
goalRule->setLookahead(goalRuleLookahead);
|
||||
State* zeroState = new State(0, goalRule);
|
||||
@@ -111,38 +107,38 @@ int Parser::stateNum(State* state) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::vector<Symbol*>* Parser::firstSet(Symbol* token) {
|
||||
std::vector<Symbol*> avoidList;
|
||||
std::vector<Symbol>* Parser::firstSet(Symbol token) {
|
||||
std::vector<Symbol> 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
|
||||
for (std::vector<Symbol*>::size_type i = 0; i < avoidList.size(); i++)
|
||||
if (*(avoidList[i]) == *token) {
|
||||
return new std::vector<Symbol*>();
|
||||
for (std::vector<Symbol>::size_type i = 0; i < avoidList.size(); i++)
|
||||
if (avoidList[i] == token) {
|
||||
return new std::vector<Symbol>();
|
||||
}
|
||||
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.
|
||||
if (token->isTerminal()) {
|
||||
if (token.isTerminal()) {
|
||||
first->push_back(token);
|
||||
return(first);
|
||||
}
|
||||
//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.
|
||||
//If that one includes mull, do the next one too (if it exists).
|
||||
Symbol* rightToken = NULL;
|
||||
std::vector<Symbol*>* recursiveFirstSet = NULL;
|
||||
Symbol rightToken;
|
||||
std::vector<Symbol>* recursiveFirstSet = NULL;
|
||||
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
|
||||
bool recFirstSetHasNull = false;
|
||||
int j = 0;
|
||||
do {
|
||||
rightToken = loadedGrammer[i]->getRightSide()[j]; //Get token of the right side of this rule
|
||||
if (rightToken->isTerminal()) {
|
||||
recursiveFirstSet = new std::vector<Symbol*>();
|
||||
if (rightToken.isTerminal()) {
|
||||
recursiveFirstSet = new std::vector<Symbol>();
|
||||
recursiveFirstSet->push_back(rightToken);
|
||||
} else {
|
||||
//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());
|
||||
//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;
|
||||
for (std::vector<Symbol*>::size_type k = 0; k < recursiveFirstSet->size(); k++) {
|
||||
if ((*(*recursiveFirstSet)[k]) == *nullSymbol) {
|
||||
for (std::vector<Symbol>::size_type k = 0; k < recursiveFirstSet->size(); k++) {
|
||||
if ((*recursiveFirstSet)[k] == nullSymbol) {
|
||||
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.
|
||||
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)
|
||||
rule = rule->clone();
|
||||
rule->advancePointer();
|
||||
|
||||
//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*>* symbolFirstSet;
|
||||
std::vector<Symbol>* followSet = new std::vector<Symbol>();
|
||||
std::vector<Symbol>* symbolFirstSet;
|
||||
bool symbolFirstSetHasNull = true;
|
||||
while (symbolFirstSetHasNull && !rule->isAtEnd()) {
|
||||
symbolFirstSetHasNull = false;
|
||||
symbolFirstSet = firstSet(rule->getAtNextIndex());
|
||||
for (std::vector<Symbol*>::size_type i = 0; i < symbolFirstSet->size(); i++) {
|
||||
if (*((*symbolFirstSet)[i]) == *nullSymbol) {
|
||||
for (std::vector<Symbol>::size_type i = 0; i < symbolFirstSet->size(); i++) {
|
||||
if ((*symbolFirstSet)[i] == nullSymbol) {
|
||||
symbolFirstSetHasNull = true;
|
||||
symbolFirstSet->erase(symbolFirstSet->begin()+i);
|
||||
break;
|
||||
@@ -192,11 +188,11 @@ std::vector<Symbol*>* Parser::incrementiveFollowSet(ParseRule* rule) {
|
||||
symbolFirstSet = rule->getLookahead();
|
||||
followSet->insert(followSet->end(), symbolFirstSet->begin(), symbolFirstSet->end());
|
||||
}
|
||||
std::vector<Symbol*>* followSetReturn = new std::vector<Symbol*>();
|
||||
for (std::vector<Symbol*>::size_type i = 0; i < followSet->size(); i++) {
|
||||
std::vector<Symbol>* followSetReturn = new std::vector<Symbol>();
|
||||
for (std::vector<Symbol>::size_type i = 0; i < followSet->size(); i++) {
|
||||
bool alreadyIn = false;
|
||||
for (std::vector<Symbol*>::size_type j = 0; j < followSetReturn->size(); j++)
|
||||
if (*((*followSet)[i]) == *((*followSetReturn)[j])) {
|
||||
for (std::vector<Symbol>::size_type j = 0; j < followSetReturn->size(); j++)
|
||||
if ((*followSet)[i] == (*followSetReturn)[j]) {
|
||||
alreadyIn = true;
|
||||
break;
|
||||
}
|
||||
@@ -216,7 +212,7 @@ void Parser::closure(State* state) {
|
||||
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
|
||||
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;
|
||||
//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;
|
||||
@@ -259,7 +255,7 @@ void Parser::addStates(std::vector< State* >* stateSets, State* state, std::queu
|
||||
//If not, create it.
|
||||
bool symbolAlreadyInState = false;
|
||||
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;
|
||||
//So now check to see if this exact rule is in this state
|
||||
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
|
||||
//See if reduce
|
||||
//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()) {
|
||||
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]));
|
||||
} 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)
|
||||
ParseRule* nullRule = (*currStateTotal)[i]->clone();
|
||||
nullRule->setRightSide(* new std::vector<Symbol*>());
|
||||
for (std::vector<Symbol*>::size_type j = 0; j < lookahead->size(); j++)
|
||||
nullRule->setRightSide(* new std::vector<Symbol>());
|
||||
for (std::vector<Symbol>::size_type j = 0; j < lookahead->size(); j++)
|
||||
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.
|
||||
bool stateAlreadyInAllStates = false;
|
||||
Symbol* currStateSymbol;
|
||||
Symbol currStateSymbol;
|
||||
for (std::vector< State * >::size_type i = 0; i < newStates.size(); i++) {
|
||||
stateAlreadyInAllStates = false;
|
||||
currStateSymbol = (*(newStates[i]->getBasis()))[0]->getAtIndex();
|
||||
@@ -327,13 +323,13 @@ std::string Parser::tableToString() {
|
||||
|
||||
//parseInput is now pure virtual
|
||||
|
||||
NodeTree<Symbol*>* Parser::reduceTreeCombine(Symbol* newSymbol, std::vector<Symbol*> &symbols) {
|
||||
NodeTree<Symbol*>* newTree = new NodeTree<Symbol*>(newSymbol->getName(), newSymbol);
|
||||
for (std::vector<Symbol*>::size_type i = 0; i < symbols.size(); i++) {
|
||||
if (symbols[i]->isTerminal())
|
||||
newTree->addChild(new NodeTree<Symbol*>(symbols[i]->getName(), symbols[i]));
|
||||
NodeTree<Symbol>* Parser::reduceTreeCombine(Symbol newSymbol, std::vector<Symbol> &symbols) {
|
||||
NodeTree<Symbol>* newTree = new NodeTree<Symbol>(newSymbol.getName(), newSymbol);
|
||||
for (std::vector<Symbol>::size_type i = 0; i < symbols.size(); i++) {
|
||||
if (symbols[i].isTerminal())
|
||||
newTree->addChild(new NodeTree<Symbol>(symbols[i].getName(), symbols[i]));
|
||||
else
|
||||
newTree->addChild(symbols[i]->getSubTree());
|
||||
newTree->addChild(symbols[i].getSubTree());
|
||||
}
|
||||
return(newTree);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ RNGLRParser::~RNGLRParser() {
|
||||
//
|
||||
}
|
||||
|
||||
NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
|
||||
NodeTree<Symbol>* RNGLRParser::parseInput(std::string inputString) {
|
||||
|
||||
//Check for no tokens
|
||||
bool accepting = false;
|
||||
@@ -24,23 +24,17 @@ NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
|
||||
} else {
|
||||
std::cout << "Rejected, no input (with no accepting state)" << std::endl;
|
||||
}
|
||||
return new NodeTree<Symbol*>();
|
||||
return new NodeTree<Symbol>();
|
||||
}
|
||||
|
||||
lexer.setInput(inputString);
|
||||
//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.
|
||||
Symbol* currentToken = lexer.next();
|
||||
Symbol currentToken = lexer.next();
|
||||
input.push_back(currentToken);
|
||||
while (*currentToken != *EOFSymbol) {
|
||||
//std::cout << EOFSymbol->toString() << " " << currentToken->toString() << std::endl;
|
||||
while (currentToken != EOFSymbol) {
|
||||
currentToken = lexer.next();
|
||||
if (currentToken != NULL) {
|
||||
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;
|
||||
@@ -78,11 +72,11 @@ NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
|
||||
// std::cout << "Checking if frontier " << i << " is empty" << std::endl;
|
||||
if (gss.frontierIsEmpty(i)) {
|
||||
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;
|
||||
int range = 5;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
@@ -124,7 +118,7 @@ void RNGLRParser::reducer(int i) {
|
||||
std::vector<NodeTree<int>*> currentPath = (*paths)[j];
|
||||
|
||||
//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());
|
||||
//If the reduction length is 0, label as passed in is null
|
||||
if (reduction.length != 0)
|
||||
@@ -132,24 +126,24 @@ void RNGLRParser::reducer(int i) {
|
||||
//The end of the current path
|
||||
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;
|
||||
|
||||
//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) {
|
||||
newLabel = reduction.nullableParts;
|
||||
} else {
|
||||
//Otherwise, we create the new label if we haven't already
|
||||
int reachedFrontier = gss.getContainingFrontier(currentReached);
|
||||
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)) {
|
||||
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) {
|
||||
newLabel = SPPFStepNodes[k].first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -198,7 +192,7 @@ void RNGLRParser::reducer(int i) {
|
||||
void RNGLRParser::shifter(int i) {
|
||||
if (i != input.size()-1) {
|
||||
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()) {
|
||||
std::pair<NodeTree<int>*, int> shift = toShift.front();
|
||||
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)
|
||||
children->push_back(nullableParts);
|
||||
|
||||
@@ -248,14 +242,14 @@ void RNGLRParser::addChildren(NodeTree<Symbol*>* parent, std::vector<NodeTree<Sy
|
||||
parent->addChildren(children);
|
||||
} else {
|
||||
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);
|
||||
std::vector<NodeTree<Symbol*>*> tmp = parent->getChildren();
|
||||
std::vector<NodeTree<Symbol>*> tmp = parent->getChildren();
|
||||
subParent->addChildren(&tmp);
|
||||
parent->clearChildren();
|
||||
parent->addChild(subParent);
|
||||
}
|
||||
NodeTree<Symbol*>* t = new NodeTree<Symbol*>("AmbiguityPackOuter", NULL);
|
||||
NodeTree<Symbol>* t = new NodeTree<Symbol>("AmbiguityPackOuter", Symbol("AmbiguityPackInner", true));
|
||||
setPacked(t, true);
|
||||
parent->addChild(t);
|
||||
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::vector<NodeTree<Symbol*>*> children = node->getChildren();
|
||||
for (std::vector<NodeTree<Symbol*>*>::size_type i = 0; i < nodes->size(); i++) {
|
||||
std::vector<NodeTree<Symbol>*> children = node->getChildren();
|
||||
for (std::vector<NodeTree<Symbol>*>::size_type i = 0; i < nodes->size(); i++) {
|
||||
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
|
||||
if ((*nodes)[i] == children[j] || ( (*nodes)[i] != NULL && children[j] != NULL && (*(*nodes)[i]) == *(children[j]) )) {
|
||||
containsOne = true;
|
||||
@@ -282,18 +276,18 @@ bool RNGLRParser::belongsToFamily(NodeTree<Symbol*>* node, std::vector<NodeTree<
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RNGLRParser::arePacked(std::vector<NodeTree<Symbol*>*> nodes) {
|
||||
bool RNGLRParser::arePacked(std::vector<NodeTree<Symbol>*> nodes) {
|
||||
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])];
|
||||
return packed;
|
||||
}
|
||||
|
||||
bool RNGLRParser::isPacked(NodeTree<Symbol*>* node) {
|
||||
bool RNGLRParser::isPacked(NodeTree<Symbol>* node) {
|
||||
return packedMap[*node];
|
||||
}
|
||||
|
||||
void RNGLRParser::setPacked(NodeTree<Symbol*>* node, bool isPacked) {
|
||||
void RNGLRParser::setPacked(NodeTree<Symbol>* node, bool isPacked) {
|
||||
packedMap[*node] = isPacked;
|
||||
}
|
||||
|
||||
@@ -315,7 +309,7 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state, std:
|
||||
//If not, create it.
|
||||
bool symbolAlreadyInState = false;
|
||||
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;
|
||||
//Add rule to state, combining with idenical rule except lookahead if exists
|
||||
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.
|
||||
bool stateAlreadyInAllStates = false;
|
||||
Symbol* currStateSymbol;
|
||||
Symbol currStateSymbol;
|
||||
for (std::vector< State * >::size_type i = 0; i < newStates.size(); i++) {
|
||||
stateAlreadyInAllStates = false;
|
||||
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++) {
|
||||
//See if reduce
|
||||
//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()) {
|
||||
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]));
|
||||
//If this has an appropriate ruduction to null, get the reduce trees out
|
||||
} 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
|
||||
//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
|
||||
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]));
|
||||
}
|
||||
}
|
||||
@@ -388,33 +382,33 @@ bool RNGLRParser::fullyReducesToNull(ParseRule* rule) {
|
||||
}
|
||||
|
||||
bool RNGLRParser::reducesToNull(ParseRule* rule) {
|
||||
std::vector<Symbol*> avoidList;
|
||||
std::vector<Symbol> 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 (rule->isAtEnd() && rule->getRightSize() != 0)
|
||||
return false;
|
||||
|
||||
for (std::vector<Symbol*>::size_type i = 0; i < avoidList.size(); i++)
|
||||
if (*(rule->getLeftSide()) == *(avoidList[i]))
|
||||
for (std::vector<Symbol>::size_type i = 0; i < avoidList.size(); i++)
|
||||
if (rule->getLeftSide() == avoidList[i])
|
||||
return false;
|
||||
|
||||
avoidList.push_back(rule->getLeftSide());
|
||||
|
||||
std::vector<Symbol*> rightSide = rule->getRightSide();
|
||||
std::vector<Symbol> rightSide = rule->getRightSide();
|
||||
bool reduces = true;
|
||||
for (std::vector<Symbol*>::size_type i = rule->getIndex(); i < rightSide.size(); i++) {
|
||||
if (*rightSide[i] == *nullSymbol)
|
||||
for (std::vector<Symbol>::size_type i = rule->getIndex(); i < rightSide.size(); i++) {
|
||||
if (rightSide[i] == nullSymbol)
|
||||
continue;
|
||||
if (rightSide[i]->isTerminal()) {
|
||||
if (rightSide[i].isTerminal()) {
|
||||
reduces = false;
|
||||
break;
|
||||
}
|
||||
bool subSymbolReduces = false;
|
||||
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)) {
|
||||
subSymbolReduces = true;
|
||||
break;
|
||||
@@ -429,32 +423,32 @@ bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector<Symbol*> avoidList)
|
||||
return reduces;
|
||||
}
|
||||
|
||||
NodeTree<Symbol*>* RNGLRParser::getNullableParts(ParseRule* rule) {
|
||||
return getNullableParts(rule, std::vector<NodeTree<Symbol*>*>());
|
||||
NodeTree<Symbol>* RNGLRParser::getNullableParts(ParseRule* rule) {
|
||||
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)) {
|
||||
//std::cout << "Reduces to null so adding parts " << rule->toString() << std::endl;
|
||||
Symbol* symbol = rule->getLeftSide();
|
||||
NodeTree<Symbol*>* symbolNode = new NodeTree<Symbol*>(symbol->getName(), symbol);
|
||||
if (*(rule->getAtNextIndex()) == *nullSymbol) {
|
||||
symbolNode->addChild(new NodeTree<Symbol*>(nullSymbol->getName(), nullSymbol));
|
||||
Symbol symbol = rule->getLeftSide();
|
||||
NodeTree<Symbol>* symbolNode = new NodeTree<Symbol>(symbol.getName(), symbol);
|
||||
if (rule->getAtNextIndex() == nullSymbol) {
|
||||
symbolNode->addChild(new NodeTree<Symbol>(nullSymbol.getName(), nullSymbol));
|
||||
} else {
|
||||
//Find recursively
|
||||
ParseRule* iterate = rule->clone();
|
||||
while (!iterate->isAtEnd()) {
|
||||
//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++) {
|
||||
if (*(iterate->getAtNextIndex()) == *(avoidList[i]->getData())) {
|
||||
for (std::vector<NodeTree<Symbol>*>::size_type i = 0; i < avoidList.size(); i++) {
|
||||
if (iterate->getAtNextIndex() == avoidList[i]->getData()) {
|
||||
symbolNode->addChild(avoidList[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//We haven't so do it recursively
|
||||
for (std::vector<ParseRule*>::size_type i = 0; i < loadedGrammer.size(); i++) {
|
||||
if (fullyReducesToNull(loadedGrammer[i]) && *(iterate->getAtNextIndex()) == *(loadedGrammer[i]->getLeftSide())) {
|
||||
NodeTree<Symbol*>* symbolTree = getNullableParts(loadedGrammer[i], avoidList);
|
||||
if (fullyReducesToNull(loadedGrammer[i]) && iterate->getAtNextIndex() == loadedGrammer[i]->getLeftSide()) {
|
||||
NodeTree<Symbol>* symbolTree = getNullableParts(loadedGrammer[i], avoidList);
|
||||
avoidList.push_back(symbolTree);
|
||||
symbolNode->addChild(symbolTree);
|
||||
}
|
||||
@@ -467,12 +461,12 @@ NodeTree<Symbol*>* RNGLRParser::getNullableParts(ParseRule* rule, std::vector<No
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NodeTree<Symbol*>* RNGLRParser::getNullableParts(Symbol* symbol) {
|
||||
return new NodeTree<Symbol*>("CRAZY_SYMBOL", nullSymbol);
|
||||
NodeTree<Symbol>* RNGLRParser::getNullableParts(Symbol symbol) {
|
||||
return new NodeTree<Symbol>("CRAZY_SYMBOL", nullSymbol);
|
||||
}
|
||||
|
||||
std::vector<NodeTree<Symbol*>*> RNGLRParser::getPathEdges(std::vector<NodeTree<int>*> path) {
|
||||
std::vector<NodeTree<Symbol*>*> pathEdges;
|
||||
std::vector<NodeTree<Symbol>*> RNGLRParser::getPathEdges(std::vector<NodeTree<int>*> path) {
|
||||
std::vector<NodeTree<Symbol>*> pathEdges;
|
||||
for (std::vector<NodeTree<int>*>::size_type i = 0; i < path.size()-1; i++)
|
||||
pathEdges.push_back(gss.getEdge(path[i], path[i+1]));
|
||||
return pathEdges;
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
#include "Symbol.h"
|
||||
|
||||
Symbol::Symbol() {
|
||||
this->name = "UninitlizedSymbol";
|
||||
this->terminal = false;
|
||||
this->subTree = NULL;
|
||||
value = "NoValue";
|
||||
}
|
||||
|
||||
Symbol::Symbol(std::string name, bool isTerminal) {
|
||||
this->name = name;
|
||||
this->terminal = isTerminal;
|
||||
@@ -14,7 +21,7 @@ Symbol::Symbol(std::string name, bool isTerminal, std::string 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->terminal = isTerminal;
|
||||
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);
|
||||
}
|
||||
|
||||
const bool Symbol::operator!=(const Symbol &other) {
|
||||
const bool Symbol::operator!=(const Symbol &other) const {
|
||||
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);
|
||||
}
|
||||
|
||||
std::string Symbol::toString() {
|
||||
std::string Symbol::toString() const {
|
||||
return(name + (terminal ? " " + value : ""));
|
||||
}
|
||||
|
||||
Symbol* Symbol::clone() {
|
||||
return new Symbol(name, terminal, subTree);
|
||||
}
|
||||
|
||||
void Symbol::setSubTree(NodeTree<Symbol*>* tree) {
|
||||
void Symbol::setSubTree(NodeTree<Symbol>* tree) {
|
||||
subTree = tree;
|
||||
}
|
||||
|
||||
NodeTree<Symbol*>* Symbol::getSubTree() {
|
||||
NodeTree<Symbol>* Symbol::getSubTree() {
|
||||
return subTree;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@ Table::~Table() {
|
||||
//
|
||||
}
|
||||
|
||||
void Table::setSymbols(Symbol* EOFSymbol, Symbol* nullSymbol) {
|
||||
void Table::setSymbols(Symbol EOFSymbol, Symbol nullSymbol) {
|
||||
this->EOFSymbol = EOFSymbol;
|
||||
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 (symbolIndexVec.size() == 0)
|
||||
@@ -28,8 +28,8 @@ void Table::add(int stateNum, Symbol* tranSymbol, ParseAction* action) {
|
||||
|
||||
//find out what index this symbol is on
|
||||
int symbolIndex = -1;
|
||||
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) {
|
||||
if ( *(symbolIndexVec[i]) == *tranSymbol ) {
|
||||
for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++) {
|
||||
if ( symbolIndexVec[i] == tranSymbol ) {
|
||||
//Has been found
|
||||
symbolIndex = i;
|
||||
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
|
||||
int symbolIndex = -1;
|
||||
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) {
|
||||
if ( *(symbolIndexVec[i]) == *tranSymbol ) {
|
||||
for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++) {
|
||||
if ( symbolIndexVec[i] == tranSymbol ) {
|
||||
//Has been found
|
||||
symbolIndex = i;
|
||||
break;
|
||||
@@ -92,21 +92,21 @@ void Table::remove(int stateNum, Symbol* tranSymbol) {
|
||||
(*(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;
|
||||
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++) {
|
||||
if ( *(symbolIndexVec[i]) == *token) {
|
||||
for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++) {
|
||||
if ( symbolIndexVec[i] == token) {
|
||||
symbolIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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()) {
|
||||
std::cout << "State bad: " << state << std::endl;
|
||||
return NULL;
|
||||
@@ -115,7 +115,7 @@ std::vector<ParseAction*>* Table::get(int state, Symbol* token) {
|
||||
std::vector<ParseAction*>* action = NULL;
|
||||
|
||||
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 {
|
||||
action = (*(table[state]))[symbolIndex];
|
||||
}
|
||||
@@ -144,7 +144,7 @@ std::vector<ParseAction*>* Table::get(int state, Symbol* token) {
|
||||
return (action);
|
||||
}
|
||||
|
||||
ParseAction* Table::getShift(int state, Symbol* token) {
|
||||
ParseAction* Table::getShift(int state, Symbol token) {
|
||||
std::vector<ParseAction*>* actions = get(state, token);
|
||||
ParseAction* shift = NULL;
|
||||
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 concat = "";
|
||||
for (std::vector<Symbol*>::size_type i = 0; i < symbolIndexVec.size(); i++)
|
||||
concat += "\t" + symbolIndexVec[i]->toString();
|
||||
for (std::vector<Symbol>::size_type i = 0; i < symbolIndexVec.size(); i++)
|
||||
concat += "\t" + symbolIndexVec[i].toString();
|
||||
concat += "\n";
|
||||
|
||||
for (std::vector< std::vector< std::vector< ParseRule* >* >* >::size_type i = 0; i < table.size(); i++) {
|
||||
|
||||
Reference in New Issue
Block a user