int main( int argc, char * argv[] ){ int i; char pgm[120]; /* source code file name */ if (argc != 3){ fprintf(stderr,"usage: %s <input> <output>\n",argv[0]); exit(1); } strcpy(pgm,argv[1]); if (strchr (pgm, '.') == NULL) strcat(pgm,".pas"); source = fopen(pgm,"r"); if (source == NULL){ fprintf(stderr,"File %s not found\n",pgm); exit(1); } yyin = source; listing = stdout; /* send listing to screen */ fprintf(listing,"\nPASCAL COMPILATION: %s\n",pgm); //scan begin #ifdef SCAN_DEBUG yy_flex_debug = 1; #endif #ifdef PARSE_DEBUG yydebug = 1; #endif auto syntaxTree = dynamic_cast<Program_Node*>(do_parse()); st->global = 1; syntaxTree->build_symbol_table(""); // puts("=========symtab debug============"); // for (i=0; i<SIZE; i++) { // if (st->units[i].use == 1) { // puts("======================="); // printf("name: %s", st->units[i].name.c_str()); puts(""); // printf("type: %s", st->units[i].type.c_str()); puts(""); // printf("array_start: %d", st->units[i].array_start); puts(""); // printf("volumn: %d", st->units[i].volumn); puts(""); // printf("isrecord: %d", st->units[i].volumn); puts(""); // printf("volumn: %d", st->units[i].volumn); puts(""); // printf("printer: %p\n", &(st->units[i])); // } // } // puts("=========symtab debug end========"); /* code generation */ CodeGenerator* cg = new CodeGenerator(syntaxTree, argv[2]); cg->generate(); fclose(source); return 0; }
int main(int argc, char **argv) { options.includeDirs.push_back("./"); for (int i=1; i<argc; ++i) { std::string arg(argv[i]); if (arg == "-h" || arg == "--help") { printHelp(argv[0]); return 0; } else if (arg == "-v" || arg == "--verbose") { options.verbose = true; } else if (arg == "-d" || arg == "--dump-json") { options.dumpJson = true; } else if (arg == "-m" || arg == "--include-main") { options.includeMain = true; } else { std::string file(argv[i]); options.inputFile = file; size_t slash = file.find_last_of("/"); if (slash != string::npos) { std::string dir = file.substr(0, slash+1); options.includeDirs.push_back(dir); } } } if (options.inputFile.size() == 0) { printHelp(argv[0]); return 0; } value content; if (!loadFile(options.inputFile, &content)) return 1; substituteImports(&content); if (options.dumpJson) cout << content.serialize(true); ObjectModelBuilder builder; builder.setVerbose(options.verbose); builder.build(content); CodeGenerator generator; generator.setClasses(builder.classes()); generator.setIncludeMain(options.includeMain); generator.generate(); return 0; }
int main(int argc, char* argv[]) { if (argc != 2) { cout << "No input files!" << std::endl; return 1; } ifstream f(argv[1]); if (!f) { cout << "Cannot open file: " << argv[1] << std::endl; return 1; } QFile file_syntax(":/plsql.rules"); if (!file_syntax.open(QIODevice::ReadOnly | QIODevice::Text)) { return 1; } QTextStream syntax_input(&file_syntax); Syntax syntax; syntax.readRules(syntax_input); syntax.print(); LexicalAnalyzer lexems(f); // auto input_name = argv[1]; // try { // while(true) { // LexemPtr lexem = lexems.nextLexem(); // prinLexem(lexem,cout); // } // } catch (const LexicalExceptionEndOfStream&) { // cout << input_name // << ':' << lexems.currentReadPos().row // << ':' << lexems.currentReadPos().column << ": " // <<"End of file reached." << std::endl; // } catch (const LexicalException& e) { // cout << input_name // << ':' << lexems.currentReadPos().row // << ':' << lexems.currentReadPos().column << ": " // << "Lexical error: " << e.what() << std::endl; // } // lexems.setCurrentLexemIndex(0); try { syntax.buildTree(lexems); } catch (const SyntaxException& e) { cout << e.what() << std::endl; return 1; } catch (const LexicalException& e) { cout << e.what() << std::endl; return 1; } syntax.getCurTree()->print(); cout << std::endl; Context context; try { context.parseBlocks(syntax.getCurTree()); context.parseVariablesInCurrentBlocks(); context.printVariablesInCurrentBlocks(); } catch (const ContextException& e) { cout << e.what() << std::endl; return 1; } CodeGenerator code; code.generate(syntax.getCurTree()); cout << std::endl << STR("Generated code:") << std::endl << code << std::endl; return 0; }
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); /*QSettings test("test.ini", QSettings::IniFormat); test.beginGroup("compiler"); test.setValue("test-value", "asd"); test.setValue("other-value", "val"); test.endGroup(); test.beginGroup("opt"); test.setValue("test-value2", "asd2"); test.setValue("other-value2", "val2"); test.endGroup(); test.sync(); return 0;*/ QTime bigTimer; bigTimer.start(); QStringList params = a.arguments(); if (params.size() != 2) { qCritical() << "Expecting file to compile"; return 0; } ErrorHandler errHandler; Settings settings; bool success = false; success = settings.loadDefaults(); if (!success) { errHandler.error(ErrorCodes::ecSettingsLoadingFailed, errHandler.tr("Loading the default settings \"%1\" failed").arg(settings.loadPath()), CodePoint()); return ErrorCodes::ecSettingsLoadingFailed; } Lexer lexer; QObject::connect(&lexer, &Lexer::error, &errHandler, &ErrorHandler::error); QObject::connect(&lexer, &Lexer::warning, &errHandler, &ErrorHandler::warning); QTime timer; timer.start(); if (lexer.tokenizeFile(params[1], settings) == Lexer::Success) { qDebug() << "Lexical analysing took " << timer.elapsed() << "ms"; #ifdef DEBUG_OUTPUT lexer.writeTokensToFile("tokens.txt"); #endif } else { errHandler.error(ErrorCodes::ecLexicalAnalysingFailed, errHandler.tr("Lexical analysing failed"), CodePoint(lexer.files().first().first)); return ErrorCodes::ecLexicalAnalysingFailed; } Parser parser; QObject::connect(&parser, &Parser::error, &errHandler, &ErrorHandler::error); QObject::connect(&parser, &Parser::warning, &errHandler, &ErrorHandler::warning); timer.start(); ast::Program *program = parser.parse(lexer.tokens(), settings); qDebug() << "Parsing took " << timer.elapsed() << "ms"; if (!parser.success()) { errHandler.error(ErrorCodes::ecParsingFailed, errHandler.tr("Parsing failed \"%1\"").arg(params[1]), CodePoint()); return ErrorCodes::ecParsingFailed; } #ifdef DEBUG_OUTPUT if (program) { QFile file("ast.txt"); if (file.open(QFile::WriteOnly)) { QTextStream stream(&file); program->write(stream); file.close(); } } #endif CodeGenerator codeGenerator; //QObject::connect(&codeGenerator, &CodeGenerator::error, &errHandler, &ErrorHandler::error); //QObject::connect(&codeGenerator, &CodeGenerator::warning, &errHandler, &ErrorHandler::warning); QObject::connect(&codeGenerator, &CodeGenerator::error, &errHandler, &ErrorHandler::error); QObject::connect(&codeGenerator, &CodeGenerator::warning, &errHandler, &ErrorHandler::warning); timer.start(); if (!codeGenerator.initialize(settings)) { return ErrorCodes::ecCodeGeneratorInitializationFailed; } qDebug() << "Code generator initialization took " << timer.elapsed() << "ms"; timer.start(); if (!codeGenerator.generate(program)) { errHandler.error(ErrorCodes::ecCodeGenerationFailed, errHandler.tr("Code generation failed"), CodePoint()); return ErrorCodes::ecCodeGenerationFailed; } qDebug() << "Code generation took" << timer.elapsed() << "ms"; qDebug() << "LLVM-IR generated"; timer.start(); codeGenerator.createExecutable(settings.defaultOutputFile()); qDebug() << "Executable generation took " << timer.elapsed() << "ms"; qDebug() << "The whole compilation took " << bigTimer.elapsed() << "ms"; return 0; }
int main(int argc, char** argv) { try { std::map<std::string, std::string> engines; ObjectFactory<std::string, Engine> engineFactory; ENGINE("groovie", "Groovie", Groovie::GroovieEngine); ENGINE("kyra2", "Legend of Kyrandia: Hand of Fate", Kyra::Kyra2Engine); ENGINE("scummv6", "SCUMM v6", Scumm::v6::Scummv6Engine); po::options_description visible("Options"); visible.add_options() ("help,h", "Produce this help message.") ("engine,e", po::value<std::string>(), "Engine the script originates from.") ("list,l", "List the supported engines.") ("dump-disassembly,d", po::value<std::string>()->implicit_value(""), "Dump the disassembly to a file. Leave out filename to output to stdout.") ("dump-graph,g", po::value<std::string>()->implicit_value(""), "Output the control flow graph in dot format to a file. Leave out filename to output to stdout.") ("only-disassembly,D", "Stops after disassembly. Implies -d.") ("only-graph,G", "Stops after control flow graph has been generated. Implies -g.") ("show-unreachable,u", "Show the address and contents of unreachable groups in the script.") ("variant,v", po::value<std::string>()->default_value(""), "Tell the engine that the script is from a specific variant. To see a list of variants supported by a specific engine, use the -h option and the -e option together.") ("no-stack-effect,s", "Leave out the stack effect when printing raw instructions."); po::options_description args(""); args.add(visible).add_options() ("input-file", po::value<std::string>(), "Input file"); po::positional_options_description fileArg; fileArg.add("input-file", -1); po::variables_map vm; try { // FIXME: If specified as the last parameter before the input file name, -d currently requires a filename to specified. -d must be specified earlier than that if outputting to stdout. po::store(po::command_line_parser(argc, argv).options(args).positional(fileArg).run(), vm); po::notify(vm); } catch (std::exception& e) { std::cout << e.what() << std::endl; } if (vm.count("list")) { std::cout << "Available engines:" << "\n"; std::map<std::string, std::string>::iterator it; for (it = engines.begin(); it != engines.end(); it++) std::cout << (*it).first << " " << (*it).second << "\n"; return 0; } if (vm.count("help") || !vm.count("input-file")) { std::cout << "Usage: " << argv[0] << " [option...] file" << "\n"; std::cout << visible << "\n"; if (vm.count("engine") && engines.find(vm["engine"].as<std::string>()) != engines.end()) { Engine *engine = engineFactory.create(vm["engine"].as<std::string>()); std::vector<std::string> variants; engine->getVariants(variants); if (variants.empty()) { std::cout << engines[vm["engine"].as<std::string>()] << " does not use variants.\n"; } else { std::cout << "Supported variants for " << engines[vm["engine"].as<std::string>()] << ":\n"; for (std::vector<std::string>::iterator i = variants.begin(); i != variants.end(); ++i) { std::cout << " " << *i << "\n"; } } delete engine; std::cout << "\n"; } std::cout << "Note: If outputting to stdout, -d or -g must NOT be specified immediately before the input file.\n"; return 1; } if (!vm.count("engine")) { std::cout << "Engine must be specified.\n"; return 2; } else if (engines.find(vm["engine"].as<std::string>()) == engines.end()) { std::cout << "Unknown engine.\n"; return 2; } if (vm.count("no-stack-effect")) { setOutputStackEffect(false); } Engine *engine = engineFactory.create(vm["engine"].as<std::string>()); engine->_variant = vm["variant"].as<std::string>(); std::string inputFile = vm["input-file"].as<std::string>(); // Disassembly InstVec insts; Disassembler *disassembler = engine->getDisassembler(insts); disassembler->open(inputFile.c_str()); disassembler->disassemble(); if (vm.count("dump-disassembly")) { std::streambuf *buf; std::ofstream of; if (vm["dump-disassembly"].as<std::string>() != "") { of.open(vm["dump-disassembly"].as<std::string>().c_str()); buf = of.rdbuf(); } else { buf = std::cout.rdbuf(); } std::ostream out(buf); disassembler->dumpDisassembly(out); } if (!engine->supportsCodeFlow() || vm.count("only-disassembly") || insts.empty()) { if (!vm.count("dump-disassembly")) { disassembler->dumpDisassembly(std::cout); } delete disassembler; delete engine; return 0; } delete disassembler; // Control flow analysis ControlFlow *cf = new ControlFlow(insts, engine); cf->createGroups(); Graph g = cf->analyze(); if (vm.count("dump-graph")) { std::streambuf *buf; std::ofstream of; if (vm["dump-graph"].as<std::string>() != "") { of.open(vm["dump-graph"].as<std::string>().c_str()); buf = of.rdbuf(); } else { buf = std::cout.rdbuf(); } std::ostream out(buf); boost::write_graphviz(out, g, boost::make_label_writer(get(boost::vertex_name, g)), boost::makeArrowheadWriter(get(boost::edge_attribute, g)), GraphProperties(engine, g)); } if (!engine->supportsCodeGen() || vm.count("only-graph")) { if (!vm.count("dump-graph")) { boost::write_graphviz(std::cout, g, boost::make_label_writer(get(boost::vertex_name, g)), boost::makeArrowheadWriter(get(boost::edge_attribute, g)), GraphProperties(engine, g)); } delete cf; delete engine; return 0; } // Post-processing of CFG engine->postCFG(insts, g); // Code generation CodeGenerator *cg = engine->getCodeGenerator(std::cout); cg->generate(g); if (vm.count("show-unreachable")) { std::vector<GroupPtr> unreachable; VertexRange vr = boost::vertices(g); for (VertexIterator v = vr.first; v != vr.second; ++v) { GroupPtr gr = boost::get(boost::vertex_name, g, *v); if (gr->_stackLevel == -1) unreachable.push_back(gr); } if (!unreachable.empty()) { for (size_t i = 0; i < unreachable.size(); i++) { if (i == 0) { if (unreachable.size() == 1) std::cout << boost::format("\n%d unreachable group detected.\n") % unreachable.size(); else std::cout << boost::format("\n%d unreachable groups detected.\n") % unreachable.size(); } std::cout << "Group " << (i + 1) << ":\n"; ConstInstIterator inst = unreachable[i]->_start; do { std::cout << *inst; } while (inst++ != unreachable[i]->_end); std::cout << "----------\n"; } } } // Free memory delete cf; delete cg; delete engine; } catch (UnknownOpcodeException &e) { std::cerr << "ERROR: " << e.what() << "\n"; return 3; } catch (std::exception &e) { std::cerr << "ERROR: " << e.what() << "\n"; return 4; } return 0; }