Added generator-dependent compilation and simple passthrough that allows us to have non-cheated emitted, printing c-code for the first time! (no typechecking or anything yet, but we'll get there). It's also still rough.

This commit is contained in:
Nathan Braswell
2013-12-22 01:34:59 -06:00
parent 6ad406e42d
commit 935cc6f968
9 changed files with 55 additions and 33 deletions

View File

@@ -13,8 +13,8 @@ enum ASTType {undef, translation_unit, interpreter_directive, import, identifier
function, code_block, function, code_block,
typed_parameter, expression, boolean_expression, statement, typed_parameter, expression, boolean_expression, statement,
if_statement, while_loop, for_loop, return_statement, assignment_statement, declaration_statement, if_statement, while_loop, for_loop, return_statement, assignment_statement, declaration_statement,
function_call, value}; if_comp, simple_passthrough, function_call, value};
enum ValueType {none, boolean, integer, floating, double_percision, char_string }; enum ValueType {none, void_type, boolean, integer, floating, double_percision, char_string };
class ASTData { class ASTData {

View File

@@ -16,6 +16,7 @@ class CGenerator {
~CGenerator(); ~CGenerator();
std::string generate(NodeTree<ASTData>* from); std::string generate(NodeTree<ASTData>* from);
static std::string ValueTypeToCType(ValueType type); static std::string ValueTypeToCType(ValueType type);
std::string generatorString;
private: private:
std::string tabs(); std::string tabs();
int tabLevel; int tabLevel;

View File

@@ -1,9 +1,9 @@
Goal = translation_unit ; Goal = translation_unit ;
translation_unit = interpreter_directive WS opt_import_list WS function_list WS ; translation_unit = interpreter_directive WS unorderd_list_part WS ;
unorderd_list_part = import_list WS unorderd_list_part | function WS unorderd_list_part | if_comp WS unorderd_list_part | simple_passthrough WS unorderd_list_part | import_list | function | if_comp | simple_passthrough ;
type = "\*" WS type | "void" | "int" | "float" | "double" | "char" | identifier ; type = type WS "\*" | "void" | "int" | "float" | "double" | "char" | identifier ;
opt_import_list = import_list | ;
import_list = import_list WS import | import ; import_list = import_list WS import | import ;
import = "import" WS identifier WS ";" ; import = "import" WS identifier WS ";" ;
@@ -14,12 +14,16 @@ forward_slash = "/" ;
back_slash = "\\" ; back_slash = "\\" ;
WS = "( | | WS = "( | |
)+" | ; )+" | WS comment WS | ;
if_comp = "__if_comp__" WS identifier WS if_comp_pred ;
if_comp_pred = code_block | simple_passthrough ;
simple_passthrough = "comp_simple_passthrough" WS triple_quoted_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)+\"\"\"" ;
identifier = alpha | alpha alphanumeric ; identifier = alpha | alpha alphanumeric ;
function_list = function_list WS function | function ;
function = type WS identifier WS "\(" WS opt_typed_parameter_list WS "\)" WS code_block ; function = type WS identifier WS "\(" WS opt_typed_parameter_list WS "\)" WS code_block ;
opt_typed_parameter_list = typed_parameter_list | ; opt_typed_parameter_list = typed_parameter_list | ;
@@ -36,12 +40,12 @@ while_loop = "while" WS boolean_expression WS statement ;
for_loop = "for" WS "\(" WS statement WS boolean_expression WS ";" WS statement WS "\)" WS statement ; for_loop = "for" WS "\(" WS statement WS boolean_expression WS ";" WS statement WS "\)" WS statement ;
return_statement = "return" WS boolean_expression ; return_statement = "return" | "return" WS boolean_expression ;
code_block = "{" WS statement_list WS "}" ; code_block = "{" WS statement_list WS "}" ;
statement_list = statement_list WS statement | statement ; statement_list = statement_list WS statement | statement ;
statement = if_statement | while_loop | for_loop | return_statement WS ";" | boolean_expression WS ";" | assignment_statement WS ";" | declaration_statement WS ";" | code_block ; statement = if_statement | while_loop | for_loop | return_statement WS ";" | boolean_expression WS ";" | assignment_statement WS ";" | declaration_statement WS ";" | code_block | if_comp | simple_passthrough ;
function_call = scope identifier "\(" WS opt_parameter_list WS "\)" ; function_call = scope identifier "\(" WS opt_parameter_list WS "\)" ;
scope = scope identifier "::" | ; scope = scope identifier "::" | ;
@@ -69,4 +73,7 @@ double = sign numeric "." numeric | sign numeric "." numeric "d" ;
bool = "true" | "false" | "True" | "False" ; bool = "true" | "false" | "True" | "False" ;
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|_)+" ; 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)+" ; numeric = "(0|1|2|3|4|5|6|7|8|9)+" ;
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)+\"" ; 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)+\"" ;
comment = "//(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)+
" | "/\*(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)+\*/" ;

