Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / Compiler.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.BufferedWriter;
31
import java.io.File;
32
import java.io.FileWriter;
33
import java.io.IOException;
34
import java.io.InputStream;
35
import java.io.OutputStream;
36
import java.io.OutputStreamWriter;
37
import java.util.ArrayList;
38
import java.util.Collections;
39
import java.util.Comparator;
40
import java.util.List;
41

    
42
import org.momut.ooas.CompilerConfiguration.Backend;
43
import org.momut.ooas.ast.IAstVisitor;
44
import org.momut.ooas.codegen.ast.OoaAstEmitter;
45
import org.momut.ooas.codegen.cadp.OoaCADPVisitor;
46
import org.momut.ooas.codegen.prolog.OoaPrologVisitor;
47
import org.momut.ooas.codegen.prologsymbolic.OoaPrologSymbolicVisitor;
48
import org.momut.ooas.parser.CompilerMessage;
49
import org.momut.ooas.parser.ParserError;
50
import org.momut.ooas.parser.ParserMessage;
51
import org.momut.ooas.parser.ParserState;
52
import org.momut.ooas.parser.ParserWarning;
53
import org.momut.ooas.parser.ooaCustomParser;
54
import org.momut.ooas.utils.exceptions.OoasCompilerRuntimeException;
55
import org.momut.ooas.visitors.OoaActionClassifierVisitor;
56
import org.momut.ooas.visitors.OoaCheckObjectRefsConstant;
57
import org.momut.ooas.visitors.OoaMethodPureClassifierVisitor;
58
import org.momut.ooas.visitors.OoaObjectInstantiationVisitor;
59
import org.momut.ooas.visitors.OoaPrintVisitor;
60
import org.momut.ooas.visitors.OoaReplaceOpaqueVisitor;
61
import org.momut.ooas.visitors.OoaResolveExpressionsVisitor;
62
import org.momut.ooas.visitors.OoaSymbolSortVisitor;
63
import org.momut.ooas.visitors.OoaTypeCheckVisitor;
64
import org.momut.ooas.visitors.OoaTypeRenameVisitor;
65
import org.momut.ooas.visitors.OoaTypesVisitor;
66
import org.momut.ooas.visitors.analysis.OoaCheckASTVisitor;
67
import org.momut.ooas.visitors.analysis.OoaPrintActionSequencesVisitor;
68
import org.momut.ooas.visitors.analysis.OoaPrintActionsVisitor;
69
import org.momut.ooas.visitors.analysis.OoaPrintMetricsVisitor;
70
import org.momut.ooas.visitors.optimisation.OoaRemoveTrivialBlocksVisitor;
71

    
72
public final class Compiler {
73
        public interface IProgressCallBack {
74
                public void startingCompilePhase(String compilePhaseName);
75
                public void doneCompilePhase();
76
        }
77
        public interface ILogCallBack {
78
                public void logError(boolean toConsole, String message);
79
        }
80
        private static final class NullProgressCallBack implements IProgressCallBack {
81
                @Override
82
                public void startingCompilePhase(String compilePhaseName) {}
83
                @Override
84
                public void doneCompilePhase() {}
85
        }
86
        private interface CreateVisitor {
87
                public IAstVisitor create(ParserState aState);
88
        }
89

    
90
        public final CompilerConfiguration config;
91
        private final ArrayList<CreateVisitor> pipeLine = new ArrayList<CreateVisitor>();
92
        private ArrayList<ParserError> listOfParserErrors = new ArrayList<>();
93
        private ArrayList<ParserWarning> listOfParserWarnings = new ArrayList<>();
94
        private ArrayList<ParserMessage> listOfParserMessages = new ArrayList<>();
95

    
96
        private void updateParserMsgs(ParserState pState) {
97
                final Comparator<CompilerMessage> comparator = new Comparator<CompilerMessage>(){
98
                        @Override
99
                        public int compare(CompilerMessage arg0, CompilerMessage arg1) {
100
                                if (arg0.line() != arg1.line())
101
                                        return arg0.line() - arg1.line();
102
                                else
103
                                        return arg0.column() - arg1.column();
104
                        }};
105

    
106
                listOfParserErrors = pState.listOfParserErrors;
107
                listOfParserMessages = pState.listOfParserMessages;
108
                listOfParserWarnings = pState.listOfParserWarnings;
109

    
110
                // sort the logs
111
                Collections.sort(listOfParserErrors, comparator);
112
                Collections.sort(listOfParserMessages, comparator);
113
                Collections.sort(listOfParserWarnings, comparator);
114
        }
115

    
116
        public List<ParserError> getErrors() {
117
                return Collections.unmodifiableList(listOfParserErrors);
118
        }
119
        public List<ParserWarning> getWarnings() {
120
                return Collections.unmodifiableList(listOfParserWarnings);
121
        }
122
        public List<ParserMessage> getMessages() {
123
                return Collections.unmodifiableList(listOfParserMessages);
124
        }
125

    
126
        @Override
127
        public String toString() {
128
                final StringBuilder result = new StringBuilder();
129
                for (final ParserError err: getErrors())
130
                        result.append(String.format("ERROR: %s (%s,%s): %s\n",
131
                                err.file(), err.line(), err.column(), err.message()));
132
                for (final ParserWarning err: getWarnings())
133
                        result.append(String.format("Warning: %s (%s,%s): %s\n",
134
                                err.file(), err.line(), err.column(), err.message()));
135
                for (final ParserMessage msg: getMessages())
136
                        result.append(String.format("Info: %s (%s,%s): %s\n",
137
                                msg.file(), msg.line(), msg.column(), msg.message()));
138
                return result.toString();
139
        }
140

    
141
        private void fillPipeLine() {
142
                pipeLine.add(new CreateVisitor(){
143
                        @Override
144
                        public IAstVisitor create(ParserState aState) {
145
                                return new OoaCheckASTVisitor(aState, "Stage 0");
146
                        }});
147
                pipeLine.add(new CreateVisitor(){
148
                        @Override
149
                        public IAstVisitor create(ParserState aState) {
150
                                return new OoaSymbolSortVisitor(aState);
151
                        }});
152
                pipeLine.add(new CreateVisitor(){
153
                        @Override
154
                        public IAstVisitor create(ParserState aState) {
155
                                return new OoaReplaceOpaqueVisitor(aState);
156
                        }});
157
                pipeLine.add(new CreateVisitor(){
158
                        @Override
159
                        public IAstVisitor create(ParserState aState) {
160
                                return new OoaTypesVisitor(aState);
161
                        }});
162
                pipeLine.add(new CreateVisitor(){
163
                        @Override
164
                        public IAstVisitor create(ParserState aState) {
165
                                return new OoaResolveExpressionsVisitor(aState);
166
                        }});
167
                pipeLine.add(new CreateVisitor(){
168
                        @Override
169
                        public IAstVisitor create(ParserState aState) {
170
                                return new OoaMethodPureClassifierVisitor(aState);
171
                        }});
172
                pipeLine.add(new CreateVisitor(){
173
                        @Override
174
                        public IAstVisitor create(ParserState aState) {
175
                                return new OoaTypeCheckVisitor(aState);
176
                        }});
177

    
178
                if (!config.getNamedTypePrefix().equals(""))
179
                {
180
                        pipeLine.add(new CreateVisitor(){
181
                                @Override
182
                                public IAstVisitor create(ParserState aState) {
183
                                        return new OoaTypeRenameVisitor(aState);
184
                                }});
185
                }
186

    
187
                // do some trivial "optimizations" (remove prioritized and nondet choice blocks
188
                // with only one element, join sequential blocks that are direct children of
189
                // sequential blocks to one sequential block
190
                pipeLine.add(new CreateVisitor(){
191
                        @Override
192
                        public IAstVisitor create(ParserState aState) {
193
                                return new OoaRemoveTrivialBlocksVisitor(aState);
194
                        }});
195
                // check the AST
196
                pipeLine.add(new CreateVisitor(){
197
                        @Override
198
                        public IAstVisitor create(ParserState aState) {
199
                                return new OoaCheckASTVisitor(aState,"After Optimisation");
200
                        }});
201

    
202

    
203
                pipeLine.add(new CreateVisitor(){
204
                        @Override
205
                        public IAstVisitor create(ParserState aState) {
206
                                return new OoaActionClassifierVisitor(aState);
207
                        }});
208

    
209
                pipeLine.add(new CreateVisitor(){
210
                        @Override
211
                        public IAstVisitor create(ParserState aState) {
212
                                return new OoaPrintMetricsVisitor(aState);
213
                        }
214
                });
215

    
216
                switch (config.getBackend()) {
217
                case Printer:
218
                        pipeLine.add(new CreateVisitor(){
219
                                @Override
220
                                public IAstVisitor create(ParserState aState) {
221
                                        return new OoaPrintVisitor(aState);
222
                                }});
223
                        break;
224
                case CADP :
225
                        pipeLine.add(new CreateVisitor(){
226
                                @Override
227
                                public IAstVisitor create(ParserState aState) {
228
                                        return new OoaObjectInstantiationVisitor(aState, config.getLabelCompression());
229
                                }});
230
                        pipeLine.add(new CreateVisitor(){
231
                                @Override
232
                                public IAstVisitor create(ParserState aState) {
233
                                        return new OoaPrintActionsVisitor(aState);
234
                                }});
235
                        pipeLine.add(new CreateVisitor(){
236
                                @Override
237
                                public IAstVisitor create(ParserState aState) {
238
                                        return new OoaPrintActionSequencesVisitor(aState);
239
                                }});
240
                        pipeLine.add(new CreateVisitor(){
241
                                @Override
242
                                public IAstVisitor create(ParserState aState) {
243
                                        return new OoaCADPVisitor(aState);
244
                                }});
245
                        break;
246
                case Prolog:
247
                        pipeLine.add(new CreateVisitor(){
248
                                @Override
249
                                public IAstVisitor create(ParserState aState) {
250
                                        return new OoaObjectInstantiationVisitor(aState, config.getLabelCompression());
251
                                }});
252
                        pipeLine.add(new CreateVisitor(){
253
                                @Override
254
                                public IAstVisitor create(ParserState aState) {
255
                                        return new OoaPrintActionsVisitor(aState);
256
                                }});
257
                        pipeLine.add(new CreateVisitor(){
258
                                @Override
259
                                public IAstVisitor create(ParserState aState) {
260
                                        return new OoaPrintActionSequencesVisitor(aState);
261
                                }});
262
                        pipeLine.add(new CreateVisitor(){
263
                                @Override
264
                                public IAstVisitor create(ParserState aState) {
265
                                        return new OoaPrologVisitor(aState, config.getMaxSearchDepth(), config.getNameSpace());
266
                                }});
267
                        break;
268
                case PrologSymbolic:
269
                        pipeLine.add(new CreateVisitor(){
270
                                @Override
271
                                public IAstVisitor create(ParserState aState) {
272
                                        return new OoaCheckObjectRefsConstant(aState);
273
                                }});
274
                        pipeLine.add(new CreateVisitor(){
275
                                @Override
276
                                public IAstVisitor create(ParserState aState) {
277
                                        return new OoaObjectInstantiationVisitor(aState, config.getLabelCompression());
278
                                }});
279
                        pipeLine.add(new CreateVisitor(){
280
                                @Override
281
                                public IAstVisitor create(ParserState aState) {
282
                                        return new OoaPrintActionSequencesVisitor(aState);
283
                                }});
284
                        pipeLine.add(new CreateVisitor(){
285
                                @Override
286
                                public IAstVisitor create(ParserState aState) {
287
                                        return new OoaPrintActionsVisitor(aState);
288
                                }});
289
                        pipeLine.add(new CreateVisitor(){
290
                                @Override
291
                                public IAstVisitor create(ParserState aState) {
292
                                        return new OoaPrologSymbolicVisitor(aState, config.getMaxSearchDepth(), config.getNameSpace());
293
                                }});
294
                        break;
295
                case CopyAST:
296
                        pipeLine.add(new CreateVisitor(){
297
                                @Override
298
                                public IAstVisitor create(ParserState aState) {
299
                                        return new OoaObjectInstantiationVisitor(aState, config.getLabelCompression());
300
                                }});
301
                        pipeLine.add(new CreateVisitor(){
302
                                @Override
303
                                public IAstVisitor create(ParserState aState) {
304
                                        return new OoaPrintActionsVisitor(aState);
305
                                }});
306
                        pipeLine.add(new CreateVisitor(){
307
                                @Override
308
                                public IAstVisitor create(ParserState aState) {
309
                                        return new OoaAstEmitter<>(aState, config.getAstTarget());
310
                                }});
311
                        break;
312
                default:
313
                        throw new OoasCompilerRuntimeException("Unknown backend.");
314
                }
315
        }
316

    
317

    
318
        public int compile(ILogCallBack logCallback) {
319
                return compile(new NullProgressCallBack(), logCallback);
320
        }
321

    
322
        /* fire up the parser */
323
        public int compile(IProgressCallBack callback, ILogCallBack logCallback)
324
        {
325
                if (config.isWriteable()) {
326
                        config.setWriteOnly();
327
                        fillPipeLine();
328
                }
329

    
330
                ParserState pState;
331
                try {
332
                        callback.startingCompilePhase("OoaParser");
333
                        pState = config.useStreams()
334
                                        ?  new ParserState(config.getUnitName(), config.getInputStream(), config.getNamedTypePrefix())
335
                                        :  new ParserState(config.getFileToParse(), config.getNamedTypePrefix());
336
                        final int result = ooaCustomParser.FirstPass(pState);
337
                        if (result == 0) {
338
                                callback.doneCompilePhase();
339
                                if (pipeLine.size() > 0) {
340
                                        IAstVisitor visitor = null;
341
                                        for (final CreateVisitor item: pipeLine) {
342
                                                visitor = item.create(pState);
343
                                                callback.startingCompilePhase(visitor.returnVisitorName());
344
                                                pState.ooaSystem.Accept(visitor);
345
                                                visitor.done();
346
                                                if (pState.listOfParserErrors.size() > 0) {
347
                                                        updateParserMsgs(pState);
348
                                                        return pState.listOfParserErrors.size();
349
                                                } else
350
                                                        callback.doneCompilePhase();
351
                                        }
352
                                        // after we've done all visitors, write the output file.
353
                                        if (!config.useStreams() && !config.getFileToOutput().equals(""))
354
                                        {
355
                                                final FileWriter fw = new FileWriter(config.getFileToOutput(), false);
356
                                                fw.write(visitor.toString()); // fixme: this should be ascii..
357
                                                fw.close();
358
                                        } else if (config.useStreams()) {
359
                                                final OutputStream out = config.getOutputStream();
360
                                                final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
361
                                                writer.write(visitor.toString());
362
                                                writer.close();
363
                                        }
364
                                }
365
                        }
366
                        updateParserMsgs(pState);
367
                        return result;
368
                } catch (final IOException e) {
369
                        logCallback.logError(true, e.toString());
370
                        return -1;
371
                }
372
        }
373

    
374

    
375
        public Compiler(CompilerConfiguration config) {
376
                this.config = config;
377
        }
378

    
379
        public Compiler(String unitName, String fileToParse, String fileToWrite, Backend be) {
380
                this(new CompilerConfiguration(unitName, fileToParse, fileToWrite, be));
381
        }
382

    
383
        public Compiler(String fileToParse, String fileToWrite, Backend be) {
384
                this(new File(fileToParse).getName(), fileToParse, fileToWrite, be);
385
        }
386

    
387
        public Compiler(String unitName, InputStream input, OutputStream output, Backend be) {
388
                this(new CompilerConfiguration(unitName, input, output, be));
389
        }
390
}