Implemented grammer loading
This commit is contained in:
@@ -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/NodeTree.cpp )
|
set( MY_SOURCES main.cpp src/Parser.cpp src/ParseRule.cpp src/Symbol.cpp src/StringReader.cpp src/NodeTree.cpp src/Parser.cpp )
|
||||||
|
|
||||||
include_directories( ${MY_INCLUDES} )
|
include_directories( ${MY_INCLUDES} )
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#ifndef NULL
|
#ifndef NULL
|
||||||
#define NULL 0
|
#define NULL 0
|
||||||
#endif NULL
|
#endif
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -37,4 +37,4 @@ class NodeTree {
|
|||||||
std::vector<NodeTree*> children;
|
std::vector<NodeTree*> children;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //NODETREE_H
|
#endif
|
||||||
31
include/ParseRule.h
Normal file
31
include/ParseRule.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef PARSERULE_H
|
||||||
|
#define PARSERULE_H
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Symbol.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class ParseRule {
|
||||||
|
public:
|
||||||
|
ParseRule();
|
||||||
|
~ParseRule();
|
||||||
|
|
||||||
|
void setLeftHandle(Symbol* leftHandle);
|
||||||
|
void appendToRight(Symbol* appendee);
|
||||||
|
|
||||||
|
std::string toString();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int pointerIndex;
|
||||||
|
Symbol* leftHandle;
|
||||||
|
std::vector<Symbol*> rightSide;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
32
include/Parser.h
Normal file
32
include/Parser.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef PARSER_H
|
||||||
|
#define PARSER_H
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ParseRule.h"
|
||||||
|
#include "Symbol.h"
|
||||||
|
#include "StringReader.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class Parser {
|
||||||
|
public:
|
||||||
|
Parser();
|
||||||
|
~Parser();
|
||||||
|
|
||||||
|
void loadGrammer(std::string grammerInputString);
|
||||||
|
std::string grammerToString();
|
||||||
|
private:
|
||||||
|
StringReader reader;
|
||||||
|
std::map<std::string, Symbol*> symbols;
|
||||||
|
std::vector<ParseRule*> loadedGrammer;
|
||||||
|
|
||||||
|
Symbol* getOrAddSymbol(std::string symbolString, bool isTerminal);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
26
include/StringReader.h
Normal file
26
include/StringReader.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef StringReader_H
|
||||||
|
#define StringReader_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class StringReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StringReader();
|
||||||
|
StringReader(std::string inputString);
|
||||||
|
virtual ~StringReader();
|
||||||
|
void setString(std::string inputString);
|
||||||
|
std::string word(bool truncateEnd = true);
|
||||||
|
std::string line(bool truncateEnd = true);
|
||||||
|
std::string getTokens(std::vector<std::string> get_chars, bool truncateEnd = true);
|
||||||
|
std::string truncateEnd(std::string to_truncate);
|
||||||
|
protected:
|
||||||
|
private:
|
||||||
|
std::string rd_string;
|
||||||
|
int str_pos;
|
||||||
|
bool end_reached;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
23
include/Symbol.h
Normal file
23
include/Symbol.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef SYMBOL_H
|
||||||
|
#define SYMBOL_H
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Symbol {
|
||||||
|
public:
|
||||||
|
Symbol(std::string name, bool isTerminal);
|
||||||
|
~Symbol();
|
||||||
|
std::string toString();
|
||||||
|
private:
|
||||||
|
std::string name;
|
||||||
|
bool isTerminal;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
19
main.cpp
19
main.cpp
@@ -1,4 +1,5 @@
|
|||||||
#include "NodeTree.h"
|
#include "NodeTree.h"
|
||||||
|
#include "Parser.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -27,7 +28,23 @@ int main(int argc, char* argv[]) {
|
|||||||
root.addChild(new NodeTree("SomeOtherChild"));
|
root.addChild(new NodeTree("SomeOtherChild"));
|
||||||
root.get(0)->addChild(new NodeTree("Grandchildren"));
|
root.get(0)->addChild(new NodeTree("Grandchildren"));
|
||||||
|
|
||||||
outFile << root.DOTGraphString() << std::endl;
|
//outFile << root.DOTGraphString() << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
//Read the input file into a string
|
||||||
|
std::string inputFileString;
|
||||||
|
std::string line;
|
||||||
|
while(inFile.good()) {
|
||||||
|
getline(inFile, line);
|
||||||
|
inputFileString.append(line+"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser parser;
|
||||||
|
parser.loadGrammer(inputFileString);
|
||||||
|
std::cout << inputFileString << std::endl;
|
||||||
|
std::cout << parser.grammerToString();
|
||||||
|
|
||||||
|
outFile << "digraph Kraken { \n" + parser.grammerToString() + "\n}" << std::endl;
|
||||||
|
|
||||||
inFile.close();
|
inFile.close();
|
||||||
outFile.close();
|
outFile.close();
|
||||||
|
|||||||
27
src/ParseRule.cpp
Normal file
27
src/ParseRule.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#include "ParseRule.h"
|
||||||
|
|
||||||
|
ParseRule::ParseRule() {
|
||||||
|
pointerIndex = 0;
|
||||||
|
leftHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseRule::~ParseRule() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseRule::setLeftHandle(Symbol* leftHandle) {
|
||||||
|
this->leftHandle = leftHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseRule::appendToRight(Symbol* appendee) {
|
||||||
|
rightSide.push_back(appendee);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ParseRule::toString() {
|
||||||
|
std::string concat = leftHandle->toString() + " -> ";
|
||||||
|
for (int i = 0; i < rightSide.size(); i++) {
|
||||||
|
concat += rightSide[i]->toString() + " ";
|
||||||
|
}
|
||||||
|
return(concat + ";");
|
||||||
|
}
|
||||||
|
|
||||||
64
src/Parser.cpp
Normal file
64
src/Parser.cpp
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#include "Parser.h"
|
||||||
|
|
||||||
|
Parser::Parser() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::~Parser() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Symbol* Parser::getOrAddSymbol(std::string symbolString, bool isTerminal) {
|
||||||
|
Symbol* symbol;
|
||||||
|
if (symbols.find(symbolString) == symbols.end()) {
|
||||||
|
symbol = new Symbol(symbolString, isTerminal);
|
||||||
|
symbols[symbolString] = symbol;
|
||||||
|
} else {
|
||||||
|
symbol = symbols[symbolString];
|
||||||
|
}
|
||||||
|
return(symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parser::loadGrammer(std::string grammerInputString) {
|
||||||
|
reader.setString(grammerInputString);
|
||||||
|
|
||||||
|
std::string currToken = reader.word();
|
||||||
|
|
||||||
|
while(currToken != "") {
|
||||||
|
//Load the left of the rule
|
||||||
|
ParseRule* currentRule = new ParseRule();
|
||||||
|
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.
|
||||||
|
currToken = reader.word();
|
||||||
|
while (currToken != ";") {
|
||||||
|
currentRule->appendToRight(getOrAddSymbol(currToken, currToken.at(0)=='\"')); //If first character is a ", then is a terminal
|
||||||
|
currToken = reader.word();
|
||||||
|
//If there are multiple endings to this rule, finish this rule and start a new one with same left handle
|
||||||
|
if (currToken == "|") {
|
||||||
|
loadedGrammer.push_back(currentRule);
|
||||||
|
currentRule = new ParseRule();
|
||||||
|
currentRule->setLeftHandle(leftSide);
|
||||||
|
currToken = reader.word();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Add new rule to grammer
|
||||||
|
loadedGrammer.push_back(currentRule);
|
||||||
|
//Get next token
|
||||||
|
currToken = reader.word();
|
||||||
|
}
|
||||||
|
std::cout << "Parsed!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Parser::grammerToString() {
|
||||||
|
//Iterate through the vector, adding string representation of each grammer rule
|
||||||
|
std::cout << "About to toString\n";
|
||||||
|
std::string concat = "";
|
||||||
|
for (int i = 0; i < loadedGrammer.size(); i++) {
|
||||||
|
concat += loadedGrammer[i]->toString() + "\n";//->toString();// + std::endl;
|
||||||
|
}
|
||||||
|
return(concat);
|
||||||
|
}
|
||||||
|
|
||||||
103
src/StringReader.cpp
Normal file
103
src/StringReader.cpp
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#include "StringReader.h"
|
||||||
|
|
||||||
|
StringReader::StringReader()
|
||||||
|
{
|
||||||
|
str_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringReader::StringReader(std::string inputString)
|
||||||
|
{
|
||||||
|
str_pos = 0;
|
||||||
|
setString(inputString);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringReader::~StringReader()
|
||||||
|
{
|
||||||
|
//dtor
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringReader::setString(std::string inputString)
|
||||||
|
{
|
||||||
|
rd_string = inputString;
|
||||||
|
end_reached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string StringReader::word(bool truncateEnd)
|
||||||
|
{
|
||||||
|
std::vector<std::string> stop_chars;
|
||||||
|
stop_chars.push_back(" ");
|
||||||
|
stop_chars.push_back("\n");
|
||||||
|
stop_chars.push_back("\t");
|
||||||
|
|
||||||
|
|
||||||
|
std::string result = getTokens(stop_chars, truncateEnd);
|
||||||
|
while (result == " " || result == "\n" || result == "\t")
|
||||||
|
{
|
||||||
|
result = getTokens(stop_chars, truncateEnd);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string StringReader::line(bool truncateEnd)
|
||||||
|
{
|
||||||
|
std::vector<std::string> stop_chars;
|
||||||
|
stop_chars.push_back("\n");
|
||||||
|
return getTokens(stop_chars, truncateEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string StringReader::getTokens(std::vector<std::string> stop_chars, bool truncateEnd)
|
||||||
|
{
|
||||||
|
int found_pos, new_found_pos;
|
||||||
|
std::string stop_char;
|
||||||
|
|
||||||
|
found_pos = rd_string.find(stop_chars[0], str_pos);
|
||||||
|
stop_char = stop_chars[0];
|
||||||
|
|
||||||
|
for (unsigned int i = 1; i < stop_chars.size(); i++)
|
||||||
|
{
|
||||||
|
new_found_pos = rd_string.find(stop_chars[i], str_pos);
|
||||||
|
|
||||||
|
//Ok, if the position we found is closer than what we have and is not the end of file, OR the position we are at is the end of file
|
||||||
|
//assign the new found position to the currrent found position
|
||||||
|
if ( ((new_found_pos <= found_pos) && (new_found_pos != std::string::npos)) || found_pos == std::string::npos )
|
||||||
|
{
|
||||||
|
found_pos = new_found_pos;
|
||||||
|
stop_char = stop_chars[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_pos == str_pos) //We are at the endline
|
||||||
|
{
|
||||||
|
str_pos++;
|
||||||
|
return stop_char;
|
||||||
|
} else if (found_pos == std::string::npos) //We are at the end of the file
|
||||||
|
{
|
||||||
|
//End of String
|
||||||
|
end_reached = true;
|
||||||
|
std::cout << "Reached end of file!\n";
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
|
||||||
|
std::string string_section;
|
||||||
|
|
||||||
|
if (truncateEnd) //If we want to get rid of the delimiting character, which is the default, don't add the last char. Note we have to increase str_pos by one manually later
|
||||||
|
found_pos -= 1;
|
||||||
|
|
||||||
|
for (; str_pos <= found_pos; str_pos++)
|
||||||
|
{
|
||||||
|
string_section += rd_string[str_pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (truncateEnd) //Ok, we didn't add the last char, but str_pos now points at that char. So we move it one ahead.
|
||||||
|
str_pos++;
|
||||||
|
return string_section;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string StringReader::truncateEnd(std::string to_truncate)
|
||||||
|
{
|
||||||
|
std::string to_return = "";
|
||||||
|
for (unsigned int i = 0; i < to_truncate.length()-1; i++)
|
||||||
|
to_return = to_return + to_truncate[i];
|
||||||
|
return to_return;
|
||||||
|
}
|
||||||
15
src/Symbol.cpp
Normal file
15
src/Symbol.cpp
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include "Symbol.h"
|
||||||
|
|
||||||
|
Symbol::Symbol(std::string name, bool isTerminal) {
|
||||||
|
this->name = name;
|
||||||
|
this->isTerminal = isTerminal;
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol::~Symbol() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Symbol::toString() {
|
||||||
|
return(name);
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user