-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCompiler.java
112 lines (89 loc) · 3.66 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
104
105
106
107
108
109
110
111
112
package rs.ac.bg.etf.pp1;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Files;
import java_cup.runtime.Symbol;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import rs.ac.bg.etf.pp1.ast.Program;
import rs.ac.bg.etf.pp1.util.CommonUtils;
import rs.ac.bg.etf.pp1.util.Log4JUtils;
import rs.etf.pp1.mj.runtime.Code;
import rs.etf.pp1.symboltable.Tab;
public class Compiler {
private static final Logger log = Logger.getLogger(Compiler.class);
private static Reader reader = null;
private static File sourceFile = null;
private static MJParser parser = null;
private static Program prog = null;
static {
DOMConfigurator.configure(Log4JUtils.instance().findLoggerConfigFile());
Log4JUtils.instance().prepareLogFile(Logger.getRootLogger());
}
public static void main(String[] args) {
try {
if (args.length < 2) {
log.error("Specify command line arguments.");
return;
}
// Print the path to the source file
String sourceFilePath = args[0];
String objFilePath = args[1];
sourceFile = new File(sourceFilePath);
log.info("Compiling source file: " + sourceFile.getAbsolutePath());
// Perform lexical and syntax analysis
lexicalAndSyntaxAnalysis();
// Initialize symbol table
CommonUtils.initSymbolTable();
// Perform semantic analysis and code generation
semanticAnalysisAndCodeGeneration(objFilePath);
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally { // Close the opened input file
if (reader != null) try {
reader.close();
} catch (IOException e1) {
log.error(e1.getMessage(), e1);
}
}
}
private static void lexicalAndSyntaxAnalysis() throws Exception {
// Lexical and syntax analysis
reader = new BufferedReader(new FileReader(sourceFile));
Yylex lexer = new Yylex(reader);
parser = new MJParser(lexer);
Symbol s = parser.parse();
prog = (Program) (s.value);
}
private static void semanticAnalysisAndCodeGeneration(String objFilePath) throws Exception {
// Perform semantic analysis
SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer();
log.info("\n\nSemantic analysis:");
prog.traverseBottomUp(semanticAnalyzer);
// Print the symbol table
log.info("===================================");
Tab.dump();
// Code generation
if (!parser.errorDetected && semanticAnalyzer.semanticAnalysisPassed()) {
// Code is syntactically and semantically correct
log.info("Parsing has been successfully completed!");
// Open the object file
File objFile = new File(objFilePath);
if (objFile.exists()) objFile.delete();
// Traverse the tree and generate code into a buffer
CodeGenerator cg = new CodeGenerator();
prog.traverseBottomUp(cg);
// Set values for 'mainPC' and 'dataSize'
Code.mainPc = cg.getMainPC();
Code.dataSize = semanticAnalyzer.getNumberOfVariables();
// Write from buffer to object file
Code.write(Files.newOutputStream(objFile.toPath()));
log.info("Code generation successfully completed!");
} else {
log.error("Semantic analysis and code generation were NOT successfully completed.");
}
}
}