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