Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / Program.cs @ 3

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
}