1
|
/**
|
2
|
*
|
3
|
* OOAS Compiler (Deprecated)
|
4
|
*
|
5
|
* Copyright 2015, Institute for Software Technology, Graz University of
|
6
|
* Technology. Portions are copyright 2015 by the AIT Austrian Institute
|
7
|
* of Technology. All rights reserved.
|
8
|
*
|
9
|
* SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
|
10
|
*
|
11
|
* Please notice that this version of the OOAS compiler is considered de-
|
12
|
* precated. Only the Java version is maintained.
|
13
|
*
|
14
|
* Contributors:
|
15
|
* Willibald Krenn (TU Graz/AIT)
|
16
|
* Stefan Tiran (TU Graz/AIT)
|
17
|
*/
|
18
|
|
19
|
using System;
|
20
|
using System.Collections.Generic;
|
21
|
using System.Text;
|
22
|
using System.Configuration;
|
23
|
using Antlr.Runtime;
|
24
|
using TUG.Mogentes.Codegen;
|
25
|
|
26
|
namespace TUG.Mogentes
|
27
|
{
|
28
|
[Serializable()]
|
29
|
public struct ArgosVersion
|
30
|
{
|
31
|
public int ParserMajor;
|
32
|
public int ParserMinor;
|
33
|
public int ParserRevision;
|
34
|
|
35
|
public int GrammarMajor;
|
36
|
public int GrammarMinor;
|
37
|
|
38
|
public override string ToString()
|
39
|
{
|
40
|
StringBuilder result = new StringBuilder();
|
41
|
result.Append(" Version: ");
|
42
|
result.Append(ParserMajor); result.Append("."); result.Append(String.Format("{0:00}",ParserMinor));
|
43
|
result.Append(" ("); result.Append(ParserRevision); result.AppendLine(")");
|
44
|
result.Append(" Grammar-Version: ");
|
45
|
result.Append(GrammarMajor); result.Append("."); result.Append(String.Format("{0:00}",GrammarMinor));
|
46
|
return result.ToString();
|
47
|
}
|
48
|
}
|
49
|
|
50
|
|
51
|
public abstract class ConfigurationElementCollection<T> : ConfigurationElementCollection
|
52
|
where T : ConfigurationElement
|
53
|
{
|
54
|
protected override ConfigurationElement CreateNewElement()
|
55
|
{
|
56
|
return (ConfigurationElement)Activator.CreateInstance(typeof(T));
|
57
|
}
|
58
|
|
59
|
public void Add(T elem)
|
60
|
{
|
61
|
BaseAdd(elem);
|
62
|
}
|
63
|
|
64
|
public T this[int index]
|
65
|
{
|
66
|
get { return (T)base.BaseGet(index); }
|
67
|
set
|
68
|
{
|
69
|
if (base.BaseGet(index) != null)
|
70
|
{
|
71
|
base.BaseRemoveAt(index);
|
72
|
}
|
73
|
this.BaseAdd(index, value);
|
74
|
}
|
75
|
}
|
76
|
|
77
|
public new T this[string key]
|
78
|
{
|
79
|
get { return (T)base.BaseGet(key); }
|
80
|
}
|
81
|
}
|
82
|
|
83
|
public class BackEndConfig : ConfigurationElement
|
84
|
{
|
85
|
[ConfigurationProperty("switch", IsRequired = true)]
|
86
|
public string Switch
|
87
|
{
|
88
|
get { return (string)base["switch"]; }
|
89
|
set { base["switch"] = value; }
|
90
|
}
|
91
|
[ConfigurationProperty("file", IsRequired = true)]
|
92
|
public string File
|
93
|
{
|
94
|
get { return (string)base["file"]; }
|
95
|
set { base["file"] = value; }
|
96
|
}
|
97
|
[ConfigurationProperty("class", IsRequired = true)]
|
98
|
public string Class
|
99
|
{
|
100
|
get { return (string)base["class"]; }
|
101
|
set { base["class"] = value; }
|
102
|
}
|
103
|
[ConfigurationProperty("descr", IsRequired = true)]
|
104
|
public string Descr
|
105
|
{
|
106
|
get { return (string)base["descr"]; }
|
107
|
set { base["descr"] = value; }
|
108
|
}
|
109
|
|
110
|
public BackEndConfig(string aSwitch, string aFile, string aClass, string aDescr)
|
111
|
: base()
|
112
|
{
|
113
|
Switch = aSwitch;
|
114
|
File = aFile;
|
115
|
Class = aClass;
|
116
|
Descr = aDescr;
|
117
|
}
|
118
|
|
119
|
public BackEndConfig(BackEndConfig toCopy)
|
120
|
{
|
121
|
Switch = toCopy.Switch;
|
122
|
File = toCopy.File;
|
123
|
Class = toCopy.Class;
|
124
|
Descr = toCopy.Descr;
|
125
|
}
|
126
|
|
127
|
public BackEndConfig() { }
|
128
|
}
|
129
|
|
130
|
public class InstantiatedBackEndConfig : BackEndConfig
|
131
|
{
|
132
|
public Type Visitor;
|
133
|
public System.Reflection.ConstructorInfo Constr;
|
134
|
|
135
|
public CreateVisitor GetConstructor()
|
136
|
{
|
137
|
return p => (IAstVisitor)Constr.Invoke(new Object[] { p });
|
138
|
}
|
139
|
|
140
|
public InstantiatedBackEndConfig(BackEndConfig toInstantiate)
|
141
|
: base(toInstantiate)
|
142
|
{
|
143
|
if (toInstantiate.File != String.Empty)
|
144
|
{
|
145
|
string filename = System.IO.Path.GetFullPath(toInstantiate.File);
|
146
|
if (!System.IO.File.Exists(filename))
|
147
|
{
|
148
|
filename = new Uri(System.Reflection.Assembly.GetExecutingAssembly().Location).LocalPath;
|
149
|
filename = System.IO.Path.GetDirectoryName(filename) + System.IO.Path.DirectorySeparatorChar + toInstantiate.File;
|
150
|
if (!System.IO.File.Exists(filename))
|
151
|
{
|
152
|
throw new ArgumentException(String.Format("Not found: {0}", toInstantiate.File));
|
153
|
}
|
154
|
}
|
155
|
this.File = filename;
|
156
|
|
157
|
|
158
|
System.Reflection.Assembly backend = System.Reflection.Assembly.LoadFile(File);
|
159
|
Visitor = backend.GetType(toInstantiate.Class);
|
160
|
if (Visitor == null)
|
161
|
throw new ArgumentException(String.Format("Cannot find type {0}", toInstantiate.Class));
|
162
|
}
|
163
|
else
|
164
|
{
|
165
|
Visitor = System.Reflection.Assembly.GetExecutingAssembly().GetType(toInstantiate.Class);
|
166
|
if (Visitor == null)
|
167
|
throw new ArgumentException(String.Format("Cannot find type {0}", toInstantiate.Class));
|
168
|
}
|
169
|
|
170
|
Constr = Visitor.GetConstructor(new Type[] { typeof(ParserState) });
|
171
|
if (Constr == null)
|
172
|
throw new ArgumentException(String.Format("Cannot get constructor of type {0}", toInstantiate.Class));
|
173
|
|
174
|
}
|
175
|
|
176
|
}
|
177
|
|
178
|
|
179
|
[ConfigurationCollection(typeof(BackEndConfig))]
|
180
|
public class BackendSettingsCollection : ConfigurationElementCollection<BackEndConfig>
|
181
|
{
|
182
|
protected override object GetElementKey(ConfigurationElement element)
|
183
|
{
|
184
|
return ((BackEndConfig)element).Switch;
|
185
|
}
|
186
|
}
|
187
|
|
188
|
|
189
|
|
190
|
public class ArgosConfigData : ConfigurationSection
|
191
|
{
|
192
|
public ArgosConfigData()
|
193
|
{
|
194
|
}
|
195
|
|
196
|
[ConfigurationProperty("backends")]
|
197
|
public BackendSettingsCollection BackendSettings
|
198
|
{
|
199
|
get { return (BackendSettingsCollection)this["backends"]; }
|
200
|
set { this["backends"] = value; }
|
201
|
}
|
202
|
}
|
203
|
|
204
|
|
205
|
public class Program
|
206
|
{
|
207
|
|
208
|
public class Options
|
209
|
{
|
210
|
public static string searchDepth = "35";
|
211
|
internal bool quiet = false;
|
212
|
internal string fileToParse = String.Empty;
|
213
|
internal string outputToFile = String.Empty;
|
214
|
internal string namedTypePrefix = String.Empty;
|
215
|
public static string nameSpace = "as";
|
216
|
internal List<CreateVisitor> pipeLine = new List<CreateVisitor>();
|
217
|
}
|
218
|
|
219
|
public static List<InstantiatedBackEndConfig> BackEnds = new List<InstantiatedBackEndConfig>();
|
220
|
public static readonly string BackEndSectionName = "BackEnds";
|
221
|
|
222
|
static void CreateSection()
|
223
|
{
|
224
|
try
|
225
|
{
|
226
|
ArgosConfigData customSection;
|
227
|
|
228
|
// Get the current configuration file.
|
229
|
System.Configuration.Configuration config =
|
230
|
ConfigurationManager.OpenExeConfiguration(
|
231
|
ConfigurationUserLevel.None);
|
232
|
|
233
|
// Create the section entry
|
234
|
// in the <configSections> and the
|
235
|
// related target section in <configuration>.
|
236
|
if (config.Sections[BackEndSectionName] == null)
|
237
|
{
|
238
|
customSection = new ArgosConfigData();
|
239
|
customSection.BackendSettings.Add(new BackEndConfig("a", String.Empty, "TUG.Mogentes.OoaPrintVisitor", "create psuedo-action system code"));
|
240
|
customSection.BackendSettings.Add(new BackEndConfig("p", String.Empty, "TUG.Mogentes.Codegen.OoaPrologVisitor", "create prolog code"));
|
241
|
customSection.BackendSettings.Add(new BackEndConfig("psym", String.Empty, "TUG.Mogentes.Codegen.PrologSymbolic.OoaPrologSymbolicVisitor", "create symbolic prolog code"));
|
242
|
config.Sections.Add(BackEndSectionName, customSection);
|
243
|
customSection.SectionInformation.ForceSave = true;
|
244
|
config.Save(ConfigurationSaveMode.Full);
|
245
|
}
|
246
|
}
|
247
|
catch (ConfigurationErrorsException err)
|
248
|
{
|
249
|
Console.WriteLine(err.ToString());
|
250
|
}
|
251
|
}
|
252
|
public static ArgosVersion GetProgramVersion()
|
253
|
{
|
254
|
Version ver = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
|
255
|
ArgosVersion result;
|
256
|
result.ParserMajor = ver.Major;
|
257
|
result.ParserMinor = ver.Minor;
|
258
|
result.ParserRevision = ver.Revision;
|
259
|
|
260
|
result.GrammarMajor = (ver.Build / 100);
|
261
|
result.GrammarMinor = (ver.Build % 100);
|
262
|
return result;
|
263
|
}
|
264
|
static void displayTitle()
|
265
|
{
|
266
|
ArgosVersion ver = Program.GetProgramVersion();
|
267
|
Console.WriteLine();
|
268
|
Console.WriteLine(" >> Mogentes OO-Action System Parser <<");
|
269
|
Console.WriteLine();
|
270
|
Console.WriteLine(ver.ToString());
|
271
|
Console.WriteLine();
|
272
|
}
|
273
|
|
274
|
/* display some help screen */
|
275
|
static void displayHelp()
|
276
|
{
|
277
|
string programName = String.Empty;
|
278
|
programName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name.ToString();
|
279
|
|
280
|
displayTitle();
|
281
|
Console.WriteLine("Usage: " + programName + " [options] <oo-actionsystem-file>");
|
282
|
Console.WriteLine("Options:");
|
283
|
Console.WriteLine(" -o<name> ... write output to file <name> (overwrites!)");
|
284
|
Console.WriteLine(" -n<name> ... use namespace <name> (default: as)");
|
285
|
Console.WriteLine(" -d<depth> ... set max. search depth (default: 35)");
|
286
|
Console.WriteLine(" -q ... \"quiet\" mode: doesn't print Warnings to console");
|
287
|
Console.WriteLine();
|
288
|
foreach (var x in BackEnds)
|
289
|
{
|
290
|
Console.WriteLine(String.Format(" -{0} ... {1}", x.Switch, x.Descr));
|
291
|
}
|
292
|
}
|
293
|
|
294
|
/* fire up the parser */
|
295
|
static int runAntlrParser(Options options)
|
296
|
{
|
297
|
ParserState pState = new ParserState(options);
|
298
|
int result = ooaParser.FirstPass(pState);
|
299
|
|
300
|
|
301
|
displayTitle();
|
302
|
|
303
|
if (result > 0)
|
304
|
{
|
305
|
Console.WriteLine("The parser returned {0} errors:", result);
|
306
|
foreach (var error in pState.listOfParserErrors)
|
307
|
Console.WriteLine("ERROR ({0}): {1},{2}; {3}", error.file, error.line, error.column, error.message);
|
308
|
}
|
309
|
else
|
310
|
{
|
311
|
Console.WriteLine(" Passed: OoaParser");
|
312
|
if (options.pipeLine.Count > 0)
|
313
|
{
|
314
|
|
315
|
IAstVisitor visitor = null;
|
316
|
foreach (var item in options.pipeLine)
|
317
|
{
|
318
|
visitor = item(pState);
|
319
|
pState.ooaSystem.Accept(visitor);
|
320
|
if (pState.listOfParserErrors.Count > 0)
|
321
|
{
|
322
|
Console.WriteLine("The parser ({0}) returned {1} errors:",
|
323
|
visitor.GetType().Name, pState.listOfParserErrors.Count);
|
324
|
foreach (var error in pState.listOfParserErrors)
|
325
|
Console.WriteLine("ERROR ({0}): {1},{2}; {3}",
|
326
|
error.file, error.line, error.column, error.message);
|
327
|
return pState.listOfParserErrors.Count;
|
328
|
}
|
329
|
else
|
330
|
{
|
331
|
Console.Write(" Passed: ");
|
332
|
Console.WriteLine(visitor.GetType().Name);
|
333
|
}
|
334
|
}
|
335
|
Console.WriteLine();
|
336
|
Console.WriteLine("File {0} successfully parsed.", pState.filename);
|
337
|
Console.WriteLine("");
|
338
|
|
339
|
if (pState.listOfParserMessages.Count > 0 && !(options.quiet))
|
340
|
{
|
341
|
Console.WriteLine(String.Format("Parser returned {0} messages:", pState.listOfParserMessages.Count));
|
342
|
foreach (var message in pState.listOfParserMessages)
|
343
|
Console.WriteLine("Message ({0}): {1},{2}; {3}",
|
344
|
message.file, message.line, message.column, message.message);
|
345
|
Console.WriteLine();
|
346
|
Console.WriteLine();
|
347
|
}
|
348
|
|
349
|
if (pState.listOfParserWarnings.Count > 0 && !(options.quiet))
|
350
|
{
|
351
|
Console.WriteLine(String.Format("Parser returned {0} warnings:", pState.listOfParserWarnings.Count));
|
352
|
foreach (var warning in pState.listOfParserWarnings)
|
353
|
Console.WriteLine("Warning ({0}): {1},{2}; {3}",
|
354
|
warning.file, warning.line, warning.column, warning.message);
|
355
|
Console.WriteLine("");
|
356
|
Console.WriteLine("");
|
357
|
}
|
358
|
|
359
|
if (options.outputToFile != String.Empty)
|
360
|
{
|
361
|
Console.WriteLine("Writing output to {0}.", options.outputToFile);
|
362
|
System.IO.File.WriteAllText(options.outputToFile, visitor.ToString(), System.Text.Encoding.ASCII);
|
363
|
}
|
364
|
else
|
365
|
Console.WriteLine(visitor.ToString());
|
366
|
}
|
367
|
else
|
368
|
{
|
369
|
Console.WriteLine();
|
370
|
Console.WriteLine("File {0} successfully parsed.", pState.filename);
|
371
|
Console.WriteLine("");
|
372
|
}
|
373
|
}
|
374
|
|
375
|
return result;
|
376
|
}
|
377
|
|
378
|
|
379
|
|
380
|
|
381
|
/* entry point */
|
382
|
static int Main(string[] args)
|
383
|
{
|
384
|
CreateSection();
|
385
|
Program.Options options = new Program.Options();
|
386
|
|
387
|
/*load backends..*/
|
388
|
ArgosConfigData backends = ConfigurationManager.GetSection(BackEndSectionName) as ArgosConfigData;
|
389
|
foreach (var x in backends.BackendSettings)
|
390
|
{
|
391
|
BackEndConfig cnfg = (BackEndConfig)x;
|
392
|
//try
|
393
|
//{
|
394
|
InstantiatedBackEndConfig icnfg = new InstantiatedBackEndConfig(cnfg);
|
395
|
BackEnds.Add(icnfg);
|
396
|
//}
|
397
|
//catch (ArgumentException)
|
398
|
//{ }
|
399
|
}
|
400
|
|
401
|
|
402
|
|
403
|
if ((args.Length == 0) || (!System.IO.File.Exists(args[args.Length - 1])))
|
404
|
{
|
405
|
displayHelp();
|
406
|
#if DEBUG
|
407
|
Console.ReadLine();
|
408
|
#endif
|
409
|
return 0;
|
410
|
}
|
411
|
|
412
|
/*do some argument 'parsing'*/
|
413
|
for (int i = 0; i < args.Length; i++)
|
414
|
{
|
415
|
if (args[i].StartsWith("-"))
|
416
|
ParserOption(args[i], options);
|
417
|
else
|
418
|
{
|
419
|
options.fileToParse = args[i];
|
420
|
break;
|
421
|
}
|
422
|
}
|
423
|
|
424
|
/* c# really lacks meta-classes :-((
|
425
|
* but lambdas are a nice feature too :-)
|
426
|
*/
|
427
|
int index = 0;
|
428
|
options.pipeLine.Insert(index++, p => new OoaSymbolSortVisitor(p));
|
429
|
options.pipeLine.Insert(index++, p => new OoaReplaceOpaqueVisitor(p));
|
430
|
options.pipeLine.Insert(index++, p => new OoaTypesVisitor(p));
|
431
|
options.pipeLine.Insert(index++, p => new OoaResolveExpressionsVisitor(p));
|
432
|
options.pipeLine.Insert(index++, p => new OoaMethodPureClassifierVisitor(p));
|
433
|
options.pipeLine.Insert(index++, p => new OoaTypeCheckVisitor(p));
|
434
|
|
435
|
if (options.namedTypePrefix != String.Empty)
|
436
|
{
|
437
|
options.pipeLine.Insert(index++, p => new OoaTypeRenameVisitor(p));
|
438
|
}
|
439
|
|
440
|
options.pipeLine.Insert(index++, aParser => new OoaRemoveTrivialPrioritizedCompositionVisitor(aParser));
|
441
|
options.pipeLine.Insert(index++, p => new OoaActionClassifierVisitor(p));
|
442
|
options.pipeLine.Insert(index++, p => new OoaObjectInstantiationVisitor(p));
|
443
|
|
444
|
|
445
|
|
446
|
|
447
|
Console.WriteLine("Parsing {0}.", options.fileToParse);
|
448
|
int result = runAntlrParser(options);
|
449
|
#if DEBUG
|
450
|
Console.ReadLine();
|
451
|
#endif
|
452
|
return result;
|
453
|
}
|
454
|
|
455
|
private static void ParserOption(string p, Options options)
|
456
|
{
|
457
|
string p_lower = p.ToLower();
|
458
|
|
459
|
|
460
|
|
461
|
if (p_lower.StartsWith("-o"))
|
462
|
options.outputToFile = p.Remove(0, 2);
|
463
|
if (p_lower.StartsWith("-t"))
|
464
|
options.namedTypePrefix = p.Remove(0, 2);
|
465
|
if (p_lower.StartsWith("-n"))
|
466
|
{
|
467
|
|
468
|
TUG.Mogentes.Program.Options.nameSpace = p.Remove(0, 2);
|
469
|
}
|
470
|
if (p_lower.StartsWith("-q"))
|
471
|
{
|
472
|
p.Remove(0, 2);
|
473
|
options.quiet = true;
|
474
|
}
|
475
|
|
476
|
if (p_lower.StartsWith("-d"))
|
477
|
{
|
478
|
TUG.Mogentes.Program.Options.searchDepth = p.Remove(0, 2);
|
479
|
}
|
480
|
|
481
|
|
482
|
else
|
483
|
foreach (var x in BackEnds)
|
484
|
{
|
485
|
if (p_lower.Equals(String.Format("-{0}", x.Switch)))
|
486
|
{
|
487
|
options.pipeLine.Add(x.GetConstructor());
|
488
|
return;
|
489
|
}
|
490
|
}
|
491
|
|
492
|
}
|
493
|
}
|
494
|
}
|