heh
[repair.git] / Repair / RepairCompiler / MCC / Compiler.java
1 package MCC;
2
3 import java.io.*;
4 import java.util.*;
5 import MCC.IR.*;
6
7 /**
8  * The main compiler module, which does the following:
9  * <ul>
10  *  <li>
11  *   nothing.
12  *  </li> 
13  * <ul>
14  *
15  * @author <b>Daniel Roy</b> droy (at) mit (dot) edu
16  * @version %I, %G 
17  */
18
19 public class Compiler {
20     
21     public static void main(String[] args) {
22         State state = null;
23         boolean success = true;
24         CLI cli = new CLI();
25         cli.parse(args);
26         printArgInfo(cli); // prints debugging information and warning
27
28         state = new State();
29         State.currentState = state;
30         State.debug = cli.debug;
31         State.verbose = cli.verbose;
32         State.infile = cli.infile;
33         State.outfile = cli.outfile;
34
35         /*
36          * added: terminates with an error message if no input file
37          * specified at command line
38          */
39
40         System.out.println("\nMCC v0.0.1 - MIT LCS (Author: Daniel Roy, Brian Demsky)");
41
42         if (cli.infile == null) {
43             System.err.println("\nError: no input file specified");
44             System.exit(-1);
45         }
46         
47         if (cli.target == CLI.ASSEMBLY || cli.target == CLI.DEFAULT) {
48             if (state.debug) {
49                 System.out.println("Compiling " + cli.infile + ".");
50             }
51
52             success = scan(state) || error(state, "Scanning failed, not attempting to parse.");
53             success = parse(state) || error(state, "Parsing failed, not attempting semantic analysis.");
54             success = semantics(state) || error(state, "Semantic analysis failed, not attempting variable initialization.");
55             
56             (new DependencyBuilder(state)).calculate();
57             
58             try {
59                 Vector nodes = new Vector(state.constraintnodes.values());
60                 nodes.addAll(state.rulenodes.values());
61
62                 FileOutputStream dotfile;
63                 dotfile = new FileOutputStream(cli.infile + ".dependencies.edgelabels.dot");
64                 GraphNode.useEdgeLabels = true;
65                 GraphNode.DOTVisitor.visit(dotfile, nodes);                
66                 dotfile.close();
67
68                 dotfile = new FileOutputStream(cli.infile + ".dependencies.dot");
69                 GraphNode.useEdgeLabels = false;
70                 GraphNode.DOTVisitor.visit(dotfile, nodes);                
71                 dotfile.close();
72             } catch (Exception e) {
73                 e.printStackTrace();
74                 System.exit(-1);
75             }
76             
77             try {
78                 FileOutputStream gcode = new FileOutputStream(cli.infile + ".cc");
79
80                 // do model optimizations
81                 (new Optimizer(state)).optimize();
82
83                 NaiveGenerator ng = new NaiveGenerator(state);
84                 ng.generate(gcode);
85                 //WorklistGenerator wg = new WorklistGenerator(state);
86                 //wg.generate(gcode);
87                 gcode.close();
88             } catch (Exception e) {
89                 e.printStackTrace();
90                 System.exit(-1);
91             }
92             
93             if (state.debug) {
94                 System.out.println("Compilation of " + state.infile + " successful.");
95                 System.out.println("#SUCCESS#");
96             }
97         } else if (cli.target == CLI.INTER) {
98             if (state.debug) {
99                 System.out.println("Semantic analysis for " + cli.infile + ".");
100             }
101
102             success = scan(state) || error(state, "Scanning failed, not attempting to parse.");
103             success = parse(state) || error(state, "Parsing failed, not attempting semantic analysis.");
104             success = semantics(state) || error(state, "Semantic analysis failed.");
105
106             if (state.debug) {
107                 System.out.println("Semantic analysis of " + state.infile + " successful.");
108                 System.out.println("#SUCCESS#");
109             }
110         } else if (cli.target == CLI.PARSE) {
111             if (state.debug) {
112                 System.out.println("Parsing " + cli.infile + ".");
113             }
114
115             success = scan(state) || error(state, "Scanning failed, not attempting to parse.");
116             success = parse(state) || error(state, "Parsing failed.");
117
118             if (state.debug) {
119                 System.out.println("Parsing of " + state.infile + " successful.");
120                 System.out.println("#SUCCESS#");
121             }
122         } else if (cli.target == CLI.SCAN) {
123             if (state.debug) {
124                 System.out.println("Scanning " + cli.infile + ".");
125             }
126
127             success = scan(state) || error(state, "Scanning failed.");
128
129             if (state.debug) {
130                 System.out.println("Scanning of " + state.infile + " successful.");
131                 System.out.println("#SUCCESS#");
132             }
133         }
134     }
135
136     private static void printArgInfo(CLI cli) {
137         if (cli.debug) {
138             System.out.println("Printing debugging information...");
139             System.out.println("Input filename: " + cli.infile);
140             System.out.println("Output filename: " + cli.outfile);
141             System.out.print("Target: ");
142
143             switch(cli.target) {
144             case CLI.ASSEMBLY:
145                 System.out.println("ASSEMBLY");
146                 break;
147             case CLI.DEFAULT:
148                 System.out.println("DEFAULT");
149                 break;
150             case CLI.INTER:
151                 System.out.println("INTER");
152                 break;
153             case CLI.LOWIR:
154                 System.out.println("LOWIR");
155                 break;
156             case CLI.PARSE:
157                 System.out.println("PARSE");
158                 break;
159             case CLI.SCAN:
160                 System.out.println("SCAN");
161                 break;
162             default:
163                 System.out.println("not recognized");
164                 break;
165             }
166
167             for (int i = 0; i < cli.opts.length; i++) {
168                 if (cli.opts[i]) {
169                     System.out.println("Optimization");
170                 }
171             }
172         }
173
174         for (int i = 0; i < cli.extraopts.size(); i++) {
175             System.err.println("Warning: optimization \"" +
176                                cli.extraopts.elementAt(i) +
177                                "\" not recognized");
178         }
179
180         for (int i = 0; i < cli.extras.size(); i++) {
181             System.err.println("Warning: option \"" +
182                                cli.extras.elementAt(i) +
183                                "\" not recognized");
184         }
185     }
186
187     private static boolean error(State state, String error) {
188         System.err.println(error);
189         if (state.debug) {
190             System.out.println("#ERROR#");
191         }
192         System.exit(-1);
193         return false;
194     }
195
196     public static boolean semantics(State state) {
197         SimpleIRErrorReporter er = new SimpleIRErrorReporter();
198         SemanticChecker checker = new SemanticChecker();
199         boolean ok = true;
200
201         try {
202             ok = checker.check(state, er);
203         } catch (Exception e) {
204             er.report(null, e.toString());
205             e.printStackTrace();
206             er.error = true;
207         }
208
209         if (!ok) {
210             er.report(null, "Semantic check failed.");
211         }
212
213         System.out.print(er.toString());
214
215         return !er.error;
216     }
217
218     public static void debugMessage(int level, String s) {
219         if (State.currentState.verbose >= level) {
220             System.err.println(s);
221         }
222     }
223
224     public static boolean parse(State state) {
225         
226         /* parse structure file */
227         try {
228             debugMessage(1, "Parsing structure file");
229             LineCount.reset();
230             FileInputStream infile = new FileInputStream(state.infile + ".struct");
231             TDLParser parser = new TDLParser(new Lexer(infile));
232             CUP$TDLParser$actions.debug = state.verbose > 1 ;
233             state.ptStructures = (ParseNode) parser.parse().value;
234         } catch (FileNotFoundException fnfe) {
235             System.err.println("Unable to open file: " + state.infile + ".struct");
236             System.exit(-1);
237         } catch (Exception e) {
238             //      System.out.println(e);
239             //      e.printStackTrace();
240             return false;
241         }
242
243         /* parse model file */
244         try {
245             debugMessage(1, "Parsing model file");
246             LineCount.reset();
247             FileInputStream infile = new FileInputStream(state.infile + ".model");
248             MDLParser parser = new MDLParser(new Lexer(infile));
249             CUP$MDLParser$actions.debug = state.verbose > 1 ;
250             state.ptModel = (ParseNode) parser.parse().value;
251         } catch (FileNotFoundException fnfe) {
252             System.err.println("Unable to open file: " + state.infile + ".model");
253             System.exit(-1);
254         } catch (Exception e) {
255             //      System.out.println(e);
256             //      e.printStackTrace();
257             return false;
258         }
259
260         /* parse space file */
261         try {
262             debugMessage(1, "Parsing space file");
263             LineCount.reset();
264             FileInputStream infile = new FileInputStream(state.infile + ".space");
265             SDLParser parser = new SDLParser(new Lexer(infile));
266             CUP$SDLParser$actions.debug = state.verbose > 1 ;
267             state.ptSpace = (ParseNode) parser.parse().value;
268         } catch (FileNotFoundException fnfe) {
269             System.err.println("Unable to open file: " + state.infile + ".space");
270             System.exit(-1);
271         } catch (Exception e) {
272             //      System.out.println(e);
273             //      e.printStackTrace();
274             return false;
275         }
276
277         /* parse constraints file */
278         try {
279             debugMessage(1, "Parsing constraints file");
280             LineCount.reset();
281             FileInputStream infile = new FileInputStream(state.infile + ".constraints");
282             CDLParser parser = new CDLParser(new Lexer(infile));
283             CUP$CDLParser$actions.debug = state.verbose > 1 ;
284             state.ptConstraints = (ParseNode) parser.parse().value;
285         } catch (FileNotFoundException fnfe) {
286             System.err.println("Unable to open file: " + state.infile + ".constraints");
287             System.exit(-1);
288         } catch (Exception e) {
289             //      System.out.println(e);
290             //      e.printStackTrace();
291             return false;
292         }
293
294         boolean success = 
295             !CUP$TDLParser$actions.errors && 
296             !CUP$SDLParser$actions.errors && 
297             !CUP$CDLParser$actions.errors && 
298             !CUP$MDLParser$actions.errors;
299
300                 
301         // if verbosity is on, then output parse trees as .dot files
302         if (success && state.verbose > 0) {
303             try {
304                 FileOutputStream dotfile;
305
306                 dotfile = new FileOutputStream(state.infile + ".struct.dot");
307                 ParseNodeDOTVisitor.visit(dotfile, state.ptStructures);                
308                 dotfile.close();
309
310                 dotfile = new FileOutputStream(state.infile + ".model.dot");
311                 ParseNodeDOTVisitor.visit(dotfile, state.ptModel);                
312                 dotfile.close();
313
314                 dotfile = new FileOutputStream(state.infile + ".space.dot");
315                 ParseNodeDOTVisitor.visit(dotfile, state.ptSpace);                
316                 dotfile.close();
317
318                 dotfile = new FileOutputStream(state.infile + ".constraints.dot");
319                 ParseNodeDOTVisitor.visit(dotfile, state.ptConstraints);                
320                 dotfile.close();
321             } catch (Exception e) {
322                 e.printStackTrace();
323                 return false;
324             }
325         }
326             
327         return success;
328     }
329
330
331     public static boolean scan(State state) {
332         FileInputStream infile = null;
333         Lexer lexer;
334         boolean errors = false;
335         String files[] = { new String(state.infile + ".struct"),
336                            new String(state.infile + ".model"),
337                            new String(state.infile + ".constraints"),
338                            new String(state.infile + ".space") };
339
340
341
342         for (int i = 0; i < files.length; i++) {
343
344             String filename = files[i];
345
346             try {
347                 infile = new FileInputStream(filename);
348             } catch (FileNotFoundException fnfe) {
349                 System.err.println("Unable to open file: " + filename);
350                 System.exit(-1);
351             }
352             
353             lexer = new Lexer(infile);
354
355             
356             try {
357                 while (true) {
358                     java_cup.runtime.Symbol symbol;
359                     
360                     symbol = lexer.next_token();
361                     
362                     if (symbol.sym == Sym.EOF) {
363                         break;
364                     } else if (symbol.sym == Sym.BAD) {
365                         errors = true;
366                     }
367                     
368                     if (State.verbose > 2) {
369                         System.out.println("Got token: " + symbol.value);
370                     }
371                 }
372             } catch (Exception e) {
373                 return false;
374             }
375         }
376
377         return !errors;
378     }
379
380
381 }
382