2013-09-26 15:16:58 -04:00
|
|
|
#include <string>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <fstream>
|
2013-10-02 03:15:20 -04:00
|
|
|
#include <vector>
|
2013-09-26 15:16:58 -04:00
|
|
|
|
2013-12-31 02:53:52 -06:00
|
|
|
#include <cstring>
|
|
|
|
|
|
2013-05-11 16:13:46 -04:00
|
|
|
#include "NodeTree.h"
|
2013-07-28 19:45:08 -04:00
|
|
|
#include "Symbol.h"
|
2013-06-13 14:25:10 -04:00
|
|
|
#include "Lexer.h"
|
2013-07-30 01:42:51 -04:00
|
|
|
#include "LALRParser.h"
|
2013-07-31 23:51:05 -04:00
|
|
|
#include "RNGLRParser.h"
|
2013-09-26 15:16:58 -04:00
|
|
|
|
2013-12-31 23:43:49 -06:00
|
|
|
#include "Importer.h"
|
2013-10-02 03:15:20 -04:00
|
|
|
#include "ASTData.h"
|
2013-11-01 02:52:18 -04:00
|
|
|
#include "CGenerator.h"
|
2013-05-11 16:13:46 -04:00
|
|
|
|
2013-12-19 10:39:36 -06:00
|
|
|
#include "util.h"
|
2013-05-11 16:13:46 -04:00
|
|
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
2014-05-01 01:18:01 -04:00
|
|
|
std::vector<std::string> includePaths;
|
|
|
|
|
includePaths.push_back(""); //Local
|
|
|
|
|
|
2013-10-25 02:04:22 -07:00
|
|
|
if (argc == 2 && std::string(argv[1]) == "--test") {
|
|
|
|
|
StringReader::test();
|
2013-10-26 23:29:23 -07:00
|
|
|
RegEx::test();
|
2013-10-26 23:05:25 -07:00
|
|
|
Lexer::test();
|
2013-12-19 10:39:36 -06:00
|
|
|
//std::cout << strSlice("123", 0, -1) << std::endl;
|
2013-10-25 02:04:22 -07:00
|
|
|
return 0;
|
|
|
|
|
}
|
2014-05-01 01:18:01 -04:00
|
|
|
std::string krakenDir = argv[0];
|
|
|
|
|
krakenDir = strSlice(krakenDir, 0, -(std::string("kraken").length()+1));
|
|
|
|
|
includePaths.push_back(krakenDir + "stdlib/");
|
2013-12-31 23:43:49 -06:00
|
|
|
std::string programName = argv[1];
|
2013-12-28 21:55:43 -05:00
|
|
|
std::string grammerFileString = argv[2];
|
2013-12-31 23:43:49 -06:00
|
|
|
std::string outputName = argv[3];
|
|
|
|
|
|
|
|
|
|
std::ifstream grammerInFile, compiledGrammerInFile;
|
2014-01-01 17:29:19 -06:00
|
|
|
std::ofstream /*outFileC,*/ compiledGrammerOutFile;
|
2013-12-28 21:55:43 -05:00
|
|
|
|
2013-12-28 21:54:22 -05:00
|
|
|
grammerInFile.open(grammerFileString);
|
2013-05-29 20:43:35 -04:00
|
|
|
if (!grammerInFile.is_open()) {
|
2013-12-28 21:54:22 -05:00
|
|
|
std::cout << "Problem opening grammerInFile " << grammerFileString << "\n";
|
2013-05-29 20:43:35 -04:00
|
|
|
return(1);
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-31 02:53:52 -06:00
|
|
|
compiledGrammerInFile.open(grammerFileString + ".comp", std::ios::binary | std::ios::ate);
|
|
|
|
|
if (!compiledGrammerInFile.is_open()) {
|
|
|
|
|
std::cout << "Problem opening compiledGrammerInFile " << grammerFileString + ".comp" << "\n";
|
|
|
|
|
//return(1);
|
|
|
|
|
}
|
2014-01-01 17:29:19 -06:00
|
|
|
/*
|
2013-12-31 23:43:49 -06:00
|
|
|
outFileC.open((outputName + ".c").c_str());
|
2013-11-01 02:52:18 -04:00
|
|
|
if (!outFileC.is_open()) {
|
2013-12-31 23:43:49 -06:00
|
|
|
std::cout << "Probelm opening third output file " << outputName + ".c" << "\n";
|
2013-11-01 02:52:18 -04:00
|
|
|
return(1);
|
|
|
|
|
}
|
2014-01-01 17:29:19 -06:00
|
|
|
*/
|
2013-05-20 19:34:15 -04:00
|
|
|
//Read the input file into a string
|
2013-12-31 23:43:49 -06:00
|
|
|
std::string grammerInputFileString;
|
2013-05-20 19:34:15 -04:00
|
|
|
std::string line;
|
2013-05-29 20:43:35 -04:00
|
|
|
while(grammerInFile.good()) {
|
|
|
|
|
getline(grammerInFile, line);
|
|
|
|
|
grammerInputFileString.append(line+"\n");
|
|
|
|
|
}
|
2013-11-01 02:52:18 -04:00
|
|
|
grammerInFile.close();
|
2013-05-29 20:43:35 -04:00
|
|
|
|
2013-07-31 23:51:05 -04:00
|
|
|
//LALRParser parser;
|
|
|
|
|
RNGLRParser parser;
|
2013-05-29 20:43:35 -04:00
|
|
|
parser.loadGrammer(grammerInputFileString);
|
2013-05-30 19:49:19 -04:00
|
|
|
//std::cout << "Creating State Set from Main" << std::endl;
|
2014-01-01 17:29:19 -06:00
|
|
|
//std::cout << "\nState Set" << std::endl;
|
2013-12-31 02:53:52 -06:00
|
|
|
|
|
|
|
|
//Start binary stuff
|
|
|
|
|
bool compGramGood = false;
|
|
|
|
|
if (compiledGrammerInFile.is_open()) {
|
|
|
|
|
std::cout << "Compiled grammer file exists, reading it in" << std::endl;
|
|
|
|
|
std::streampos compGramSize = compiledGrammerInFile.tellg();
|
|
|
|
|
char* binaryTablePointer = new char [compGramSize];
|
|
|
|
|
compiledGrammerInFile.seekg(0, std::ios::beg);
|
|
|
|
|
compiledGrammerInFile.read(binaryTablePointer, compGramSize);
|
|
|
|
|
compiledGrammerInFile.close();
|
2013-12-31 23:43:49 -06:00
|
|
|
//Check magic number
|
2013-12-31 02:53:52 -06:00
|
|
|
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));
|
2014-01-01 17:29:19 -06:00
|
|
|
//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;
|
2013-12-31 02:53:52 -06:00
|
|
|
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;
|
2014-01-01 17:29:19 -06:00
|
|
|
std::cout << "Grammer file is up to date." << std::endl;
|
2013-12-31 02:53:52 -06:00
|
|
|
//int tableLength = *((int*)(binaryTablePointer + 4 + sizeof(int) + gramStringLength));
|
|
|
|
|
parser.importTable(binaryTablePointer + 4 + sizeof(int) + gramStringLength); //Load table starting at the table section
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
std::cout << grammerFileString << ".comp is NOT A Valid Kraken Compiled Grammer File, aborting" << std::endl;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
delete binaryTablePointer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!compGramGood) {
|
|
|
|
|
//The load failed because either the file does not exist or it is not up-to-date.
|
|
|
|
|
std::cout << "Compiled grammer file does not exist or is not up-to-date, generating table and writing it out" << std::endl;
|
|
|
|
|
compiledGrammerOutFile.open(grammerFileString + ".comp", std::ios::binary);
|
|
|
|
|
if (!compiledGrammerOutFile.is_open())
|
|
|
|
|
std::cout << "Could not open compiled file to write either!" << std::endl;
|
2014-01-19 18:20:52 -05:00
|
|
|
compiledGrammerOutFile.write("KRAK", sizeof(char)*4); //Let us know when we load it that this is a kraken grammer file, but don't write out
|
|
|
|
|
compiledGrammerOutFile.flush(); // the grammer txt until we create the set, so that if we fail creating it it won't look valid
|
|
|
|
|
parser.createStateSet();
|
2013-12-31 02:53:52 -06:00
|
|
|
int* intBuffer = new int;
|
|
|
|
|
*intBuffer = grammerInputFileString.length()+1;
|
|
|
|
|
compiledGrammerOutFile.write((char*)intBuffer, sizeof(int));
|
|
|
|
|
delete intBuffer;
|
|
|
|
|
compiledGrammerOutFile.write(grammerInputFileString.c_str(), grammerInputFileString.length()+1); //Don't forget null terminator
|
|
|
|
|
|
|
|
|
|
parser.exportTable(compiledGrammerOutFile);
|
|
|
|
|
compiledGrammerOutFile.close();
|
|
|
|
|
}
|
|
|
|
|
//End binary stuff
|
|
|
|
|
|
2013-05-30 19:49:19 -04:00
|
|
|
//std::cout << "finished State Set from Main" << std::endl;
|
|
|
|
|
//std::cout << "Doing stateSetToString from Main" << std::endl;
|
2013-08-16 00:03:26 -04:00
|
|
|
// std::cout << "\n\n\n\n\n\n\n\n\n\nState Set toString" << std::endl;
|
2013-08-26 15:37:49 -04:00
|
|
|
// std::cout << parser.stateSetToString() << std::endl;
|
2013-12-18 18:05:21 -06:00
|
|
|
// std::cout << "finished stateSetToString from Main" << std::endl;
|
2013-08-26 15:37:49 -04:00
|
|
|
// std::cout << "\n\n\n\n\n\n\n\n\n\nTable" << std::endl;
|
|
|
|
|
// std::cout << parser.tableToString() << std::endl;
|
2013-08-16 00:03:26 -04:00
|
|
|
// std::cout << "\n\n\n\n\n\n\n\n\n\nGrammer Input File" << std::endl;
|
|
|
|
|
// std::cout << grammerInputFileString << std::endl;
|
|
|
|
|
// std::cout << "\n\n\n\n\n\n\n\n\n\nGrammer toString" << std::endl;
|
|
|
|
|
// std::cout << parser.grammerToString() << std::endl;
|
2013-05-30 19:49:19 -04:00
|
|
|
//std::cout << parser.grammerToDOT() << std::endl;
|
2013-05-20 19:34:15 -04:00
|
|
|
|
2013-05-30 19:49:19 -04:00
|
|
|
//outFile << parser.grammerToDOT() << std::endl;
|
2013-08-16 00:03:26 -04:00
|
|
|
std::cout << "\nParsing" << std::endl;
|
2013-05-11 16:13:46 -04:00
|
|
|
|
2014-05-01 01:18:01 -04:00
|
|
|
Importer importer(&parser, includePaths);
|
2013-05-30 19:49:19 -04:00
|
|
|
|
2014-01-01 17:29:19 -06:00
|
|
|
/*NodeTree<ASTData>* AST =*/
|
2014-05-01 01:18:01 -04:00
|
|
|
for (auto i : includePaths)
|
|
|
|
|
std::cout << i << std::endl;
|
|
|
|
|
|
2014-01-01 17:29:19 -06:00
|
|
|
importer.import(programName);
|
2014-02-18 21:55:00 -05:00
|
|
|
std::map<std::string, NodeTree<ASTData>*> ASTs = importer.getASTMap();
|
2013-05-11 16:13:46 -04:00
|
|
|
|
2013-12-31 23:43:49 -06:00
|
|
|
//Do optomization, etc. here.
|
2013-12-22 01:34:59 -06:00
|
|
|
//None at this time, instead going straight to C in this first (more naive) version
|
2013-11-01 02:52:18 -04:00
|
|
|
|
|
|
|
|
//Code generation
|
|
|
|
|
//For right now, just C
|
2014-01-01 17:29:19 -06:00
|
|
|
|
|
|
|
|
CGenerator().generateCompSet(ASTs, outputName);
|
|
|
|
|
/*
|
2013-11-01 02:52:18 -04:00
|
|
|
std::string c_code = CGenerator().generate(AST);
|
|
|
|
|
outFileC << c_code << std::endl;
|
2013-12-22 01:34:59 -06:00
|
|
|
outFileC.close();
|
2014-01-01 17:29:19 -06:00
|
|
|
*/
|
2013-05-11 16:13:46 -04:00
|
|
|
return(0);
|
|
|
|
|
}
|
2013-10-25 02:04:22 -07:00
|
|
|
|