From 15674fec2a15bd3fa0764ce5d8d0d4720a9d5ed7 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Mon, 23 Dec 2013 01:26:24 -0600 Subject: [PATCH] Added Type class, bettered types a bit, made address of and dereference operators work. --- CMakeLists.txt | 2 +- include/ASTData.h | 12 +++---- include/CGenerator.h | 3 +- include/Type.h | 29 ++++++++++++++++ krakenGrammer.kgm | 5 +-- main.cpp | 62 +++++++++++++++++---------------- src/ASTData.cpp | 43 ++--------------------- src/ASTTransformation.cpp | 46 +++++++++++++++++------- src/CGenerator.cpp | 38 +++++++++++++------- src/Type.cpp | 73 +++++++++++++++++++++++++++++++++++++++ 10 files changed, 207 insertions(+), 106 deletions(-) create mode 100644 include/Type.h create mode 100644 src/Type.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4083ad4..e0fcec1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 src/ASTData.cpp src/ASTTransformation.cpp src/CGenerator.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 src/CGenerator.cpp src/Type.cpp ) include_directories( ${MY_INCLUDES} ) diff --git a/include/ASTData.h b/include/ASTData.h index 593c84b..e511b98 100644 --- a/include/ASTData.h +++ b/include/ASTData.h @@ -3,7 +3,9 @@ #include #include + #include "Symbol.h" +#include "Type.h" #ifndef NULL #define NULL 0 @@ -14,21 +16,17 @@ enum ASTType {undef, translation_unit, interpreter_directive, import, identifier typed_parameter, expression, boolean_expression, statement, if_statement, while_loop, for_loop, return_statement, assignment_statement, declaration_statement, if_comp, simple_passthrough, function_call, value}; -enum ValueType {none, void_type, boolean, integer, floating, double_percision, char_string }; - class ASTData { public: ASTData(); - ASTData(ASTType type, ValueType valueType = none); - ASTData(ASTType type, Symbol symbol, ValueType valueType = none); + ASTData(ASTType type, Type valueType = Type()); + ASTData(ASTType type, Symbol symbol, Type valueType = Type()); ~ASTData(); std::string toString(); static std::string ASTTypeToString(ASTType type); - static std::string ValueTypeToString(ValueType type); - static ValueType strToType(std::string type); ASTType type; - ValueType valueType; + Type valueType; Symbol symbol; private: diff --git a/include/CGenerator.h b/include/CGenerator.h index b819f77..35d26a7 100644 --- a/include/CGenerator.h +++ b/include/CGenerator.h @@ -6,6 +6,7 @@ #include "NodeTree.h" #include "ASTData.h" +#include "Type.h" #include "util.h" @@ -15,7 +16,7 @@ class CGenerator { CGenerator(); ~CGenerator(); std::string generate(NodeTree* from); - static std::string ValueTypeToCType(ValueType type); + static std::string ValueTypeToCType(Type type); std::string generatorString; private: std::string tabs(); diff --git a/include/Type.h b/include/Type.h new file mode 100644 index 0000000..4727f49 --- /dev/null +++ b/include/Type.h @@ -0,0 +1,29 @@ +#ifndef TYPE_H +#define TYPE_H + +#ifndef NULL +#define NULL 0 +#endif + +#include +#include + +#include "util.h" + +enum ValueType {none, void_type, boolean, integer, floating, double_percision, character }; + + +class Type { + public: + Type(); + Type(ValueType typeIn, int indirectionIn); + Type(ValueType typeIn); + Type(std::string typeIn); + ~Type(); + std::string toString(); + ValueType baseType; + int indirection; + private: +}; + +#endif \ No newline at end of file diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index bb027b5..419e345 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -28,7 +28,7 @@ function = type WS identifier WS "\(" WS opt_typed_parameter_list WS "\)" WS cod opt_typed_parameter_list = typed_parameter_list | ; typed_parameter_list = typed_parameter_list WS "," WS typed_parameter | typed_parameter ; -typed_parameter = type WS parameter ; +typed_parameter = type WS identifier ; opt_parameter_list = parameter_list | ; parameter_list = parameter_list WS "," WS parameter | parameter ; @@ -58,7 +58,7 @@ expression = expression WS "<<" WS term | expression WS ">>" WS shiftand | shift shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ; term = term WS forward_slash WS factor | term WS "\*" WS factor | term WS "%" WS factor | factor ; factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\(" WS type WS "\)" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ; -unarad = number | identifier | function_call | bool | string | "\(" WS boolean_expression WS "\)" ; +unarad = number | identifier | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" ; number = integer | float | double ; assignment_statement = identifier WS "=" WS boolean_expression | identifier WS "\+=" WS boolean_expression | identifier WS "-=" WS boolean_expression | identifier WS "\*=" WS boolean_expression | identifier WS "/=" WS boolean_expression ; @@ -71,6 +71,7 @@ integer = sign numeric | sign hexadecimal | "null" ; float = sign numeric "." numeric "f" ; double = sign numeric "." numeric | sign numeric "." numeric "d" ; bool = "true" | "false" | "True" | "False" ; +character = "'(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|.|,|!|\?|_|-|:|%| | |\\|/|\||\(|\)|0|1|2|3|4|5|6|7|8|9)'" ; alpha = "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|_)+" ; numeric = "(0|1|2|3|4|5|6|7|8|9)+" ; string = triple_quoted_string | "\"(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|.|,|!|\?|_|-|:|%| | |\\|/|\||\(|\)|0|1|2|3|4|5|6|7|8|9)+\"" ; diff --git a/main.cpp b/main.cpp index 2b1ca82..f5f9b67 100644 --- a/main.cpp +++ b/main.cpp @@ -113,37 +113,41 @@ int main(int argc, char* argv[]) { } outFile.close(); - //Pre AST Transformations - std::vector*> preASTTransforms; //Remove Transformations - preASTTransforms.push_back(new RemovalTransformation(Symbol("WS", false))); - preASTTransforms.push_back(new RemovalTransformation(Symbol("\\(", true))); - preASTTransforms.push_back(new RemovalTransformation(Symbol("\\)", true))); - preASTTransforms.push_back(new RemovalTransformation(Symbol("::", true))); - preASTTransforms.push_back(new RemovalTransformation(Symbol(";", true))); - preASTTransforms.push_back(new RemovalTransformation(Symbol("{", true))); - preASTTransforms.push_back(new RemovalTransformation(Symbol("}", true))); - preASTTransforms.push_back(new RemovalTransformation(Symbol("(", true))); - preASTTransforms.push_back(new RemovalTransformation(Symbol(")", true))); - preASTTransforms.push_back(new RemovalTransformation(Symbol("import", true))); //Don't need the actual text of the symbol - preASTTransforms.push_back(new RemovalTransformation(Symbol("interpreter_directive", false))); - preASTTransforms.push_back(new RemovalTransformation(Symbol("if", true))); - preASTTransforms.push_back(new RemovalTransformation(Symbol("while", true))); - //Collapse Transformations - preASTTransforms.push_back(new CollapseTransformation(Symbol("opt_typed_parameter_list", false))); - preASTTransforms.push_back(new CollapseTransformation(Symbol("opt_parameter_list", false))); - preASTTransforms.push_back(new CollapseTransformation(Symbol("opt_import_list", false))); - preASTTransforms.push_back(new CollapseTransformation(Symbol("import_list", false))); - preASTTransforms.push_back(new CollapseTransformation(Symbol("statement_list", false))); - preASTTransforms.push_back(new CollapseTransformation(Symbol("parameter_list", false))); - preASTTransforms.push_back(new CollapseTransformation(Symbol("typed_parameter_list", false))); - preASTTransforms.push_back(new CollapseTransformation(Symbol("unorderd_list_part", false))); - preASTTransforms.push_back(new CollapseTransformation(Symbol("if_comp_pred", false))); + std::vector removeSymbols; + removeSymbols.push_back(Symbol("WS", false)); + removeSymbols.push_back(Symbol("\\(", true)); + removeSymbols.push_back(Symbol("\\)", true)); + removeSymbols.push_back(Symbol("::", true)); + removeSymbols.push_back(Symbol(";", true)); + removeSymbols.push_back(Symbol("{", true)); + removeSymbols.push_back(Symbol("}", true)); + removeSymbols.push_back(Symbol("(", true)); + removeSymbols.push_back(Symbol(")", true)); + removeSymbols.push_back(Symbol("import", true)); //Don't need the actual text of the symbol + removeSymbols.push_back(Symbol("interpreter_directive", false)); + removeSymbols.push_back(Symbol("if", true)); + removeSymbols.push_back(Symbol("while", true)); + + for (int i = 0; i < removeSymbols.size(); i++) + parseTree = RemovalTransformation(removeSymbols[i]).transform(parseTree); + + //Collapse Transformations + std::vector collapseSymbols; + + collapseSymbols.push_back(Symbol("opt_typed_parameter_list", false)); + collapseSymbols.push_back(Symbol("opt_parameter_list", false)); + collapseSymbols.push_back(Symbol("opt_import_list", false)); + collapseSymbols.push_back(Symbol("import_list", false)); + collapseSymbols.push_back(Symbol("statement_list", false)); + collapseSymbols.push_back(Symbol("parameter_list", false)); + collapseSymbols.push_back(Symbol("typed_parameter_list", false)); + collapseSymbols.push_back(Symbol("unorderd_list_part", false)); + collapseSymbols.push_back(Symbol("if_comp_pred", false)); + + for (int i = 0; i < collapseSymbols.size(); i++) + parseTree = CollapseTransformation(collapseSymbols[i]).transform(parseTree); - for (int i = 0; i < preASTTransforms.size(); i++) { - parseTree = preASTTransforms[i]->transform(parseTree); - } - preASTTransforms.erase(preASTTransforms.begin(), preASTTransforms.end()); NodeTree* AST = ASTTransformation().transform(parseTree); diff --git a/src/ASTData.cpp b/src/ASTData.cpp index 5e5ee66..0d1335b 100644 --- a/src/ASTData.cpp +++ b/src/ASTData.cpp @@ -4,12 +4,12 @@ ASTData::ASTData() { this->type = undef; } -ASTData::ASTData(ASTType type, ValueType valueType) { +ASTData::ASTData(ASTType type, Type valueType) { this->type = type; this->valueType = valueType; } -ASTData::ASTData(ASTType type, Symbol symbol, ValueType valueType) { +ASTData::ASTData(ASTType type, Symbol symbol, Type valueType) { this->type = type; this->valueType = valueType; this->symbol = symbol; @@ -20,44 +20,7 @@ ASTData::~ASTData() { } std::string ASTData::toString() { - return ASTTypeToString(type) + (symbol.isTerminal() ? " " + symbol.toString() : "") + (valueType ? " " + ValueTypeToString(valueType) : ""); -} - -ValueType ASTData::strToType(std::string type) { - if (type == "void") - return void_type; - else if (type == "bool") - return boolean; - else if (type == "int") - return integer; - else if (type == "float") - return floating; - else if (type == "double") - return double_percision; - else if (type == "string") - return char_string; - else return none; -} - -std::string ASTData::ValueTypeToString(ValueType type) { - switch (type) { - case none: - return "none"; - case void_type: - return "void"; - case boolean: - return "bool"; - case integer: - return "int"; - case floating: - return "float"; - case double_percision: - return "double"; - case char_string: - return "string"; - default: - return "unknown_ValueType"; - } + return ASTTypeToString(type) + (symbol.isTerminal() ? " " + symbol.toString() : "") + " " + valueType.toString(); } std::string ASTData::ASTTypeToString(ASTType type) { diff --git a/src/ASTTransformation.cpp b/src/ASTTransformation.cpp index 52d17c0..ea22d29 100644 --- a/src/ASTTransformation.cpp +++ b/src/ASTTransformation.cpp @@ -25,14 +25,14 @@ NodeTree* ASTTransformation::transform(NodeTree* from) { } else if (name == "identifier") { newNode = new NodeTree(name, ASTData(identifier, Symbol(concatSymbolTree(children[0]), true))); } else if (name == "function") { - newNode = new NodeTree(name, ASTData(function, Symbol(concatSymbolTree(children[1]), true), ASTData::strToType(concatSymbolTree(children[0])))); + newNode = new NodeTree(name, ASTData(function, Symbol(concatSymbolTree(children[1]), true), Type(concatSymbolTree(children[0])))); skipChildren.insert(0); skipChildren.insert(1); } else if (name == "code_block") { newNode = new NodeTree(name, ASTData(code_block)); } else if (name == "typed_parameter") { newNode = transform(children[1]); //Transform to get the identifier - newNode->getDataRef()->valueType = ASTData::strToType(concatSymbolTree(children[0])); //Get the type (left child) and set our new identifer to be that type + newNode->getDataRef()->valueType = Type(concatSymbolTree(children[0])); //Get the type (left child) and set our new identifer to be that type return newNode; } else if (name == "boolean_expression") { //If this is an actual part of an expression, not just a premoted term @@ -62,16 +62,31 @@ NodeTree* ASTTransformation::transform(NodeTree* from) { return transform(children[0]); //Just a promoted bool_exp, so do child } //Here's the order of ops stuff - } else if (name == "expression" || name == "shiftand" || name == "term" || name == "factor" || name == "unarad") { + } else if (name == "expression" || name == "shiftand" || name == "term" || name == "unarad") { //unarad can ride through, it should always just be a promoted child //If this is an actual part of an expression, not just a premoted child - if (children.size() > 1) { + if (children.size() > 2) { std::string functionCallName = concatSymbolTree(children[1]); - std::cout << functionCallName << std::endl; newNode = new NodeTree(functionCallName, ASTData(function_call, Symbol(functionCallName, true))); skipChildren.insert(1); } else { return transform(children[0]); //Just a promoted child, so do it instead } + } else if (name == "factor") { //Do factor here, as it has all the weird unary operators + //If this is an actual part of an expression, not just a premoted child + //NO SUPPORT FOR CASTING YET + if (children.size() == 2) { + std::string funcName = concatSymbolTree(children[0]); + int funcNum; + if (funcName == "*" || funcName == "&" || funcName == "++" || funcName == "--" || funcName == "-" || funcName == "!" || funcName == "~") + funcNum = 0; + else + funcName = concatSymbolTree(children[1]), funcNum = 1; + + newNode = new NodeTree(funcName, ASTData(function_call, Symbol(funcName, true))); + skipChildren.insert(funcNum); + } else { + return transform(children[0]); //Just a promoted child, so do it instead + } } else if (name == "statement") { newNode = new NodeTree(name, ASTData(statement)); } else if (name == "if_statement") { @@ -101,7 +116,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from) { } else if (name == "declaration_statement") { newNode = new NodeTree(name, ASTData(declaration_statement)); NodeTree* newIdentifier = transform(children[1]); //Transform the identifier - newIdentifier->getDataRef()->valueType = ASTData::strToType(concatSymbolTree(children[0]));//set the type of the identifier + newIdentifier->getDataRef()->valueType = Type(concatSymbolTree(children[0]));//set the type of the identifier newNode->addChild(newIdentifier); skipChildren.insert(0); //These, the type and the identifier, have been taken care of. skipChildren.insert(1); @@ -116,18 +131,23 @@ NodeTree* ASTTransformation::transform(NodeTree* from) { skipChildren.insert(1); } else if (name == "parameter") { return transform(children[0]); //Don't need a parameter node, just the value - } else if (name == "bool") { - newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), boolean)); + } else if (name == "parameter") { + return transform(children[0]); //Don't need a parameter node, just the value + } else if (name == "type") { + std::string theConcat = concatSymbolTree(from); //We have no symbol, so this will concat our children + newNode = new NodeTree(name, ASTData(value, Symbol(theConcat, true), Type(theConcat))); } else if (name == "number") { return transform(children[0]); } else if (name == "integer") { - newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(from), true), integer)); + newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(from), true), Type(integer))); } else if (name == "float") { - newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(from), true), floating)); + newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(from), true), Type(floating))); } else if (name == "double") { - newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(from), true), double_percision)); + newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(from), true), Type(double_percision))); + } else if (name == "char") { + newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), Type(character))); //Indirection of 1 for array } else if (name == "string" || name == "triple_quoted_string") { - newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), char_string)); + newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), Type(character, 1))); //Indirection of 1 for array } else { return new NodeTree(); } @@ -153,7 +173,7 @@ std::string ASTTransformation::concatSymbolTree(NodeTree* root) { concatString += ourValue; std::vector*> children = root->getChildren(); for (int i = 0; i < children.size(); i++) { - concatString = concatSymbolTree(children[i]); + concatString += concatSymbolTree(children[i]); } return concatString; } diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index 2f68091..2b4645d 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -73,7 +73,7 @@ std::string CGenerator::generate(NodeTree* from) { case assignment_statement: return generate(children[0]) + " = " + generate(children[1]); case declaration_statement: - return ASTData::ValueTypeToString(children[0]->getData().valueType) + " " + generate(children[0]) + " = " + generate(children[1]); + return ValueTypeToCType(children[0]->getData().valueType) + " " + generate(children[0]) + " = " + generate(children[1]); case if_comp: if (generate(children[0]) == generatorString) return generate(children[1]); @@ -87,6 +87,8 @@ std::string CGenerator::generate(NodeTree* from) { std::string name = data.symbol.getName(); if (name == "++" || name == "--") return generate(children[0]) + name; + if (name == "*" && children.size() == 1) //Is dereference, not multiplication + return "*(" + generate(children[0]) + ")"; if (name == "+" || name == "-" || name == "*" || name == "/" || name == "==" || name == ">=" || name == "<=" || name == "!=" || name == "<" || name == ">" || name == "%" || name == "+=" || name == "-=" || name == "*=" || name == "/=") { return "((" + generate(children[0]) + ")" + name + "(" + generate(children[1]) + "))"; } @@ -110,25 +112,35 @@ std::string CGenerator::generate(NodeTree* from) { return output; } -std::string CGenerator::ValueTypeToCType(ValueType type) { - switch (type) { +std::string CGenerator::ValueTypeToCType(Type type) { + std::string return_type; + switch (type.baseType) { case none: - return "none"; + return_type = "none"; + break; case void_type: - return "void"; + return_type = "void"; + break; case boolean: - return "bool"; + return_type = "bool"; + break; case integer: - return "int"; + return_type = "int"; break; case floating: - return "float"; - case double_percision: - return "double"; + return_type = "float"; + break; + case double_percision: + return_type = "double"; + break; + case character: + return_type = "char"; break; - case char_string: - return "char*"; default: - return "unknown_ValueType"; + return_type = "unknown_ValueType"; + break; } + for (int i = 0; i < type.indirection; i++) + return_type += "*"; + return return_type; } diff --git a/src/Type.cpp b/src/Type.cpp new file mode 100644 index 0000000..f8df255 --- /dev/null +++ b/src/Type.cpp @@ -0,0 +1,73 @@ +#include "Type.h" + +Type::Type() { + indirection = 0; + baseType = none; +} + +Type::Type(ValueType typeIn) { + indirection = 0; + baseType = typeIn; +} + +Type::Type(ValueType typeIn, int indirectionIn) { + indirection = indirectionIn; + baseType = typeIn; +} + +Type::Type(std::string typeIn) { + indirection = 0; + while (typeIn[typeIn.size() - indirection - 1] == '*') indirection++; + std::string edited = strSlice(typeIn, 0, -(indirection + 1)); + if (edited == "void") + baseType = void_type; + else if (edited == "bool") + baseType = boolean; + else if (edited == "int") + baseType = integer; + else if (edited == "float") + baseType = floating; + else if (edited == "double") + baseType = double_percision; + else if (edited == "char") + baseType = character; + else + baseType = none; + std::cout << ":ALKJF:LSKDJF:SDJF:LKSJDF\t\t\t" << typeIn << "\t" << edited << std::endl; +} + + +Type::~Type() { +} + +std::string Type::toString() { + std::string typeString; + switch (baseType) { + case none: + typeString = "none"; + break; + case void_type: + typeString = "void"; + break; + case boolean: + typeString = "bool"; + break; + case integer: + typeString = "int"; + break; + case floating: + typeString = "float"; + break; + case double_percision: + typeString = "double"; + break; + case character: + typeString = "char"; + break; + default: + typeString = "unknown_type"; + } + for (int i = 0; i < indirection; i++) + typeString += "*"; + return typeString; +}