7ea9362de66b9d1660172afdc5f46c6ccf59e3a2
[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                 NaiveGenerator ng = new NaiveGenerator(state);
80                 ng.generate(gcode);
81                 gcode.close();
82             } catch (Exception e) {
83                 e.printStackTrace();
84                 System.exit(-1);
85             }
86             
87             if (state.debug) {
88                 System.out.println("Compilation of " + state.infile + " successful.");
89                 System.out.println("#SUCCESS#");
90             }
91         } else if (cli.target == CLI.INTER) {
92             if (state.debug) {
93                 System.out.println("Semantic analysis for " + cli.infile + ".");
94             }
95
96             success = scan(state) || error(state, "Scanning failed, not attempting to parse.");
97             success = parse(state) || error(state, "Parsing failed, not attempting semantic analysis.");
98             success = semantics(state) || error(state, "Semantic analysis failed.");
99
100             if (state.debug) {
101                 System.out.println("Semantic analysis of " + state.infile + " successful.");
102                 System.out.println("#SUCCESS#");
103             }
104         } else if (cli.target == CLI.PARSE) {
105             if (state.debug) {
106                 System.out.println("Parsing " + cli.infile + ".");
107             }
108
109             success = scan(state) || error(state, "Scanning failed, not attempting to parse.");
110             success = parse(state) || error(state, "Parsing failed.");
111
112             if (state.debug) {
113                 System.out.println("Parsing of " + state.infile + " successful.");
114                 System.out.println("#SUCCESS#");
115             }
116         } else if (cli.target == CLI.SCAN) {
117             if (state.debug) {
118                 System.out.println("Scanning " + cli.infile + ".");
119             }
120
121             success = scan(state) || error(state, "Scanning failed.");
122
123             if (state.debug) {
124                 System.out.println("Scanning of " + state.infile + " successful.");
125                 System.out.println("#SUCCESS#");
126             }
127         }
128     }
129
130     private static void printArgInfo(CLI cli) {
131         if (cli.debug) {
132             System.out.println("Printing debugging information...");
133             System.out.println("Input filename: " + cli.infile);
134             System.out.println("Output filename: " + cli.outfile);
135             System.out.print("Target: ");
136
137             switch(cli.target) {
138             case CLI.ASSEMBLY:
139                 System.out.println("ASSEMBLY");
140                 break;
141             case CLI.DEFAULT:
142                 System.out.println("DEFAULT");
143                 break;
144             case CLI.INTER:
145                 System.out.println("INTER");
146                 break;
147             case CLI.LOWIR:
148                 System.out.println("LOWIR");
149                 break;
150             case CLI.PARSE:
151                 System.out.println("PARSE");
152                 break;
153             case CLI.SCAN:
154                 System.out.println("SCAN");
155                 break;
156             default:
157                 System.out.println("not recognized");
158                 break;
159             }
160
161             for (int i = 0; i < cli.opts.length; i++) {
162                 if (cli.opts[i]) {
163                     System.out.println("Optimization");
164                 }
165             }
166         }
167
168         for (int i = 0; i < cli.extraopts.size(); i++) {
169             System.err.println("Warning: optimization \"" +
170                                cli.extraopts.elementAt(i) +
171                                "\" not recognized");
172         }
173
174         for (int i = 0; i < cli.extras.size(); i++) {
175             System.err.println("Warning: option \"" +
176                                cli.extras.elementAt(i) +
177                                "\" not recognized");
178         }
179     }
180
181     private static boolean error(State state, String error) {
182         System.err.println(error);
183         if (state.debug) {
184             System.out.println("#ERROR#");
185         }
186         System.exit(-1);
187         return false;
188     }
189
190     public static boolean semantics(State state) {
191         SimpleIRErrorReporter er = new SimpleIRErrorReporter();
192         SemanticChecker checker = new SemanticChecker();
193         boolean ok = true;
194
195         try {
196             ok = checker.check(state, er);
197         } catch (Exception e) {
198             er.report(null, e.toString());
199             e.printStackTrace();
200             er.error = true;
201         }
202
203         if (!ok) {
204             er.report(null, "Semantic check failed.");
205         }
206
207         System.out.print(er.toString());
208
209         return !er.error;
210     }
211
212     public static void debugMessage(int level, String s) {
213         if (State.currentState.verbose >= level) {
214             System.err.println(s);
215         }
216     }
217
218     public static boolean parse(State state) {
219         
220         /* parse structure file */
221         try {
222             debugMessage(1, "Parsing structure file");
223             LineCount.reset();
224             FileInputStream infile = new FileInputStream(state.infile + ".struct");
225             TDLParser parser = new TDLParser(new Lexer(infile));
226             CUP$TDLParser$actions.debug = state.verbose > 1 ;
227             state.ptStructures = (ParseNode) parser.parse().value;
228         } catch (FileNotFoundException fnfe) {
229             System.err.println("Unable to open file: " + state.infile + ".struct");
230             System.exit(-1);
231         } catch (Exception e) {
232             //      System.out.println(e);
233             //      e.printStackTrace();
234             return false;
235         }
236
237         /* parse model file */
238         try {
239             debugMessage(1, "Parsing model file");
240             LineCount.reset();
241             FileInputStream infile = new FileInputStream(state.infile + ".model");
242             MDLParser parser = new MDLParser(new Lexer(infile));
243             CUP$MDLParser$actions.debug = state.verbose > 1 ;
244             state.ptModel = (ParseNode) parser.parse().value;
245         } catch (FileNotFoundException fnfe) {
246             System.err.println("Unable to open file: " + state.infile + ".model");
247             System.exit(-1);
248         } catch (Exception e) {
249             //      System.out.println(e);
250             //      e.printStackTrace();
251             return false;
252         }
253
254         /* parse space file */
255         try {
256             debugMessage(1, "Parsing space file");
257             LineCount.reset();
258             FileInputStream infile = new FileInputStream(state.infile + ".space");
259             SDLParser parser = new SDLParser(new Lexer(infile));
260             CUP$SDLParser$actions.debug = state.verbose > 1 ;
261             state.ptSpace = (ParseNode) parser.parse().value;
262         } catch (FileNotFoundException fnfe) {
263             System.err.println("Unable to open file: " + state.infile + ".space");
264             System.exit(-1);
265         } catch (Exception e) {
266             //      System.out.println(e);
267             //      e.printStackTrace();
268             return false;
269         }
270
271         /* parse constraints file */
272         try {
273             debugMessage(1, "Parsing constraints file");
274             LineCount.reset();
275             FileInputStream infile = new FileInputStream(state.infile + ".constraints");
276             CDLParser parser = new CDLParser(new Lexer(infile));
277             CUP$CDLParser$actions.debug = state.verbose > 1 ;
278             state.ptConstraints = (ParseNode) parser.parse().value;
279         } catch (FileNotFoundException fnfe) {
280             System.err.println("Unable to open file: " + state.infile + ".constraints");
281             System.exit(-1);
282         } catch (Exception e) {
283             //      System.out.println(e);
284             //      e.printStackTrace();
285             return false;
286         }
287
288         boolean success = 
289             !CUP$TDLParser$actions.errors && 
290             !CUP$SDLParser$actions.errors && 
291             !CUP$CDLParser$actions.errors && 
292             !CUP$MDLParser$actions.errors;
293
294                 
295         // if verbosity is on, then output parse trees as .dot files
296         if (success && state.verbose > 0) {
297             try {
298                 FileOutputStream dotfile;
299
300                 dotfile = new FileOutputStream(state.infile + ".struct.dot");
301                 ParseNodeDOTVisitor.visit(dotfile, state.ptStructures);                
302                 dotfile.close();
303
304                 dotfile = new FileOutputStream(state.infile + ".model.dot");
305                 ParseNodeDOTVisitor.visit(dotfile, state.ptModel);                
306                 dotfile.close();
307
308                 dotfile = new FileOutputStream(state.infile + ".space.dot");
309                 ParseNodeDOTVisitor.visit(dotfile, state.ptSpace);                
310                 dotfile.close();
311
312                 dotfile = new FileOutputStream(state.infile + ".constraints.dot");
313                 ParseNodeDOTVisitor.visit(dotfile, state.ptConstraints);                
314                 dotfile.close();
315             } catch (Exception e) {
316                 e.printStackTrace();
317                 return false;
318             }
319         }
320             
321         return success;
322     }
323
324
325     public static boolean scan(State state) {
326         FileInputStream infile = null;
327         Lexer lexer;
328         boolean errors = false;
329         String files[] = { new String(state.infile + ".struct"),
330                            new String(state.infile + ".model"),
331                            new String(state.infile + ".constraints"),
332                            new String(state.infile + ".space") };
333
334
335
336         for (int i = 0; i < files.length; i++) {
337
338             String filename = files[i];
339
340             try {
341                 infile = new FileInputStream(filename);
342             } catch (FileNotFoundException fnfe) {
343                 System.err.println("Unable to open file: " + filename);
344                 System.exit(-1);
345             }
346             
347             lexer = new Lexer(infile);
348
349             
350             try {
351                 while (true) {
352                     java_cup.runtime.Symbol symbol;
353                     
354                     symbol = lexer.next_token();
355                     
356                     if (symbol.sym == Sym.EOF) {
357                         break;
358                     } else if (symbol.sym == Sym.BAD) {
359                         errors = true;
360                     }
361                     
362                     if (State.verbose > 2) {
363                         System.out.println("Got token: " + symbol.value);
364                     }
365                 }
366             } catch (Exception e) {
367                 return false;
368             }
369         }
370
371         return !errors;
372     }
373
374
375 }
376