diff --git a/include/CGenerator.h b/include/CGenerator.h index 35d26a7..eab5c53 100644 --- a/include/CGenerator.h +++ b/include/CGenerator.h @@ -3,6 +3,7 @@ #include #include +#include #include "NodeTree.h" #include "ASTData.h" @@ -15,8 +16,10 @@ class CGenerator { public: CGenerator(); ~CGenerator(); + void generateCompSet(std::map*> ASTs, std::string outputName); std::string generate(NodeTree* from); static std::string ValueTypeToCType(Type type); + std::string generatorString; private: std::string tabs(); diff --git a/include/Importer.h b/include/Importer.h index 187d054..c0b4f55 100644 --- a/include/Importer.h +++ b/include/Importer.h @@ -19,10 +19,12 @@ class Importer { Importer(Parser* parserIn); ~Importer(); NodeTree* import(std::string fileName); + std::map*> getASTMap(); private: Parser* parser; std::vector removeSymbols; std::vector collapseSymbols; + std::map*> imported; }; #endif \ No newline at end of file diff --git a/main.cpp b/main.cpp index 41de216..9ca06ef 100644 --- a/main.cpp +++ b/main.cpp @@ -31,7 +31,7 @@ int main(int argc, char* argv[]) { std::string outputName = argv[3]; std::ifstream grammerInFile, compiledGrammerInFile; - std::ofstream outFileC, compiledGrammerOutFile; + std::ofstream /*outFileC,*/ compiledGrammerOutFile; grammerInFile.open(grammerFileString); if (!grammerInFile.is_open()) { @@ -44,12 +44,13 @@ int main(int argc, char* argv[]) { std::cout << "Problem opening compiledGrammerInFile " << grammerFileString + ".comp" << "\n"; //return(1); } - +/* outFileC.open((outputName + ".c").c_str()); if (!outFileC.is_open()) { std::cout << "Probelm opening third output file " << outputName + ".c" << "\n"; return(1); } + */ //Read the input file into a string std::string grammerInputFileString; std::string line; @@ -63,7 +64,7 @@ int main(int argc, char* argv[]) { RNGLRParser parser; parser.loadGrammer(grammerInputFileString); //std::cout << "Creating State Set from Main" << std::endl; - std::cout << "\nState Set" << std::endl; + //std::cout << "\nState Set" << std::endl; //Start binary stuff bool compGramGood = false; @@ -78,15 +79,15 @@ int main(int argc, char* argv[]) { if (binaryTablePointer[0] == 'K' && binaryTablePointer[1] == 'R' && binaryTablePointer[2] == 'A' && binaryTablePointer[3] == 'K') { std::cout << "Valid Kraken Compiled Grammer File" << std::endl; int gramStringLength = *((int*)(binaryTablePointer+4)); - std::cout << "The grammer string is stored to be " << gramStringLength << " characters long, gramString is " - << grammerInputFileString.length() << " long. Remember 1 extra for null terminator!" << std::endl; + //std::cout << "The grammer string is stored to be " << gramStringLength << " characters long, gramString is " + //<< grammerInputFileString.length() << " long. Remember 1 extra for null terminator!" << std::endl; if (grammerInputFileString.length() != gramStringLength-1 || (strncmp(grammerInputFileString.c_str(), (binaryTablePointer+4+sizeof(int)), gramStringLength) != 0)) { //(one less for null terminator that is stored) std::cout << "The Grammer has been changed, will re-create" << std::endl; } else { compGramGood = true; - std::cout << "grammer file good" << std::endl; + std::cout << "Grammer file is up to date." << std::endl; //int tableLength = *((int*)(binaryTablePointer + 4 + sizeof(int) + gramStringLength)); parser.importTable(binaryTablePointer + 4 + sizeof(int) + gramStringLength); //Load table starting at the table section } @@ -134,17 +135,22 @@ int main(int argc, char* argv[]) { Importer importer(&parser); - NodeTree* AST = importer.import(programName); + /*NodeTree* AST =*/ + importer.import(programName); + std::map*> ASTs =importer.getASTMap(); //Do optomization, etc. here. //None at this time, instead going straight to C in this first (more naive) version //Code generation //For right now, just C + + CGenerator().generateCompSet(ASTs, outputName); + /* std::string c_code = CGenerator().generate(AST); outFileC << c_code << std::endl; outFileC.close(); - +*/ return(0); } diff --git a/src/ASTTransformation.cpp b/src/ASTTransformation.cpp index 7ca4937..0f0ad42 100644 --- a/src/ASTTransformation.cpp +++ b/src/ASTTransformation.cpp @@ -57,7 +57,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree return newNode; // Don't need children of import } else if (name == "identifier") { std::string lookupName = concatSymbolTree(children[0]); - std::cout << "scope lookup from identifier" << std::endl; + //std::cout << "scope lookup from identifier" << std::endl; newNode = scopeLookup(scope, lookupName); if (newNode == NULL) { std::cout << "scope lookup error! Could not find " << lookupName << std::endl; @@ -87,7 +87,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree //If this is an actual part of an expression, not just a premoted term if (children.size() > 1) { std::string functionCallName = concatSymbolTree(children[1]); - std::cout << "scope lookup from boolen_expression or similar" << std::endl; + //std::cout << "scope lookup from boolen_expression or similar" << std::endl; NodeTree* function = scopeLookup(scope, functionCallName); if (function == NULL) { std::cout << "scope lookup error! Could not find " << functionCallName << std::endl; @@ -97,7 +97,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree newNode->addChild(function); // First child of function call is a link to the function definition skipChildren.insert(1); } else { - std::cout << children.size() << std::endl; + //std::cout << children.size() << std::endl; if (children.size() == 0) return new NodeTree(); return transform(children[0], scope); //Just a promoted term, so do child @@ -107,7 +107,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree //If this is an actual part of an expression, not just a premoted child if (children.size() > 2) { std::string functionCallName = concatSymbolTree(children[1]); - std::cout << "scope lookup from expression or similar" << std::endl; + //std::cout << "scope lookup from expression or similar" << std::endl; NodeTree* function = scopeLookup(scope, functionCallName); if (function == NULL) { std::cout << "scope lookup error! Could not find " << functionCallName << std::endl; @@ -130,7 +130,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree else funcName = concatSymbolTree(children[1]), funcNum = 1; - std::cout << "scope lookup from factor" << std::endl; + //std::cout << "scope lookup from factor" << std::endl; NodeTree* function = scopeLookup(scope, funcName); if (function == NULL) { std::cout << "scope lookup error! Could not find " << funcName << std::endl; @@ -199,7 +199,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree //children[0] is scope std::string functionCallName = concatSymbolTree(children[1]); newNode = new NodeTree(functionCallName, ASTData(function_call, Symbol(functionCallName, true))); - std::cout << "scope lookup from function_call" << std::endl; + //std::cout << "scope lookup from function_call" << std::endl; NodeTree* function = scopeLookup(scope, functionCallName); if (function == NULL) { std::cout << "scope lookup error! Could not find " << functionCallName << std::endl; @@ -260,8 +260,8 @@ NodeTree* ASTTransformation::scopeLookup(NodeTree* scope, std: //Seach the map auto scopeMap = scope->getDataRef()->scope; //std::cout << "scope size: " << scopeMap.size() << ", scope from " << scope->getName() << std::endl; - for (auto i = scopeMap.begin(); i != scopeMap.end(); i++) - std::cout << i->first << " : " << i-> second << " - " << i->second->getName() << std::endl; + // for (auto i = scopeMap.begin(); i != scopeMap.end(); i++) + // std::cout << i->first << " : " << i-> second << " - " << i->second->getName() << std::endl; auto elementIterator = scopeMap.find(lookup); if (elementIterator != scopeMap.end()) { diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index 1b9a108..6e6912a 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -7,6 +7,27 @@ CGenerator::~CGenerator() { } +void CGenerator::generateCompSet(std::map*> ASTs, std::string outputName) { + //Generate an entire set of files + std::string buildString = "#!/bin/sh\ncc -std=c99 "; + for (auto i = ASTs.begin(); i != ASTs.end(); i++) { + buildString += i->first + ".c "; + std::ofstream outputCFile; + outputCFile.open(i->first + ".c"); + if (outputCFile.is_open()) { + outputCFile << generate(i->second); + } else { + std::cout << "Cannot open file " << i->first << ".c" << std::endl; + } + outputCFile.close(); + } + buildString += "-o " + outputName; + std::ofstream outputBuild; + outputBuild.open(outputName + ".sh"); + outputBuild << buildString; + outputBuild.close(); +} + std::string CGenerator::tabs() { std::string returnTabs; for (int i = 0; i < tabLevel; i++) @@ -39,7 +60,7 @@ std::string CGenerator::generate(NodeTree* from) { output+= "); /*func*/\n"; break; default: - std::cout << "Declaration? named " << declaration->getName() << " of unknown type " << ASTData::ASTTypeToString(declarationData.type) << " in translation unit scope" << std::endl; + //std::cout << "Declaration? named " << declaration->getName() << " of unknown type " << ASTData::ASTTypeToString(declarationData.type) << " in translation unit scope" << std::endl; output += "/*unknown declaration named " + declaration->getName() + "*/\n"; } } @@ -109,7 +130,7 @@ std::string CGenerator::generate(NodeTree* from) { //Handle operators specially for now. Will later replace with //Inlined functions in the standard library std::string name = data.symbol.getName(); - std::cout << name << " == " << children[0]->getData().symbol.getName() << std::endl; + //std::cout << name << " == " << children[0]->getData().symbol.getName() << std::endl; if (name == "++" || name == "--") return generate(children[1]) + name; if (name == "*" && children.size() == 2) //Is dereference, not multiplication diff --git a/src/Importer.cpp b/src/Importer.cpp index f4a1cf9..7cac9ab 100644 --- a/src/Importer.cpp +++ b/src/Importer.cpp @@ -36,6 +36,10 @@ Importer::~Importer() { } NodeTree* Importer::import(std::string fileName) { + //Check to see if we've already done it + if (imported.find(fileName) != imported.end()) + return imported[fileName]; + std::ifstream programInFile; std::ofstream outFile, outFileTransformed, outFileAST; @@ -64,7 +68,7 @@ NodeTree* Importer::import(std::string fileName) { std::cout << "Probelm opening second output file " << outputName + ".AST.dot" << "\n"; return NULL; } - //ljklj + std::string programInputFileString, line; while(programInFile.good()) { getline(programInFile, line); @@ -72,7 +76,7 @@ NodeTree* Importer::import(std::string fileName) { } programInFile.close(); - std::cout << programInputFileString << std::endl; + //std::cout << programInputFileString << std::endl; NodeTree* parseTree = parser->parseInput(programInputFileString); if (parseTree) { @@ -109,5 +113,11 @@ NodeTree* Importer::import(std::string fileName) { } outFileAST.close(); + imported[fileName] = AST; + return AST; -} \ No newline at end of file +} + +std::map*> Importer::getASTMap() { + return imported; +} diff --git a/src/Parser.cpp b/src/Parser.cpp index 5133c32..5971829 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -78,7 +78,7 @@ void Parser::loadGrammer(std::string grammerInputString) { //Get next token currToken = reader.word(); } - std::cout << "Parsed!\n"; + //std::cout << "Parsed!\n"; // for (std::vector::size_type i = 0; i < loadedGrammer.size(); i++) // std::cout << loadedGrammer[i]->toString() << std::endl; diff --git a/src/RNGLRParser.cpp b/src/RNGLRParser.cpp index 33989ff..274558f 100644 --- a/src/RNGLRParser.cpp +++ b/src/RNGLRParser.cpp @@ -50,8 +50,8 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { input.push_back(currentToken); } - std::cout << "\nDone with Lexing, length:" << input.size() << std::endl; - std::cout << input[0].toString() << std::endl; + // std::cout << "\nDone with Lexing, length:" << input.size() << std::endl; + // std::cout << input[0].toString() << std::endl; // for (int i = 0; i < input.size(); i++) @@ -59,13 +59,13 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { // std::cout << std::endl; - std::cout << "Setting up 0th frontier, first actions, toShift, toReduce" << std::endl; + //std::cout << "Setting up 0th frontier, first actions, toShift, toReduce" << std::endl; //Frontier 0, new node with state 0 NodeTree* v0 = gss.newNode(0); gss.addToFrontier(0,v0); - std::cout << "Done setting up new frontier" << std::endl; + //std::cout << "Done setting up new frontier" << std::endl; std::vector firstActions = *(table.get(0, input[0])); for (std::vector::size_type i = 0; i < firstActions.size(); i++) { @@ -80,7 +80,7 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { // std::cout << "GSS:\n" << gss.toString() << std::endl; - std::cout << "Starting parse loop" << std::endl; + //std::cout << "Starting parse loop" << std::endl; for (int i = 0; i < input.size(); i++) { // std::cout << "Checking if frontier " << i << " is empty" << std::endl; @@ -110,7 +110,7 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { shifter(i); //std::cout << "GSS:\n" << gss.toString() << std::endl; } - std::cout << "Done with parsing loop, checking for acceptance" << std::endl; + //std::cout << "Done with parsing loop, checking for acceptance" << std::endl; NodeTree* accState = gss.frontierGetAccState(input.size()-1); if (accState) { std::cout << "Accepted!" << std::endl; @@ -143,7 +143,7 @@ void RNGLRParser::reducer(int i) { //The end of the current path NodeTree* 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 shift 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 @@ -189,7 +189,7 @@ void RNGLRParser::reducer(int i) { //std::cout << "Adding shifts and reductions for a state that did not exist" << std::endl; std::vector actions = *(table.get(toState, input[i])); for (std::vector::size_type k = 0; k < actions.size(); k++) { - std::cout << "Action is " << actions[k]->toString() << std::endl; + //std::cout << "Action is " << actions[k]->toString() << std::endl; if (actions[k]->action == ParseAction::SHIFT) { toShift.push(std::make_pair(toStateNode, actions[k]->shiftState)); } else if (actions[k]->action == ParseAction::REDUCE && fullyReducesToNull(actions[k]->reduceRule)) { @@ -213,7 +213,7 @@ void RNGLRParser::shifter(int i) { while (!toShift.empty()) { std::pair*, int> shift = toShift.front(); toShift.pop(); - std::cout << "Current potential shift from " << shift.first->getData() << " to " << shift.second << std::endl; + //std::cout << "Current potential shift from " << shift.first->getData() << " to " << shift.second << std::endl; NodeTree* shiftTo = gss.inFrontier(i+1, shift.second); if (shiftTo) { //std::cout << "State already existed, just adding edge" << std::endl; @@ -232,7 +232,7 @@ void RNGLRParser::shifter(int i) { gss.addEdge(shiftTo, shift.first, newLabel); std::vector actions = *(table.get(shift.second, input[i+1])); for (std::vector::size_type j = 0; j < actions.size(); j++) { - std::cout << "Adding action " << actions[j]->toString() << " to either nextShifts or toReduce" << std::endl; + //std::cout << "Adding action " << actions[j]->toString() << " to either nextShifts or toReduce" << std::endl; //Shift if (actions[j]->action == ParseAction::SHIFT) { nextShifts.push(std::make_pair(shiftTo, actions[j]->shiftState)); diff --git a/src/StringReader.cpp b/src/StringReader.cpp index 29772b4..f4b6e50 100644 --- a/src/StringReader.cpp +++ b/src/StringReader.cpp @@ -75,7 +75,7 @@ std::string StringReader::getTokens(const char *stop_chars, bool truncateEnd) { //End of String end_reached = true; - std::cout << "Reached end of file!\n"; + //std::cout << "Reached end of file!\n"; return ""; } else { diff --git a/src/Table.cpp b/src/Table.cpp index 0c8b8fe..ddbc421 100644 --- a/src/Table.cpp +++ b/src/Table.cpp @@ -303,7 +303,7 @@ std::vector* Table::get(int state, Symbol token) { 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; @@ -312,7 +312,7 @@ std::vector* Table::get(int state, Symbol token) { std::vector* 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]; } diff --git a/src/Type.cpp b/src/Type.cpp index f8df255..3da4601 100644 --- a/src/Type.cpp +++ b/src/Type.cpp @@ -33,7 +33,7 @@ Type::Type(std::string typeIn) { baseType = character; else baseType = none; - std::cout << ":ALKJF:LSKDJF:SDJF:LKSJDF\t\t\t" << typeIn << "\t" << edited << std::endl; + //std::cout << ":ALKJF:LSKDJF:SDJF:LKSJDF\t\t\t" << typeIn << "\t" << edited << std::endl; }