Main.java 4.05 KiB
package cn.edu.nju.software;
import java.io.IOException;
import java.util.Arrays;
import cn.edu.nju.software.backend.RiscModule;
import cn.edu.nju.software.pass.PassManager;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import cn.edu.nju.software.frontend.lexer.LexerErrorListener;
import cn.edu.nju.software.frontend.lexer.SysYLexer;
import cn.edu.nju.software.frontend.parser.ParserErrorListener;
import cn.edu.nju.software.frontend.parser.SysYParser;
import cn.edu.nju.software.frontend.semantic.SysYSemanticVisitor;
import cn.edu.nju.software.ir.generator.IRVisitor;
import cn.edu.nju.software.ir.module.ModuleRef;
public class Main {
    private static String input;
    private static String output;
    private static boolean optimized = false;
    private static boolean emitLLVM = false;
    private static boolean emitAssembly = false;
    public static void main(String... args) {
        Thread t = new Thread(() -> execute(args));
        t.start();
        try {
            t.join();
        } catch (Exception ignored) {}
    private static void execute(String... args) {
        parseArgs(args);
        if (input == null || output == null) {
            throw new RuntimeException("required input and output path");
        CharStream inputStream;
        try {
            inputStream = CharStreams.fromFileName(input);
        } catch (IOException e) {
            return;
        // lexer
        SysYLexer sysYLexer = new SysYLexer(inputStream);
        LexerErrorListener lexerErrorListener = new LexerErrorListener();
        sysYLexer.removeErrorListeners();
        sysYLexer.addErrorListener(lexerErrorListener);
        // parser
        CommonTokenStream tokens = new CommonTokenStream(sysYLexer);
        SysYParser sysYParser = new SysYParser(tokens);
        ParserErrorListener parserErrorListener = new ParserErrorListener();
        sysYParser.removeErrorListeners();
        sysYParser.addErrorListener(parserErrorListener);
        ParseTree tree = sysYParser.program();
        if (!parserErrorListener.noParseError()) {
            return;
        // semantic
        SysYSemanticVisitor semanticVisitor = new SysYSemanticVisitor();
        semanticVisitor.visit(tree);
        if (!semanticVisitor.noSemanticError()) {
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
return; } // generate llvm ir IRVisitor irVisitor = new IRVisitor(); irVisitor.visit(tree); // irVisitor.dumpModuleToConsole(); ModuleRef module = irVisitor.getModule(); if(module == null){ assert false; } if(optimized){ PassManager passManager=new PassManager(module); //TODO:调试完成后删除这句 //passManager.setDbgFlag(); passManager.runPass(); } if (emitLLVM) { module.dumpToFile(output); } if(emitAssembly){ RiscModule riscModule = new RiscModule(module); riscModule.codeGen(); riscModule.dumpToFile(output); } } private static void parseArgs(String... args) { Arrays.stream(args).forEach(arg -> { int index; switch (arg) { case "-o": index = Arrays.asList(args).indexOf(arg); output = args[index + 1]; break; case "-O0": optimized = false; break; case "-O1", "-O2": optimized = true; break; case "--emit-llvm": emitLLVM = true; break; case "-S": emitAssembly = true; break; default: index = Arrays.asList(args).indexOf(arg); if (0 == index || !"-o".equals(args[index - 1]) ) { input = arg; } } }); } }