-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCompiler.java
103 lines (90 loc) · 3.05 KB
/
Compiler.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import ast.*;
import codegen.*;
import ir.*;
import java.io.*;
import org.antlr.runtime.*;
import semantic.*;
/*
* Uses the ANTLR tool to perform lexical analysis and generate
* a parser based on the grammar for the unnamed language.
*/
public class Compiler {
private static void handleCompilationError() {
// Allows error code checking to automate testing.
System.exit(1);
}
private static String programNameFromFileName(String fileName) throws Exception {
// Remove leading directory names
var dirSeparatorIndex = fileName.lastIndexOf(File.separator);
if (dirSeparatorIndex == fileName.length()) {
throw new Exception("Input file name should not end in a " + File.separator);
}
else if (dirSeparatorIndex >= 0) {
fileName = fileName.substring(dirSeparatorIndex + 1);
}
// Move file extension
var extIndex = fileName.indexOf('.');
if (extIndex == -1) {
// No file extension is present
return fileName;
}
else if (extIndex == 0) {
throw new Exception("Input file name should not begin with a period.");
}
else {
// Remove the file extension
return fileName.substring(0, extIndex);
}
}
public static void main (String[] args) throws IOException {
if (args.length == 0) {
System.out.println("Usage: Compiler filename.ul");
return;
}
String sourceFileName = args[0];
ANTLRInputStream input;
try {
input = new ANTLRInputStream(new FileInputStream(sourceFileName));
}
catch (FileNotFoundException e) {
System.out.println(String.format("Could not open file %s", sourceFileName));
return;
}
// The name of the grammar here is "UnnamedLanguage", so ANTLR
// generates UnnamedLanguageLexer and UnnamedLanguageParser
UnnamedLanguageLexer lexer = new UnnamedLanguageLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
UnnamedLanguageParser parser = new UnnamedLanguageParser(tokens);
try {
Program astProgram = parser.program();
// Ensure the type system and language semantics are respected.
TypeCheckVisitor semanticVisitor = new TypeCheckVisitor();
semanticVisitor.visit(astProgram);
// Create the intermediate representation.
IRAstVisitor irVisitor = new IRAstVisitor();
String programName = programNameFromFileName(sourceFileName);
IRProgram irProgram = irVisitor.buildIRProgram(astProgram, programName);
// Generate Jasmin code from the IR representation and save it
// to the output file.
JasminVisitor jasminVisitor = new JasminVisitor();
jasminVisitor.visit(irProgram);
}
catch (RecognitionException e ) {
// A lexical or parsing error occured.
// ANTLR will have already printed information about the error
// to System.err.
handleCompilationError();
}
catch(SemanticException e) {
// Print out the cause of the error and positional information
// if appropriate.
System.err.println(e.getMessageWithPosition());
handleCompilationError();
}
catch (Exception e) {
System.err.println(e);
e.printStackTrace();
handleCompilationError();
}
}
}