#include #include #include #include "3rdparty/easylogging++.h" #include "BaseErrorListener.h" #include "Exceptions.h" #include "antlr4-runtime.h" #include "antlrgen/SysyLexer.h" #include "antlrgen/SysyParser.h" #include <3rdparty/argparse.hpp> #include "common.h" #include "visitor.h" INITIALIZE_EASYLOGGINGPP using namespace antlrSysY; using namespace antlr4; class AbortErrorListener : public BaseErrorListener { public: void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line, size_t charPositionInLine, const std::string &msg, std::exception_ptr e) override { throw ParseCancellationException("line " + std::to_string(line) + ":" + std::to_string(charPositionInLine) + " " + msg); } }; int main(int argc, const char **argv) { #pragma region ArgParse argparse::ArgumentParser arg_parser("Catfood's SysY Compiler"); arg_parser.add_argument("source").help("A single SysY source file"); arg_parser.add_argument("-S").implicit_value(true).help("Useless but required by the contest").required(); arg_parser.add_argument("-o").help("Output file name").required(); arg_parser.add_argument("-O1").implicit_value(true).default_value(false).help("Performance mode"); try { arg_parser.parse_args(argc, argv); } catch (const std::runtime_error &err) { std::cerr << err.what() << std::endl; std::cerr << arg_parser; std::exit(1); } auto source_file = arg_parser.get("source"); auto output_file = arg_parser.get("-o"); auto flg_O1 = arg_parser["-O1"] == true; // std::cout << source_file << " " << output_file << " " << flg_O1 << // std::endl; #pragma endregion #pragma region Logger el::Configurations defaultConf; defaultConf.setToDefault(); defaultConf.set(el::Level::Debug, el::ConfigurationType::Format, "%level %loc %msg"); defaultConf.set(el::Level::Warning, el::ConfigurationType::Format, "%level %loc %msg"); defaultConf.set(el::Level::Error, el::ConfigurationType::Format, "%level %loc %msg"); el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput); el::Loggers::reconfigureLogger("default", defaultConf); #pragma endregion std::ifstream ifs_source_file(source_file); ANTLRInputStream input(ifs_source_file); SysyLexer lexer(&input); CommonTokenStream tokens(&lexer); #if 0 tokens.fill(); for (auto token : tokens.getTokens()) { std::cout << token->toString() << std::endl; } #endif SysyParser parser(&tokens); parser.removeErrorListeners(); parser.addErrorListener(new AbortErrorListener()); auto tree = parser.program(); Visitor visitor(lexer); visitor.visitProgram(tree); #if 0 std::cout << tree->toStringTree(&parser) << std::endl << std::endl; #endif return 0; }