Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / CmdlineCompiler.java @ 7

1
/**
2
  *
3
  *                      OOAS Compiler
4
  *
5
  *       Copyright 2015, AIT Austrian Institute of Technology.
6
  * This code is based on the C# Version of the OOAS Compiler, which is
7
  * copyright 2015 by the Institute of Software Technology, Graz University
8
  * of Technology with portions copyright by the AIT Austrian Institute of
9
  * Technology. All rights reserved.
10
  *
11
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
12
  *
13
  * If you modify the file please update the list of contributors below to in-
14
  * clude your name. Please also stick to the coding convention of using TABs
15
  * to do the basic (block-level) indentation and spaces for anything after
16
  * that. (Enable the display of special chars and it should be pretty obvious
17
  * what this means.) Also, remove all trailing whitespace.
18
  *
19
  * Contributors:
20
  *               Willibald Krenn (AIT)
21
  *               Stephan Zimmerer (AIT)
22
  *               Markus Demetz (AIT)
23
  *               Christoph Czurda (AIT)
24
  *
25
  */
26

    
27

    
28
package org.momut.ooas;
29

    
30
import java.io.File;
31
import java.io.FileFilter;
32
import java.io.FileWriter;
33
import java.io.IOException;
34
import java.util.ArrayList;
35
import java.util.Iterator;
36
import java.util.List;
37

    
38
import org.momut.ooas.CompilerConfiguration.LabelCompression;
39
import org.momut.ooas.ast.IAstVisitor;
40
import org.momut.ooas.codegen.prolog.OoaPrologVisitor;
41
import org.momut.ooas.codegen.prologsymbolic.OoaPrologSymbolicVisitor;
42
import org.momut.ooas.parser.ParserError;
43
import org.momut.ooas.parser.ParserMessage;
44
import org.momut.ooas.parser.ParserState;
45
import org.momut.ooas.parser.ParserWarning;
46
import org.momut.ooas.parser.ooaCustomParser;
47
import org.momut.ooas.visitors.OoaActionClassifierVisitor;
48
import org.momut.ooas.visitors.OoaMethodPureClassifierVisitor;
49
import org.momut.ooas.visitors.OoaObjectInstantiationVisitor;
50
import org.momut.ooas.visitors.OoaReplaceOpaqueVisitor;
51
import org.momut.ooas.visitors.OoaResolveExpressionsVisitor;
52
import org.momut.ooas.visitors.OoaSymbolSortVisitor;
53
import org.momut.ooas.visitors.OoaTypeCheckVisitor;
54
import org.momut.ooas.visitors.OoaTypeRenameVisitor;
55
import org.momut.ooas.visitors.OoaTypesVisitor;
56
import org.momut.ooas.visitors.optimisation.OoaRemoveTrivialPrioritizedCompositionVisitor;
57

    
58
public final class CmdlineCompiler
59
{
60
        public interface CreateVisitor {
61
                public IAstVisitor cerate(ParserState aState);
62
        }
63

    
64
        public static class Options
65
        {
66
                public boolean quiet = false;
67
                public String fileToParse = "";
68
                public String outputToFile = "";
69
                public String namedTypePrefix = "";
70
                public String namespace = "";
71
                public ArrayList<CreateVisitor> pipeLine = new ArrayList<CreateVisitor>();
72
        }
73

    
74
        static void displayTitle()
75
        {
76
                System.out.println();
77
                System.out.println("          >> OO-Action System Parser <<");
78
                System.out.println();
79
                System.out.println();
80
        }
81

    
82

    
83
        /* fire up the parser */
84
        static int runAntlrParser(Options options)
85
        {
86
                ParserState pState;
87
                try {
88
                        pState = new ParserState(options.fileToParse, options.namedTypePrefix);
89
                        final int result = ooaCustomParser.FirstPass(pState);
90
                        if (result > 0)
91
                        {
92
                                System.out.println(String.format("The parser returned %s errors:", result));
93
                                for (final ParserError error: pState.listOfParserErrors)
94
                                        System.out.println(String.format("ERROR (%s): %s,%s; %s",
95
                                                        error.file(), error.line(), error.column(), error.message()));
96
                        }
97
                        else
98
                        {
99
                                System.out.println("   Passed: OoaParser");
100
                                if (options.pipeLine.size() > 0)
101
                                {
102

    
103
                                        IAstVisitor visitor = null;
104
                                        for (final CreateVisitor item: options.pipeLine)
105
                                        {
106
                                                visitor = item.cerate(pState);
107
                                                pState.ooaSystem.Accept(visitor);
108
                                                if (pState.listOfParserErrors.size() > 0)
109
                                                {
110
                                                        System.out.println(String.format("The parser (%s) returned %s errors:",
111
                                                                        visitor.returnVisitorName(), pState.listOfParserErrors.size()));
112

    
113
                                                        for (final ParserError error: pState.listOfParserErrors)
114
                                                                System.out.println(String.format("ERROR (%s): %s,%s; %s",
115
                                                                                error.file(), error.line(), error.column(), error.message()));
116
                                                        return pState.listOfParserErrors.size();
117
                                                }
118
                                                else
119
                                                {
120
                                                        System.out.print("   Passed: ");
121
                                                        System.out.println(visitor.returnVisitorName());
122
                                                }
123
                                        }
124
                                        System.out.println();
125
                                        System.out.println(String.format("File %s successfully parsed.", pState.filename));
126
                                        System.out.println();
127

    
128
                                        if (pState.listOfParserMessages.size() > 0 && !(options.quiet))
129
                                        {
130
                                                System.out.println(String.format("Parser returned %s messages:", pState.listOfParserMessages.size()));
131
                                                for (final ParserMessage message: pState.listOfParserMessages)
132
                                                        System.out.println(String.format("Message (%s): %s,%s; %s",
133
                                                                        message.file(), message.line(), message.column(), message.message()));
134
                                                System.out.println();
135
                                                System.out.println();
136
                                        }
137

    
138
                                        if (pState.listOfParserWarnings.size() > 0 && !(options.quiet))
139
                                        {
140
                                                System.out.println(String.format("Parser returned %s warnings:", pState.listOfParserWarnings.size()));
141
                                                for (final ParserWarning warning: pState.listOfParserWarnings)
142
                                                        System.out.println(String.format("Warning (%s): %s,%s; %s",
143
                                                                        warning.file(), warning.line(), warning.column(), warning.message()));
144
                                                System.out.println("");
145
                                                System.out.println("");
146
                                        }
147

    
148
                                        if (!options.outputToFile.equals(""))
149
                                        {
150
                                                System.out.println(String.format("Writing output to %s.", options.outputToFile));
151
                                                final FileWriter fw = new FileWriter(options.outputToFile, false);
152
                                                fw.write(visitor.toString()); // fixme: this should be ascii..
153
                                                fw.close();
154
                                        }
155
                                        else
156
                                                System.out.println(visitor.toString());
157
                                }
158
                                else
159
                                {
160
                                        System.out.println();
161
                                        System.out.println(String.format("File %s successfully parsed.", pState.filename));
162
                                        System.out.println("");
163
                                }
164
                        }
165

    
166
                        return result;
167
                } catch (final IOException e) {
168
                        e.printStackTrace();
169
                        return -1;
170
                }
171
        }
172

    
173

    
174
        private static void fillPipeLine(Options options) {
175
                int index = 0;
176

    
177
                options.pipeLine.add(index++, new CreateVisitor(){
178
                        @Override
179
                        public IAstVisitor cerate(ParserState aState) {
180
                                return new OoaSymbolSortVisitor(aState);
181
                        }});
182
                options.pipeLine.add(index++, new CreateVisitor(){
183
                        @Override
184
                        public IAstVisitor cerate(ParserState aState) {
185
                                return new OoaReplaceOpaqueVisitor(aState);
186
                        }});
187
                options.pipeLine.add(index++, new CreateVisitor(){
188
                        @Override
189
                        public IAstVisitor cerate(ParserState aState) {
190
                                return new OoaTypesVisitor(aState);
191
                        }});
192
                options.pipeLine.add(index++, new CreateVisitor(){
193
                        @Override
194
                        public IAstVisitor cerate(ParserState aState) {
195
                                return new OoaResolveExpressionsVisitor(aState);
196
                        }});
197
                options.pipeLine.add(index++, new CreateVisitor(){
198
                        @Override
199
                        public IAstVisitor cerate(ParserState aState) {
200
                                return new OoaMethodPureClassifierVisitor(aState);
201
                        }});
202
                options.pipeLine.add(index++, new CreateVisitor(){
203
                        @Override
204
                        public IAstVisitor cerate(ParserState aState) {
205
                                return new OoaTypeCheckVisitor(aState);
206
                        }});
207

    
208
                if (!options.namedTypePrefix.equals(""))
209
                {
210
                        options.pipeLine.add(index++, new CreateVisitor(){
211
                                @Override
212
                                public IAstVisitor cerate(ParserState aState) {
213
                                        return new OoaTypeRenameVisitor(aState);
214
                                }});
215
                }
216

    
217
                options.pipeLine.add(index++, new CreateVisitor(){
218
                        @Override
219
                        public IAstVisitor cerate(ParserState aState) {
220
                                return new OoaRemoveTrivialPrioritizedCompositionVisitor(aState);
221
                        }});
222
                options.pipeLine.add(index++, new CreateVisitor(){
223
                        @Override
224
                        public IAstVisitor cerate(ParserState aState) {
225
                                return new OoaActionClassifierVisitor(aState);
226
                        }});
227

    
228
                options.pipeLine.add(index++, new CreateVisitor(){
229
                        @Override
230
                        public IAstVisitor cerate(ParserState aState) {
231
                                return new OoaObjectInstantiationVisitor(aState, LabelCompression.NoCompression);
232
                        }});
233
        }
234

    
235

    
236
        /* entry point */
237
        public static void main(String[] args)
238
        {
239
                displayTitle();
240

    
241
                if (args.length != 4) {
242
                        System.out.println("3 Arguments expected: backend orig/mut inputfile outputfile");
243
                        System.out.println();
244
                        System.out.println("   backend    ... 'psym' or 'p'");
245
                        System.out.println("   orig/mut   ... 'orig' or 'mut'");
246
                        System.out.println("   input  file or directory ... full path to input .ooas file or");
247
                        System.out.println("                                directory containing .ooas files");
248
                        System.out.println("   output file or directory ... full path to output file; will erase or");
249
                        System.out.println("                                directory (only if also input is a directory)");
250
                        System.out.println();
251
                        System.exit(-1);
252
                }
253

    
254
                final Options options  = new Options();
255
                final boolean symbolic = args[0].toLowerCase().trim().equals("psym");
256
                final boolean mutant   = args[1].toLowerCase().trim().equals("mut");
257
                options.fileToParse    = args[2];
258
                options.outputToFile   = args[3];
259
                fillPipeLine(options); // add all basic operations
260
                final String namespace = mutant? "asm" : "as";
261
                options.namespace      = namespace;
262

    
263
                // add the prolog codegen target...
264
                if (symbolic) {
265
                        options.pipeLine.add(new CreateVisitor(){
266
                                @Override
267
                                public IAstVisitor cerate(ParserState aState) {
268
                                        return new OoaPrologSymbolicVisitor(aState, 35, namespace);
269
                                }});
270
                } else {
271
                        options.pipeLine.add(new CreateVisitor(){
272
                                @Override
273
                                public IAstVisitor cerate(ParserState aState) {
274
                                        return new OoaPrologVisitor(aState, 35, namespace); // "as" ... original, "asm" ... mutant
275
                                }});
276
                }
277
                System.out.println(String.format("Running OOAS Compiler... [backend=%s, namespace=%s]", symbolic?"psym":"p", namespace));
278
                if (new File(options.fileToParse).isDirectory()) {
279
                        directoryMode(options);
280
                } else {
281
                        fileMode(options);
282
                }
283
        }
284

    
285
        /**
286
         * Iterates over all files in a directory if options.fileToParse is a directory
287
         * and runs the antlr parser for each file. the output is stored in the same
288
         * directory if the options.outputToFile is blank or not a directory.
289
         * @param options
290
         */
291
        public static void directoryMode(final Options options) {
292
                final File input  = new File(options.fileToParse);
293
                final File output = new File(options.outputToFile);
294
                final List<File> errors = new ArrayList<File>();
295

    
296
                File[] filesToParse = null;
297
                final FileFilter filter = new FileFilter() {
298
                        @Override
299
                        public final boolean accept(final File myFile) {
300
                                return myFile.getName().endsWith(".ooas");
301
                        }
302
                };
303

    
304
                System.out.println(String.format("Processing Directory [Input, Output]: %s, %s",
305
                                input.getAbsolutePath(), output.getAbsoluteFile()));
306

    
307
                filesToParse = input.listFiles(filter);
308

    
309
                int result              = 0;
310
                File fileToParse        = null;
311
                String inputFileName    = "";
312
                String outputFileName   = "";
313
                final String outputFileSuffix = "." + options.namespace + ".pl";
314

    
315
                if (filesToParse != null) {
316
                        for (int i = 0; i < filesToParse.length; ++i) {
317
                                fileToParse    = filesToParse[i];
318
                                inputFileName  = fileToParse.getAbsolutePath();
319
                                outputFileName = fileToParse.getName().substring(0, fileToParse.getName().indexOf(".ooas")).concat(outputFileSuffix);
320

    
321
                                if (output != null) {
322
                                        if (!output.isDirectory())
323
                                                output.mkdir();
324
                                        outputFileName = output.getAbsolutePath() + File.separatorChar + outputFileName;
325
                                }
326
                                else {
327
                                        // use same directory as input file for output
328
                                        outputFileName = fileToParse.getParent() + File.separatorChar + outputFileName;
329
                                }
330

    
331
                                options.fileToParse  = inputFileName;
332
                                options.outputToFile = outputFileName;
333

    
334
                                System.out.println(String.format("Parsing %s", options.fileToParse));
335
                                result = runAntlrParser(options);
336
                                if (result != 0)
337
                                        errors.add(fileToParse);
338
                        }
339
                }
340

    
341
                if (errors.size() > 0) {
342
                        System.out.println("Following files were not processed correctly:");
343
                        final Iterator<File> i = errors.iterator();
344
                        File file = null;
345
                        while (i.hasNext()) {
346
                                file = i.next();
347
                                System.out.println(file.getName());
348
                        }
349
                        System.exit(-1);
350
                }
351
                System.exit(0);
352
        }
353

    
354
        /**
355
         * Runs the antlr parser with the given options
356
         * @param options
357
         */
358
        public static void fileMode(final Options options) {
359
                System.out.println(String.format("Parsing %s.", options.fileToParse));
360
                final int result = runAntlrParser(options);
361
                System.exit(result);
362
        }
363
}