cminus/main/Main.java

110 lines
3.8 KiB
Java

package main;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import parser.CminusLexer;
import parser.CminusParser;
import submit.ASTVisitor;
import org.antlr.v4.runtime.Parser;
import submit.RegisterAllocator;
import submit.SymbolTable;
import submit.ast.Node;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
private static Logger LOGGER;
/**
* @param args the command line arguments
* @throws java.io.IOException
*/
public static void main(String[] args) throws IOException {
// Logging setup
Level level = Level.INFO;
// TODO Enable trace-level code as needed. When true, LOGGER.fine() statements
// will be visible.
final boolean trace = true;
if (trace) {
level = Level.ALL;
}
Properties props = System.getProperties();
props.setProperty("java.util.logging.SimpleFormatter.format", "%5$s%6$s%n");
Logger.getLogger("").setLevel(level);
for (Handler handler : Logger.getLogger("").getHandlers()) {
handler.setLevel(level);
}
LOGGER = Logger.getLogger(Parser.class.getName());
if (args.length < 1) {
throw new RuntimeException("Be sure to add your test C- file as a command-line parameter.");
}
final String filename = args[0];
LOGGER.info("");
LOGGER.info("Parsing " + filename + "\n");
LOGGER.info("");
final CharStream charStream = CharStreams.fromFileName(filename);
CminusLexer lexer = new CminusLexer(charStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
CminusParser parser = new CminusParser(tokens);
parser.setBuildParseTree(true);
CminusParser.ProgramContext programCtx = parser.program();
LOGGER.info("");
LOGGER.info("Building abstract syntax tree");
LOGGER.info("");
ASTVisitor v = new ASTVisitor(LOGGER);
Node ast = v.visitProgram(programCtx);
SymbolTable symbolTable = v.getSymbolTable();
LOGGER.info("");
LOGGER.info("MIPS code:");
LOGGER.info("");
StringBuilder code = new StringBuilder();
StringBuilder data = new StringBuilder();
RegisterAllocator regAllocator = new RegisterAllocator();
try {
ast.toMIPS(code, data, symbolTable, regAllocator);
} finally {
StringBuilder mips = new StringBuilder();
mips.append("# All program code is placed after the\n" +
"# .text assembler directive\n" +
".text\n" +
"\n" +
"# Declare main as a global function\n" +
".globl\tmain\n\nj main\n");
mips.append(code.toString());
mips.append("\n# All memory structures are placed after the\n" +
"# .data assembler directive\n" +
".data\n" +
"\n");
mips.append(data.toString());
// Write MIPS code to stdout
LOGGER.info(mips.toString());
// Write MIPS code to output file for easy loading into MARS
final String fn = filename.substring(0, filename.length() - 1) + "asm";
try {
FileWriter myWriter = new FileWriter(fn);
myWriter.write(mips.toString());
myWriter.close();
} catch (IOException e) {
LOGGER.severe("Error writing to file " + fn + "\n");
e.printStackTrace();
}
}
}
}