Example #1
0
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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
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;
}