View File

@@ -134,10 +134,11 @@ int main(int argc, char* argv[]) {
preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("opt_parameter_list", false))); preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("opt_parameter_list", false)));
preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("opt_import_list", false))); preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("opt_import_list", false)));
preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("import_list", false))); preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("import_list", false)));
preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("function_list", false)));
preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("statement_list", false))); preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("statement_list", false)));
preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("parameter_list", false))); preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("parameter_list", false)));
preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("typed_parameter_list", false))); preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("typed_parameter_list", false)));
preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("unorderd_list_part", false)));
preASTTransforms.push_back(new CollapseTransformation<Symbol>(Symbol("if_comp_pred", false)));
for (int i = 0; i < preASTTransforms.size(); i++) { for (int i = 0; i < preASTTransforms.size(); i++) {
parseTree = preASTTransforms[i]->transform(parseTree); parseTree = preASTTransforms[i]->transform(parseTree);
@@ -145,7 +146,6 @@ int main(int argc, char* argv[]) {
preASTTransforms.erase(preASTTransforms.begin(), preASTTransforms.end()); preASTTransforms.erase(preASTTransforms.begin(), preASTTransforms.end());
NodeTree<ASTData>* AST = ASTTransformation().transform(parseTree); NodeTree<ASTData>* AST = ASTTransformation().transform(parseTree);
//NodeTree<ASTData>* AST = (new ASTTransformation())->transform(parseTree);
if (parseTree) { if (parseTree) {
outFileTransformed << parseTree->DOTGraphString() << std::endl; outFileTransformed << parseTree->DOTGraphString() << std::endl;
@@ -162,7 +162,7 @@ int main(int argc, char* argv[]) {
outFileAST.close(); outFileAST.close();
//Do type checking, scope creation, etc. here. //Do type checking, scope creation, etc. here.
//None at this time, instead going strait to C in this first (more naive) version //None at this time, instead going straight to C in this first (more naive) version
//Code generation //Code generation
//For right now, just C //For right now, just C

View File

@@ -24,7 +24,9 @@ std::string ASTData::toString() {
} }
ValueType ASTData::strToType(std::string type) { ValueType ASTData::strToType(std::string type) {
if (type == "bool") if (type == "void")
return void_type;
else if (type == "bool")
return boolean; return boolean;
else if (type == "int") else if (type == "int")
return integer; return integer;
@@ -41,22 +43,18 @@ std::string ASTData::ValueTypeToString(ValueType type) {
switch (type) { switch (type) {
case none: case none:
return "none"; return "none";
break; case void_type:
return "void";
case boolean: case boolean:
return "bool"; return "bool";
break;
case integer: case integer:
return "int"; return "int";
break;
case floating: case floating:
return "float"; return "float";
break;
case double_percision: case double_percision:
return "double"; return "double";
break;
case char_string: case char_string:
return "string"; return "string";
break;
default: default:
return "unknown_ValueType"; return "unknown_ValueType";
} }
@@ -96,6 +94,10 @@ std::string ASTData::ASTTypeToString(ASTType type) {
return "assignment_statement"; return "assignment_statement";
case declaration_statement: case declaration_statement:
return "declaration_statement"; return "declaration_statement";
case if_comp:
return "if_comp";
case simple_passthrough:
return "simple_passthrough";
case function_call: case function_call:
return "function_call"; return "function_call";
case value: case value:

View File

@@ -105,6 +105,10 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
newNode->addChild(newIdentifier); newNode->addChild(newIdentifier);
skipChildren.insert(0); //These, the type and the identifier, have been taken care of. skipChildren.insert(0); //These, the type and the identifier, have been taken care of.
skipChildren.insert(1); skipChildren.insert(1);
} else if (name == "if_comp") {
newNode = new NodeTree<ASTData>(name, ASTData(if_comp));
} else if (name == "simple_passthrough") {
newNode = new NodeTree<ASTData>(name, ASTData(simple_passthrough));
} else if (name == "function_call") { } else if (name == "function_call") {
//children[0] is scope //children[0] is scope
std::string functionCallName = concatSymbolTree(children[1]); std::string functionCallName = concatSymbolTree(children[1]);
@@ -122,7 +126,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), floating)); newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), floating));
} else if (name == "double") { } else if (name == "double") {
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), double_percision)); newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), double_percision));
} else if (name == "string") { } else if (name == "string" || name == "triple_quoted_string") {
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), char_string)); newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), char_string));
} else { } else {
return new NodeTree<ASTData>(); return new NodeTree<ASTData>();

View File

@@ -1,6 +1,6 @@
#include "CGenerator.h" #include "CGenerator.h"
CGenerator::CGenerator() { CGenerator::CGenerator() : generatorString("__C__") {
tabLevel = 0; tabLevel = 0;
} }
CGenerator::~CGenerator() { CGenerator::~CGenerator() {
@@ -26,7 +26,8 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
//Do nothing //Do nothing
break; break;
case import: case import:
return "#include <" + data.symbol.getName() + ">\n"; return "/* would import \"" + data.symbol.getName() + "\" but....*/\n";
//return "#include <" + data.symbol.getName() + ">\n";
case identifier: case identifier:
return data.symbol.getName(); return data.symbol.getName();
case function: case function:
@@ -34,7 +35,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
for (int i = 0; i < children.size()-1; i++) { for (int i = 0; i < children.size()-1; i++) {
if (i > 0) if (i > 0)
output += ", "; output += ", ";
output += ASTData::ValueTypeToString(children[i]->getData().valueType) + " " + generate(children[i]); output += ValueTypeToCType(children[i]->getData().valueType) + " " + generate(children[i]);
} }
output+= ")\n" + generate(children[children.size()-1]); output+= ")\n" + generate(children[children.size()-1]);
return output; return output;
@@ -65,11 +66,20 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
output += "for (" + strSlice(generate(children[0]),0,-2) + generate(children[1]) + ";" + strSlice(generate(children[2]),0,-3) + ")\n\t" + generate(children[3]); output += "for (" + strSlice(generate(children[0]),0,-2) + generate(children[1]) + ";" + strSlice(generate(children[2]),0,-3) + ")\n\t" + generate(children[3]);
return output; return output;
case return_statement: case return_statement:
return "return " + generate(children[0]); if (children.size())
return "return " + generate(children[0]);
else
return "return";
case assignment_statement: case assignment_statement:
return generate(children[0]) + " = " + generate(children[1]); return generate(children[0]) + " = " + generate(children[1]);
case declaration_statement: case declaration_statement:
return ASTData::ValueTypeToString(children[0]->getData().valueType) + " " + generate(children[0]) + " = " + generate(children[1]); return ASTData::ValueTypeToString(children[0]->getData().valueType) + " " + generate(children[0]) + " = " + generate(children[1]);
case if_comp:
if (generate(children[0]) == generatorString)
return generate(children[1]);
return "";
case simple_passthrough:
return strSlice(generate(children[0]), 3, -4);
case function_call: case function_call:
{ {
//Handle operators specially for now. Will later replace with //Handle operators specially for now. Will later replace with
@@ -104,22 +114,20 @@ std::string CGenerator::ValueTypeToCType(ValueType type) {
switch (type) { switch (type) {
case none: case none:
return "none"; return "none";
break; case void_type:
return "void";
case boolean: case boolean:
return "bool"; return "bool";
break;
case integer: case integer:
return "int"; return "int";
break; break;
case floating: case floating:
return "float"; return "float";
break;
case double_percision: case double_percision:
return "double"; return "double";
break; break;
case char_string: case char_string:
return "char*"; return "char*";
break;
default: default:
return "unknown_ValueType"; return "unknown_ValueType";
} }

View File

@@ -79,7 +79,7 @@ NodeTree<Symbol>* RNGLRParser::parseInput(std::string inputString) {
std::cout << "Frontier " << i << " is empty." << std::endl; std::cout << "Frontier " << i << " is empty." << std::endl;
std::cout << "Failed on " << input[i].toString() << std::endl; std::cout << "Failed on " << input[i].toString() << std::endl;
std::cout << "Nearby is:" << std::endl; std::cout << "Nearby is:" << std::endl;
int range = 5; const int range = 10;
for (int j = (i-range >= 0 ? i-range : 0); j < (i+range < input.size() ? i+range : input.size()); j++) for (int j = (i-range >= 0 ? i-range : 0); j < (i+range < input.size() ? i+range : input.size()); j++)
if (j == i) if (j == i)
std::cout << "||*||*||" << input[j].toString() << "||*||*|| "; std::cout << "||*||*||" << input[j].toString() << "||*||*|| ";

View File

@@ -8,7 +8,7 @@ std::string intToString(int theInt) {
std::string replaceExEscape(std::string first, std::string search, std::string replace) { std::string replaceExEscape(std::string first, std::string search, std::string replace) {
size_t pos = 0; size_t pos = 0;
while (pos < first.size()-search.size()) { while (pos <= first.size()-search.size()) {
pos = first.find(search, pos); pos = first.find(search, pos);
if (pos == std::string::npos) if (pos == std::string::npos)
break; break;