Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / parser / ooaParser.cs

1 3 krennw
/**
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 Antlr.Runtime;
21
using System.Text;
22
using System.Collections.Generic;
23
using System.Text.RegularExpressions;
24
25
namespace TUG.Mogentes
26
{
27
28
    public class CompilerMessage
29
    {
30
        private string m_file;
31
        private int m_line;
32
        private int m_column;
33
        private string m_message;
34
35
        public CompilerMessage(string aFile, int aLine, int aColumn, string aMessage)
36
        {
37
            m_file = aFile;
38
            m_line = aLine;
39
            m_column = aColumn;
40
            m_message = aMessage;
41
        }
42
43
        public CompilerMessage(string aFile, IToken aSymbol, string aMessage)
44
        {
45
            m_file = aFile;
46
            m_line = aSymbol.Line;
47
            m_column = aSymbol.CharPositionInLine;
48
            m_message = aMessage;
49
        }
50
51
        public string file { get { return m_file; } }
52
        public int line { get { return m_line; } }
53
        public int column { get { return m_column; } }
54
        public string message { get { return m_message; } }
55
56
    }
57
58
59
    public class ParserError : CompilerMessage
60
    {
61
        public ParserError(string aFile, int aLine, int aColumn, string aMessage)
62
            : base(aFile, aLine, aColumn, aMessage)
63
        { }
64
65
        public ParserError(string aFile, IToken aSymbol, string aMessage)
66
            : base(aFile, aSymbol, aMessage)
67
        { }
68
    }
69
70
71
    public class ParserWarning : CompilerMessage
72
    {
73
        public ParserWarning(string aFile, int aLine, int aColumn, string aMessage)
74
            : base(aFile, aLine, aColumn, aMessage)
75
        { }
76
77
        public ParserWarning(string aFile, IToken aSymbol, string aMessage)
78
            : base(aFile, aSymbol, aMessage)
79
        { }
80
    }
81
82
    public class ParserMessage : CompilerMessage
83
    {
84
        public ParserMessage(string aFile, int aLine, int aColumn, string aMessage)
85
            : base(aFile, aLine, aColumn, aMessage)
86
        { }
87
88
        public ParserMessage(string aFile, IToken aSymbol, string aMessage)
89
            : base(aFile, aSymbol, aMessage)
90
        { }
91
    }
92
93
94
    public class ParserState
95
    {
96
        public ooaParser parser;
97
        public ooaLexer lexer;
98
        public string filename;
99
        public string namesTypePrefix = String.Empty;
100
        public bool parsingAttributes;
101
102
103
        public MainModule ooaSystem;
104
105
        public IScope currentScope;
106
        public List<ParserError> listOfParserErrors;
107
        public List<ParserWarning> listOfParserWarnings;
108
        public List<ParserMessage> listOfParserMessages;
109
        public List<OpaqueType> typesToFixUp;
110
111
        public ParserState(Program.Options options)
112
        {
113
            listOfParserErrors = new List<ParserError>();
114
            listOfParserWarnings = new List<ParserWarning>();
115
            listOfParserMessages = new List<ParserMessage>();
116
            typesToFixUp = new List<OpaqueType>();
117
            this.filename = options.fileToParse;
118
            this.namesTypePrefix = options.namedTypePrefix;
119
            ICharStream input = new ANTLRFileStream(filename, Encoding.ASCII);
120
            lexer = new ooaLexer(input);
121
            CommonTokenStream tokens = new CommonTokenStream(lexer);
122
            parser = new ooaParser(tokens);
123
            parser.pState = this;
124
        }
125
126
        public void AddErrorMessage(ParserError parserError)
127
        {
128
            listOfParserErrors.Add(parserError);
129
        }
130
        public void AddWarningMessage(ParserWarning parserWarning)
131
        {
132
            listOfParserWarnings.Add(parserWarning);
133
        }
134
        public void AddMessage(ParserMessage aMessage)
135
        {
136
            listOfParserMessages.Add(aMessage);
137
        }
138
139
        public Identifier Lookup(string symbolName, IScope resolveStack)
140
        {
141
            string lkupname = symbolName;
142
            do
143
            {
144
                Identifier result = resolveStack.ResolveIdentifier(lkupname);
145
                if (result != null)
146
                    return result;
147
                resolveStack = resolveStack.GetParentScope();
148
            } while (resolveStack != null);
149
150
            return null;
151
        }
152
        public Identifier Lookup(string symbolName)
153
        {
154
            return Lookup(symbolName, currentScope);
155
        }
156
        public Identifier Lookup(IToken symbolName)
157
        {
158
            if (symbolName != null)
159
                return Lookup(symbolName.Text);
160
            else
161
                return null;
162
        }
163
164
        public void PushResolveStack(IScope newScope)
165
        {
166
            // some sanity check.
167
            if (newScope is MethodIdentifier)
168
                System.Diagnostics.Debug.Assert(currentScope is OoActionSystemType);
169
170
            newScope.SetParentScope(currentScope);
171
            currentScope = newScope;
172
        }
173
        public void PopResolveStack()
174
        {
175
            currentScope = currentScope.GetParentScope();
176
        }
177
    }
178
179
180
    public partial class ooaParser : Parser
181
    {
182
        public ParserState pState { get; set; }
183
184
185
186
187
        public bool IsRightToLeft(ExpressionKind type)
188
        {
189
            return type == ExpressionKind.implies; // implication has right grouping
190
        }
191
192
        public int GetOperatorPrecedence(ExpressionKind type)
193
        {
194
            switch (type)
195
            {
196
                /*Family of Evaluators*/
197
198
                case ExpressionKind.abs:    // T_ABS:
199
                case ExpressionKind.card:   // T_CARD:
200
                case ExpressionKind.dom:    // T_DOM:
201
                case ExpressionKind.range:  // T_RNG:
202
                case ExpressionKind.merge:  // T_MERGE:
203
                case ExpressionKind.len:    // T_LEN:
204
                case ExpressionKind.elems:  // T_ELEMS:
205
                case ExpressionKind.head:   // T_HEAD:
206
                case ExpressionKind.tail:   // T_TAIL:
207
                case ExpressionKind.conc:   // T_CONC:
208
                case ExpressionKind.inds:   // T_INDS:
209
                case ExpressionKind.dinter: // T_DINTER:
210
                case ExpressionKind.dunion: // T_DUNION:
211
                    return 1;
212
213
                case ExpressionKind.domresby:   // T_DOMRESBY:
214
                case ExpressionKind.domresto:   // T_DOMRESTO:
215
                case ExpressionKind.rngresby:   // T_RNGRESBY:
216
                case ExpressionKind.rngresto:   // T_RNGRESTO:
217
                    return 2;
218
219
                case ExpressionKind.div:    // T_DIV:
220
                case ExpressionKind.idiv:   // T_IDIV:
221
                case ExpressionKind.mod:    // T_MOD:
222
                case ExpressionKind.prod:   // T_PROD:
223
                case ExpressionKind.inter:  // T_INTER:
224
                    return 3;
225
226
                case ExpressionKind.sum:    // T_SUM:
227
                case ExpressionKind.minus:  // T_MINUS:
228
                case ExpressionKind.union:  // T_UNION:
229
                case ExpressionKind.diff:   // T_DIFF:
230
                case ExpressionKind.munion: // T_MUNION:
231
                case ExpressionKind.seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE:
232
                    return 4;
233
234
                /*Family of Relations*/
235
236
                case ExpressionKind.less:
237
                case ExpressionKind.lessequal:
238
                case ExpressionKind.greater:
239
                case ExpressionKind.greaterequal:
240
                case ExpressionKind.equal:
241
                case ExpressionKind.notequal:
242
                case ExpressionKind.subset:
243
                case ExpressionKind.elemin:
244
                case ExpressionKind.notelemin:
245
                    return 5;
246
247
                /*Family of Connectives*/
248
249
                case ExpressionKind.and:    // T_AND:
250
                    return 6;
251
252
                case ExpressionKind.or:     // T_OR:
253
                    return 7;
254
255
                case ExpressionKind.implies:    // T_IMPLIES:
256
                    return 8;
257
258
                case ExpressionKind.biimplies:  // T_BIIMPLIES:
259
                    return 9;
260
261
                default:
262
                    throw new NotImplementedException("operator not supported: " + type.ToString());
263
                // return 0;
264
            }
265
        }
266
267
        /*taken from antlr homepage:
268
         http://www.antlr.org/wiki/display/ANTLR3/Operator+precedence+parser
269
         */
270
        int findPivot(List<BinaryOperator> operators, int startIndex, int stopIndex)
271
        {
272
            int pivot = startIndex;
273
            int pivotRank = GetOperatorPrecedence(operators[pivot].kind);
274
            for (int i = startIndex + 1; i <= stopIndex; i++)
275
            {
276
                ExpressionKind type = operators[i].kind;
277
                int current = GetOperatorPrecedence(type);
278
                bool rtl = IsRightToLeft(type);
279
                if (current > pivotRank || (current == pivotRank && rtl))
280
                {
281
                    pivot = i;
282
                    pivotRank = current;
283
                }
284
            }
285
            return pivot;
286
        }
287
288
        internal Expression createPrecedenceTree(
289
            List<Expression> expressions,
290
            List<BinaryOperator> operators,
291
            int startIndex,
292
            int stopIndex)
293
        {
294
            if (stopIndex == startIndex)
295
                return expressions[startIndex];
296
297
            int pivot = findPivot(operators, startIndex, stopIndex - 1);
298
299
            BinaryOperator result = operators[pivot];
300
            result.SetLeftChild(createPrecedenceTree(expressions, operators, startIndex, pivot));
301
            result.SetRightChild(createPrecedenceTree(expressions, operators, pivot + 1, stopIndex));
302
303
            return result;
304
        }
305
306
        internal Expression createPrecedenceTree(List<Expression> expressions, List<BinaryOperator> operators)
307
        {
308
            return createPrecedenceTree(expressions, operators, 0, expressions.Count - 1);
309
        }
310
311
312
        /* add error message to state. */
313
        private void doError(IToken aToken, string aMessage)
314
        {
315
            pState.AddErrorMessage(
316
                new ParserError(pState.filename, aToken, aMessage));
317
        }
318
319
        /* add warning message to state */
320
        private void doWarning(IToken id1, string p)
321
        {
322
            pState.AddWarningMessage(new ParserWarning(pState.filename, id1, p));
323
        }
324
325
        private void doError(string aMessage)
326
        {
327
            pState.AddErrorMessage(
328
                new ParserError(pState.filename, 0, 0, aMessage));
329
        }
330
331
        /* init global state */
332
        internal void initializeTopLevelParserState()
333
        {
334
            pState.ooaSystem = new MainModule();
335
            pState.PushResolveStack(pState.ooaSystem);
336
        }
337
338
339
        private IScope GetScope()
340
        {
341
            return pState.currentScope;
342
        }
343
344
345
        /*create a named constant*/
346
        internal void addNamedConst(IToken aName, Expression anExpr)
347
        {
348
            if (pState.currentScope.ResolveIdentifier(aName.Text) == null)
349
            {
350
                /* needs to be a constant... */
351
                ConstantIdentifier aConst = new ConstantIdentifier(aName, anExpr, GetScope());
352
353
                OoaResolveExpressionsVisitor resolver = new OoaResolveExpressionsVisitor(pState);
354
                aConst.Accept(resolver);
355
356
                if (aConst.Value == null || aConst.Value.type == null || aConst.Value.kind != ExpressionKind.Value)
357
                {
358
                    doError(aName, String.Format("{0} not a constant!", aName.Text));
359
                }
360
                else
361
                {
362
                    aConst.SetType(aConst.Value.type);
363
                    pState.currentScope.AddIdentifier(aConst, null);
364
                }
365
            }
366
            else
367
                doError(aName, String.Format("{0} already defined!", aName.Text));
368
        }
369
370
371
372
        /* create a named type; we're on top-level here */
373
        internal void createNamedType(IToken aName, UlyssesType aType)
374
        {
375
            // precond..
376
            System.Diagnostics.Debug.Assert(aName != null);
377
378
            if (aType == null)
379
            {
380
                doError(aName, String.Format("{0} lacks a type! (Type not added)", aName.Text));
381
                return;
382
            }
383
384
385
            if (pState.currentScope.ResolveIdentifier(aName.Text) == null)
386
            {
387
                TypeIdentifier newid = new TypeIdentifier(aName, aType, GetScope());
388
                aType.SetTypeIdentifier(newid);
389
                pState.currentScope.AddIdentifier(newid, null);
390
            }
391
            else
392
                doError(aName, String.Format("{0} already defined!", aName.Text));
393
394
        }
395
396
        /* create basic structure for an ooa-system descr. resolve stack TOS is now ooa-system symbols */
397
        internal OoActionSystemType createOoaType(IToken refinesSystemName, bool autoCons)
398
        {
399
            Identifier refinedSystem = pState.Lookup(refinesSystemName);
400
            OoActionSystemType refinedSystemType = null;
401
            if ((refinedSystem != null) && (refinedSystem.type != null))
402
            {
403
                if (refinedSystem.type.kind != TypeKind.OoActionSystemType)
404
                    doError(refinesSystemName,
405
                            String.Format("{0} not an object oriented action system", refinesSystemName.Text));
406
                else
407
                    refinedSystemType = (OoActionSystemType)refinedSystem.type;
408
            }
409
            else if (refinesSystemName != null)
410
            {
411
                pState.AddErrorMessage(
412
                    new ParserError(pState.filename, refinesSystemName,
413
                        String.Format("Type that's being refined ({0}) not found!", refinesSystemName.Text)));
414
            }
415
416
            OoActionSystemType result = new OoActionSystemType(autoCons, refinedSystemType, null);
417
418
419
            // add 'self' to the symbols.. (self is a keyword, so it can't be defined)
420
            result.AddIdentifier(new SelfTypeIdentifier("self", result, GetScope()), null);
421
422
423
424
            pState.PushResolveStack(result);
425
            return result;
426
        }
427
428
        /* remove ooa-system symbols from resolve stack TOS */
429
        internal void fixupOoaType(OoActionSystemType aTypeSymbol)
430
        {
431
            if (aTypeSymbol == null)
432
                return;
433
434
            aTypeSymbol.SetupAnonymousName();
435
            if (aTypeSymbol != null)
436
                pState.PopResolveStack();
437
        }
438
439
        internal Expression addCastExpression(Expression e, IToken cid)
440
        {
441
            System.Diagnostics.Debug.Assert(e != null);
442
443
            Expression result = new UnaryOperator(ExpressionKind.Cast, e, cid.Line, cid.CharPositionInLine);
444
            result.SetType(new OpaqueType(new TypeIdentifier(cid, null, GetScope())));
445
            pState.typesToFixUp.Add((OpaqueType)result.type);
446
            return result;
447
        }
448
449
450
        /* add a new ooa to the list describing the composition of action systems */
451
        internal void addToIdentifierList(IdentifierList top, IToken aName)
452
        {
453
            System.Diagnostics.Debug.Assert(top != null);
454
455
            Identifier aSym = pState.Lookup(aName);
456
            if (aSym == null)
457
            {
458
                doError(aName, String.Format("Could not find ooa-system {0}!", aName.Text));
459
            }
460
            else if ((aSym.type == null) || !(aSym.type.kind == TypeKind.OoActionSystemType))
461
            {
462
                doError(aName, String.Format("Referenced type ({0}) does not have correct type!", aName.Text));
463
            }
464
            else
465
            {
466
                OoActionSystemType aType = (OoActionSystemType)aSym.type;
467
                if (aType.isInSystemDescription)
468
                    doError(aName, String.Format("Referenced type ({0}) already used in composition!", aName.Text));
469
                else
470
                    aType.SetIsInSystemDescription(true);
471
                top.AddElement(aSym);
472
            }
473
        }
474
475
        /* does a fixup run after parsing */
476
        internal void fixUpRun(IdentifierList sysDescr)
477
        {
478
            // set system descr.
479
            pState.ooaSystem.SetSystemDescription(sysDescr);
480
481
            // fixup named types
482
            FixupNamedTypes();
483
        }
484
485
        private void FixupNamedTypes()
486
        {
487
            /*named type refs that could not be resolved in the first run, have to
488
              be resolved now. */
489
            foreach (var ntype in pState.typesToFixUp)
490
            {
491
                if (ntype.resolvedType == null)
492
                {
493
                    //ntype.identifier
494
                    Identifier asym = pState.Lookup(ntype.identifier.tokenText, ntype.identifier.definingScope);
495
                    if ((asym == null) || (asym.kind != IdentifierKind.TypeIdentifier))
496
                    {
497
                        ParserError error = new ParserError(pState.filename, ntype.identifier.line, ntype.identifier.column,
498
                            String.Format("Can not resolve {0} to a named type", ntype.identifier.tokenText));
499
                        pState.AddErrorMessage(error);
500
                    }
501
                    else
502
                        ntype.SetResolvedType(asym.type);
503
                }
504
            }
505
            pState.typesToFixUp.Clear();
506
        }
507
508
509
        private bool TosIsActionSystem()
510
        {
511
            return pState.currentScope is OoActionSystemType;
512
        }
513
514
515
        private int currentLine
516
        {
517
            get
518
            {
519
                IToken token = input.LT(-1);
520
                return token == null ? 0 : token.Line;
521
            }
522
        }
523
524
        private int currentPos
525
        {
526
            get
527
            {
528
                IToken token = input.LT(-1);
529
                return token == null ? 0 : token.CharPositionInLine;
530
            }
531
        }
532
533
        /* add var symbol to the current action system */
534
        internal void createAttribute(IToken varname, bool isStatic, bool isObs, bool isCtr, UlyssesType aType, Expression anExpr)
535
        {
536
            if (!TosIsActionSystem())
537
                return;
538
539
            if (aType == null)
540
            {
541
                doError(varname, String.Format("{0} lacks type!", varname.Text));
542
            }
543
            if (anExpr == null)
544
            {
545
                doError(varname, String.Format("{0} lacks initializer!", varname.Text));
546
            }
547
            if (isObs == true || isCtr == true)
548
                if (aType.kind != TypeKind.QrType)
549
                    doError(varname, "'obs' or 'ctr' on attributes only allowed for qualitative types");
550
551
552
            AttributeIdentifier var = new AttributeIdentifier(varname, aType, GetScope(), anExpr, isStatic, isObs, isCtr);
553
            if (pState.currentScope.ResolveIdentifier(varname.Text) == null)
554
                pState.currentScope.AddIdentifier(var, null);
555
            else
556
                doError(varname, String.Format("Can not add {0}: Symbol already defined!", varname.Text));
557
        }
558
559
560
        /* create a bool type */
561
        internal BoolType createBoolType()
562
        {
563
            return new BoolType(null);
564
        }
565
566
        /* create a char type */
567
        internal CharType createCharType()
568
        {
569
            return new CharType(null);
570
        }
571
572
        /* create an int type */
573
        internal UlyssesType createIntType(IToken rangeLow, IToken rangeHigh)
574
        {
575
            int low = 0;
576
            int high = 0;
577
578
            if (rangeLow.Type == ooaLexer.T_INFTY)
579
                doError(rangeLow, "Infinity not supported.");
580
            if (rangeLow.Type == ooaLexer.T_INFTY)
581
                doError(rangeHigh, "Infinity not supported.");
582
583
            if (rangeLow.Type == ooaLexer.T_IDENTIFIER)
584
            {
585
                // see whether we can find the constant
586
                Identifier aconst = pState.currentScope.ResolveIdentifier(rangeLow.Text);
587
                if (aconst == null || aconst.kind != IdentifierKind.Constant)
588
                    doError(rangeLow, String.Format("Constant {0} not found", rangeLow.Text));
589
                else if (aconst.type.kind != TypeKind.IntType)
590
                    doError(rangeLow, "Constant must be integer");
591
                else
592
                    low = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
593
            }
594
            else
595
                if (!Int32.TryParse(rangeLow.Text, out low))
596
                    doError(rangeLow, "Can not convert to integer");
597
598
            if (rangeHigh.Type == ooaLexer.T_IDENTIFIER)
599
            {
600
                // see whether we can find the constant
601
                Identifier aconst = pState.currentScope.ResolveIdentifier(rangeHigh.Text);
602
                if (aconst == null || aconst.kind != IdentifierKind.Constant)
603
                    doError(rangeHigh, String.Format("Constant {0} not found", rangeHigh.Text));
604
                else if (aconst.type.kind != TypeKind.IntType)
605
                    doError(rangeHigh, "Constant must be integer");
606
                else
607
                    high = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
608
            }
609
            else
610
                if (!Int32.TryParse(rangeHigh.Text, out high))
611
                    doError(rangeHigh, "Can not convert to interger");
612
613
            if (high < low)
614
                doError(rangeHigh, "Lower bound greater than upper bound");
615
616
            return new IntType(low, high, null);
617
        }
618
619
        /* create a float type */
620
        internal UlyssesType createFloatType(IToken rangeLow, IToken rangeHigh)
621
        {
622
            float low = 0;
623
            float high = 0;
624
625
            if (rangeLow.Type == ooaLexer.T_INFTY)
626
                doError(rangeLow, "Infinity not supported.");
627
            if (rangeLow.Type == ooaLexer.T_INFTY)
628
                doError(rangeHigh, "Infinity not supported.");
629
630
            if (rangeLow.Type == ooaLexer.T_IDENTIFIER)
631
            {
632
                // see whether we can find the constant
633
                Identifier aconst = pState.currentScope.ResolveIdentifier(rangeLow.Text);
634
                if (aconst == null || aconst.kind != IdentifierKind.Constant)
635
                    doError(rangeLow, String.Format("Constant {0} not found", rangeLow.Text));
636
                else if (aconst.type.kind != TypeKind.FloatType)
637
                    doError(rangeLow, "Constant must be float");
638
                else
639
                    low = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
640
            }
641
            else if (!float.TryParse(rangeLow.Text, out low))
642
                doError(rangeLow, "Can not convert to float (single)");
643
644
            if (rangeHigh.Type == ooaLexer.T_IDENTIFIER)
645
            {
646
                // see whether we can find the constant
647
                Identifier aconst = pState.currentScope.ResolveIdentifier(rangeHigh.Text);
648
                if (aconst == null || aconst.kind != IdentifierKind.Constant)
649
                    doError(rangeHigh, String.Format("Constant {0} not found", rangeHigh.Text));
650
                else if (aconst.type.kind != TypeKind.FloatType)
651
                    doError(rangeHigh, "Constant must be integer");
652
                else
653
                    high = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
654
            }
655
            else if (!float.TryParse(rangeHigh.Text, out high))
656
                doError(rangeHigh, "Can not convert to float (single)");
657
658
            if (high < low)
659
                doError(rangeHigh, "Lower bound greater than upper bound");
660
661
            /* precision */
662
            float afterc_low = low - (float)Convert.ToInt32(low);
663
            float afterc_high = high - (float)Convert.ToInt32(high);
664
            float precision = afterc_low < afterc_high ? afterc_low : afterc_high;
665
666
            return new FloatType(low, high, precision, null);
667
        }
668
669
        /* create a list of an enumerated type */
670
        internal UlyssesType createListEnumType(IToken alistelem)
671
        {
672
            EnumType hiddenEnumType = new EnumType(null);
673
674
            ListType result = new ListType(hiddenEnumType, 500, null);
675
            addToListEnumType(result, alistelem);
676
            return result;
677
        }
678
679
        /* add a new enum symbol to a list with an anonymous enumerated type */
680
        internal void addToListEnumType(UlyssesType aTypeSymbol, IToken otherlistelem)
681
        {
682
            EnumType enumtype = (EnumType)((ListType)aTypeSymbol).innerType;
683
            addToEnumType(enumtype, otherlistelem, null);
684
        }
685
686
        /* create a new enumerated type */
687
        internal UlyssesType createEnumType(IToken aRangeValue, IToken anIntegerValue)
688
        {
689
            EnumType result;
690
691
            if (anIntegerValue == null)
692
                result = new EnumType(null);
693
            else
694
                result = new ValuedEnumType(null);
695
696
            addToEnumType(result, aRangeValue, anIntegerValue);
697
            return result;
698
        }
699
700
        /* add a new enum symbol to the enumerated type */
701
        internal void addToEnumType(UlyssesType aTypeSymbol, IToken otherRangeValue, IToken anIntegerValue)
702
        {
703
            EnumType anEnum = (EnumType)aTypeSymbol;
704
            if (anEnum.symbolTable.Defined(otherRangeValue.Text))
705
            {
706
                doError(otherRangeValue, String.Format("Element '{0}' already defined!", otherRangeValue.Text));
707
                return;
708
            }
709
710
            /* for now we allow the usage of enum-ids without specifying the actual enum type,
711
             * e.g., x = some_enum_id, hence all enum identifier must be globally unique.
712
             * This decision could be reverted at later time...
713
             */
714
            Identifier sym = pState.Lookup(otherRangeValue);
715
            if (sym != null)
716
            {
717
                doError(otherRangeValue, String.Format("Element '{0}' already defined!", otherRangeValue.Text));
718
                return;
719
            }
720
721
            EnumIdentifier enumval;
722
            if (anIntegerValue == null)
723
            {
724
                if (aTypeSymbol is ValuedEnumType)
725
                {
726
                    doError(otherRangeValue, String.Format("Element '{0}' needs integer value!", otherRangeValue.Text));
727
                    return;
728
                }
729
730
                enumval = new EnumIdentifier(otherRangeValue, (EnumType)aTypeSymbol, GetScope());
731
            }
732
            else
733
            {
734
                if (!(aTypeSymbol is ValuedEnumType))
735
                {
736
                    doError(otherRangeValue, String.Format("Element '{0}' must not have integer value!", otherRangeValue.Text));
737
                    return;
738
                }
739
                enumval = new EnumIdentifier(otherRangeValue, Int32.Parse(anIntegerValue.Text), (EnumType)aTypeSymbol, GetScope());
740
            }
741
742
            ((EnumType)aTypeSymbol).AddEnumSymbol(enumval);
743
744
            /* add the enum id to 'global' state */
745
            pState.currentScope.AddIdentifier(enumval, null);
746
        }
747
748
        /* get a named type */
749
        internal UlyssesType getNamedType(IToken aType)
750
        {
751
            UlyssesType result = null;
752
            Identifier sym = pState.Lookup(aType);
753
            if (sym == null)
754
            {
755
                /* we might not have seen this type yet - so do a fixup run later */
756
                result = new OpaqueType(new TypeIdentifier(aType, null, GetScope()));
757
                pState.typesToFixUp.Add((OpaqueType)result);
758
            }
759
            else if (sym.kind == IdentifierKind.TypeIdentifier)
760
                result = ((TypeIdentifier)sym).type;
761
            else
762
                doError(aType, "Not a named type symbol!");
763
764
            return result;
765
        }
766
767
        /* create a list type */
768
        internal UlyssesType createListType(IToken numOfElements, UlyssesType innertype)
769
        {
770
            if (innertype == null)
771
                doError(numOfElements, "List type lacks proper element type (null)");
772
773
            int numElems = 0;
774
775
            if (numOfElements.Type == ooaLexer.T_IDENTIFIER)
776
            {
777
                // see whether we can find the constant
778
                Identifier aconst = pState.currentScope.ResolveIdentifier(numOfElements.Text);
779
                if (aconst == null || aconst.kind != IdentifierKind.Constant)
780
                    doError(numOfElements, String.Format("Constant {0} not found", numOfElements.Text));
781
                else if (aconst.type.kind != TypeKind.IntType)
782
                    doError(numOfElements, "Constant must be integer");
783
                else
784
                    numElems = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
785
            }
786
            else
787
            {
788
                if (!Int32.TryParse(numOfElements.Text, out numElems))
789
                    doError(numOfElements, "Not an integer");
790
                if (numElems <= 0)
791
                    doError(numOfElements, "Number of elements in a list must be >= 1");
792
            }
793
794
            ListType result = new ListType(innertype, numElems, null);
795
            return result;
796
        }
797
798
        /* create a map type */
799
        internal UlyssesType createMapType(IToken numOfElements, UlyssesType mapfromtype, UlyssesType maptotype)
800
        {
801
            if (mapfromtype == null)
802
                doError(numOfElements, "Map: From-type not set (null)");
803
            if (maptotype == null)
804
                doError(numOfElements, "Map: To-type not set (null)");
805
806
            int max = 0;
807
808
            if (numOfElements.Type == ooaLexer.T_IDENTIFIER)
809
            {
810
                // see whether we can find the constant
811
                Identifier aconst = pState.currentScope.ResolveIdentifier(numOfElements.Text);
812
                if (aconst == null || aconst.kind != IdentifierKind.Constant)
813
                    doError(numOfElements, String.Format("Constant {0} not found", numOfElements.Text));
814
                else if (aconst.type.kind != TypeKind.IntType)
815
                    doError(numOfElements, "Constant must be integer");
816
                else
817
                    max = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
818
            }
819
            else
820
                if (!Int32.TryParse(numOfElements.Text, out max))
821
                    doError(numOfElements, "Not an integer");
822
823
            MapType result = new MapType(mapfromtype, maptotype, max, null);
824
            return result;
825
        }
826
827
        /* create a tuple type */
828
        internal UlyssesType createTupleType(UlyssesType aType)
829
        {
830
            TupleType result = new TupleType(null);
831
            if (aType == null)
832
                doError("Unknown inner type.");
833
            else
834
                addToTupleType(result, aType);
835
            return result;
836
        }
837
838
        /* add inner type to tuple */
839
        internal void addToTupleType(UlyssesType aTypeSymbol, UlyssesType anotherType)
840
        {
841
            if (anotherType == null)
842
                doError("Unknown inner type.");
843
            else
844
            {
845
                TupleType tuple = (TupleType)aTypeSymbol;
846
                tuple.AddType(anotherType);
847
            }
848
        }
849
850
        /* create a QR type */
851
        internal UlyssesType createQrType(IToken alandmark)
852
        {
853
            QrType result = new QrType(null);
854
            addToQrType(result, alandmark);
855
            return result;
856
        }
857
858
        /* add another landmark to QR type */
859
        private void addToQrType(UlyssesType aTypeSymbol, IToken otherlandmark)
860
        {
861
            Identifier sym = pState.Lookup(otherlandmark);
862
            if (sym != null)
863
            {
864
                doError(otherlandmark, String.Format("Redifinition of {0}", otherlandmark.Text));
865
                return;
866
            }
867
868
            LandmarkIdentifier lndmrk = new LandmarkIdentifier(otherlandmark, (QrType)aTypeSymbol, GetScope());
869
            ((QrType)aTypeSymbol).AddLandmark(lndmrk);
870
        }
871
872
        /* gets called after a simple type has been constructed. used to define an internal name*/
873
        internal void fixupSimpleType(UlyssesType aTypeSymbol)
874
        {
875
            if (aTypeSymbol != null)
876
                aTypeSymbol.SetupAnonymousName();
877
        }
878
879
        /* gets called after a simple or complex type has been constructed. used to define an internal name */
880
        internal void fixupComplexType(UlyssesType aTypeSymbol)
881
        {
882
            if (aTypeSymbol != null)
883
                aTypeSymbol.SetupAnonymousName();
884
        }
885
886
887
        /* create a method symbol */
888
        internal FunctionIdentifier createMethodSymbol(IToken mname)
889
        {
890
            Identifier sym = pState.Lookup(mname);
891
            if (sym != null)
892
            {
893
                doError(mname, String.Format("Redefinition of {0}", mname.Text));
894
                return null;
895
            }
896
897
            FunctionType funtype = new FunctionType(FunctionTypeEnum.Method, new LinkedList<UlyssesType>(), null);
898
            MethodIdentifier msym = new MethodIdentifier(mname, funtype, GetScope());
899
            funtype.SetTypeIdentifier(msym);
900
901
            pState.currentScope.AddIdentifier(msym, null);
902
903
            pState.PushResolveStack(msym);
904
            return msym;
905
        }
906
907
        /* remove local method symbols from resolution stack again */
908
        private void popResolveStack(FunctionIdentifier newMethod)
909
        {
910
            if (newMethod != null)
911
                pState.PopResolveStack();
912
        }
913
914
915
        /* add a return type to a method */
916
        internal void setMethodReturnType(FunctionIdentifier newMethod, UlyssesType rt)
917
        {
918
            if (newMethod == null)
919
                return;
920
921
            if (rt == null)
922
                doError(String.Format("Method {0} has no return type (null)", newMethod.tokenText));
923
924
            /* set return type */
925
            ((FunctionType)newMethod.type).SetReturnType(rt);
926
927
928
            /* add hidden return parameter */
929
            if (newMethod.symbolTable.Defined("result"))
930
            {
931
                doError(String.Format("Method {0} defines 'result'", newMethod.tokenText));
932
                return;
933
            }
934
935
            ParameterIdentifier returnval = new ParameterIdentifier("result", rt, GetScope());
936
            newMethod.symbolTable.AddIdentifier(returnval);
937
        }
938
939
        /* add a parameter to a method */
940
        internal void addMethodParameter(FunctionIdentifier newMethod, IToken paramName, UlyssesType atype)
941
        {
942
            if (newMethod == null)
943
                return;
944
945
            if (atype == null)
946
                doError(paramName, "Parameter has no type (null)");
947
948
949
            if (newMethod.symbolTable.Defined(paramName.Text) == true)
950
            {
951
                doError(paramName, String.Format("Parameter {0} already defined", paramName.Text));
952
                return;
953
            }
954
955
            // add parameter to scope
956
            ParameterIdentifier param = new ParameterIdentifier(paramName, atype, GetScope());
957
            newMethod.AddParameter(param);
958
959
            // add type of param to signature
960
            FunctionType ftype = (FunctionType)newMethod.type;
961
            ftype.AddParameterType(atype);
962
        }
963
964
        /* set method body of a method */
965
        internal void addMethodBody(FunctionIdentifier newMethod, Block statements)
966
        {
967
            if (newMethod == null)
968
                return;
969
970
            if (statements == null)
971
                doError(String.Format("{0} has empty body (null)",
972
                    ((FunctionType)newMethod.type).functionType == FunctionTypeEnum.Method ? "Method" : "Action"));
973
974
            newMethod.SetBody(statements);
975
        }
976
977
        /* create a continuous action */
978
        internal FunctionIdentifier createNamedContinuousAction(IToken cactionname, FunctionTypeEnum actionTypeEnum)
979
        {
980
            return createNamedAction(cactionname, actionTypeEnum);
981
        }
982
983
        /* create a named action */
984
        internal FunctionIdentifier createNamedAction(IToken actionname, FunctionTypeEnum actionType)
985
        {
986
            Identifier sym = pState.Lookup(actionname);
987
            if (sym != null)
988
            {
989
                doError(actionname, "Symbol already defined.");
990
                return null;
991
            }
992
993
            FunctionType atype = new FunctionType(actionType, new LinkedList<UlyssesType>(), null);
994
            NamedActionIdentifier action = new NamedActionIdentifier(actionname, atype, GetScope());
995
            atype.SetTypeIdentifier(action);
996
997
            pState.currentScope.AddIdentifier(action, null);
998
            pState.PushResolveStack(action);
999
            return action;
1000
        }
1001
1002
        /* add body of action */
1003
        internal void addActionBody(FunctionIdentifier newAction, GuardedCommand body)
1004
        {
1005
            // we need a wrapper around the guarded command..
1006
            Block bdy = new SeqBlock(currentLine, currentPos);
1007
            bdy.AddStatement(body);
1008
            addMethodBody(newAction, bdy);
1009
        }
1010
1011
        /* add constraints of cont. action */
1012
        internal void addContinuousActionBody(FunctionIdentifier newAction, GuardedCommand constraints)
1013
        {
1014
            Block bdy = new SeqBlock(currentLine, currentPos);
1015
            bdy.AddStatement(constraints);
1016
            addMethodBody(newAction, bdy);
1017
        }
1018
1019
        /* create a guarded command */
1020
        internal GuardedCommand createGuardedCommandStatement(Expression expr, Block bdy)
1021
        {
1022
            if (bdy == null)
1023
                doError("Guarded command without body (null)!");
1024
1025
            if (expr == null)
1026
                doError("Guarded command without guard (null)!");
1027
1028
            GuardedCommand result = new GuardedCommand(expr, bdy, currentLine, currentPos);
1029
            return result;
1030
        }
1031
        internal GuardedCommand createGuardedCommandStatement(Expression expr, Block bdy, bool isQualitative)
1032
        {
1033
            GuardedCommand result = createGuardedCommandStatement(expr, bdy);
1034
            result.SetIsQualitative(isQualitative);
1035
            return result;
1036
        }
1037
1038
        /* add statements to list */
1039
        internal void addToStatementList(Block top, Statement stmt)
1040
        {
1041
            if (stmt == null)
1042
                doError("Can not add statement: null!");
1043
1044
            top.AddStatement(stmt);
1045
        }
1046
1047
        /* create a Kill statement */
1048
        internal Statement createKillStatement(IToken aname)
1049
        {
1050
            Identifier sym = pState.Lookup(aname);
1051
            if (sym == null)
1052
                doError(aname, "Not defined");
1053
1054
            KillStatement result = new KillStatement(sym, aname.Line, aname.CharPositionInLine);
1055
            return result;
1056
        }
1057
1058
        /* create a Skip statement */
1059
        internal Statement createSkipStatement()
1060
        {
1061
            return new SkipStatement(currentLine, currentPos);
1062
        }
1063
1064
        /* create an Abort statement */
1065
        internal Statement createAbortStatement()
1066
        {
1067
            return new AbortStatement(currentLine, currentPos);
1068
        }
1069
1070
        /* creates a prioritized composition block */
1071
        internal Block createPrioBlock(Block top)
1072
        {
1073
            return new PrioBlock(top, currentLine, currentPos);
1074
        }
1075
1076
        /* creates a nondeterministically composed block */
1077
        internal Block createNondetBlock(Block top)
1078
        {
1079
            return new NondetBlock(top, currentLine, currentPos);
1080
        }
1081
1082
        /* creates a sequentially composed block */
1083
        internal Block createSeqBlock(Block top)
1084
        {
1085
            return new SeqBlock(top, currentLine, currentPos);
1086
        }
1087
1088
1089
        /* adds a filter expression to seq block */
1090
        private void addSeqBlockExpression(Block seqList, Expression sexpr)
1091
        {
1092
            seqList.SetFilter(sexpr); /*gets transformed to guarded command in resolvevisitor!*/
1093
        }
1094
1095
1096
        /* create a self identifier */
1097
        internal IdentifierExpression createSelfIdentifierExpression(IToken self)
1098
        {
1099
            Identifier id = pState.Lookup("self");
1100
            if (id == null)
1101
            {
1102
                doError(self, "Can not resolve 'self'");
1103
                return null;
1104
            }
1105
1106
            IdentifierExpression result = new IdentifierExpression(id, self.Line, self.CharPositionInLine);
1107
            result.setIsSelf(true);
1108
            return result;
1109
        }
1110
1111
        /* build up identifier tree... */
1112
        internal Expression createIdentifierAccessExpression(IdentifierExpression aself, IToken token)
1113
        {
1114
            Identifier someid = pState.Lookup(token.Text, GetScope());
1115
            Identifier self = pState.Lookup("self");
1116
1117
            if (someid != null)
1118
            {
1119
                switch (someid.kind)
1120
                {
1121
                    /* all method and attribute accesses are prefixed by self */
1122
                    case IdentifierKind.AttributeIdentifier:
1123
                    case IdentifierKind.MethodIdentifier:
1124
                        if (self == null)
1125
                            doError(token, "Self access of method: Can not find 'self' symbol! (internal error)");
1126
                        aself = new IdentifierExpression(self, token.Line, token.CharPositionInLine);
1127
                        aself.setIsSelf(true);
1128
                        break;
1129
                    default:
1130
                        break;
1131
                }
1132
            }
1133
1134
            IdentifierExpression ident = new UnresolvedIdentifierExpression(token, GetScope());
1135
            if (aself != null)
1136
                return new AccessExpression(aself, ident, token.Line, token.CharPositionInLine);
1137
            else
1138
                return ident;
1139
        }
1140
1141
        internal AccessExpression addIdentifierAccessExpression(Expression parent, IToken token)
1142
        {
1143
            IdentifierExpression ident = new UnresolvedIdentifierExpression(token, GetScope());
1144
            return new AccessExpression(parent, ident, token.Line, token.CharPositionInLine);
1145
        }
1146
1147
        /* we have a primed id; prime the complete subtree.. */
1148
        internal void setIdentifierExpressionPrimed(ref Expression result, IToken token)
1149
        {
1150
            Expression priming = new UnaryOperator(ExpressionKind.Primed, result, token.Line, token.CharPositionInLine);
1151
            result = priming;
1152
        }
1153
1154
        /* create a fold operation */
1155
        internal Expression createFoldExpression(Expression result, IToken afold, Expression initval, Expression anexpr)
1156
        {
1157
            ExpressionKind akind = ExpressionKind.foldLR;
1158
            if (afold.Type == ooaLexer.T_FOLDLR)
1159
                akind = ExpressionKind.foldLR;
1160
            else if (afold.Type == ooaLexer.T_FOLDRL)
1161
                akind = ExpressionKind.foldRL;
1162
            else
1163
                System.Diagnostics.Debug.Assert(false);
1164
1165
            TernaryOperator op = new TernaryOperator(akind, result, initval, anexpr, currentLine, currentPos, GetScope());
1166
            return op;
1167
        }
1168
1169
1170
        /* create a method access */
1171
        internal CallExpression createMethodAccessExpression(Expression subexpr, List<Expression> m_params, IToken token)
1172
        {
1173
            System.Diagnostics.Debug.Assert(subexpr != null);
1174
1175
            return new CallExpression(subexpr, m_params, token.Line, token.CharPositionInLine, GetScope());
1176
        }
1177
1178
        /* create a tuple or map access */
1179
        internal TupleMapAccessExpression createTupleMapAccessExpression(Expression subexpr, Expression ac, IToken token)
1180
        {
1181
            System.Diagnostics.Debug.Assert(subexpr != null);
1182
1183
            return new TupleMapAccessExpression(subexpr, ac, token.Line, token.CharPositionInLine);
1184
        }
1185
1186
        /* create a method call statement; has to be resolved in a second run */
1187
        internal Statement createCallStatement(Expression aqname)
1188
        {
1189
            return new Call(aqname, currentLine, currentPos);
1190
        }
1191
1192
        /* create a single assignment statement */
1193
        internal Statement createSingleAssignmentStatement(Expression aqname, Expression aexp)
1194
        {
1195
            Assignment result = new Assignment(aqname, aexp, null, currentLine, currentPos);
1196
            return result;
1197
        }
1198
1199
        /* create a multi-assignment statement; has to be resolved in a second run */
1200
        internal Statement createMultipleAssignmentStatementLHS(Expression aqname)
1201
        {
1202
            return new Assignment(aqname, null, null, currentLine, currentPos);
1203
        }
1204
1205
        /* adds an expression to the multi-assign */
1206
        internal void addMutlipleAssignmentStatementRHS(Statement result, Expression mexp)
1207
        {
1208
            ((Assignment)result).AddValue(mexp);
1209
        }
1210
1211
        /* adds a LHS-var to the multi assign */
1212
        internal void addMultipleAssignmentStatementLHS(Statement result, Expression malhs)
1213
        {
1214
            ((Assignment)result).AddPlace(malhs);
1215
        }
1216
1217
        /* pop an assignment statement from the resolve stack */
1218
        internal void popAssignmentOffResolveStack(Statement result)
1219
        {
1220
            System.Diagnostics.Debug.Assert(ReferenceEquals(result, pState.currentScope));
1221
            pState.PopResolveStack();
1222
        }
1223
1224
        /* pushes the assignment statement onto resolve stack. */
1225
        internal void pushAssignmentOnResolveStack(Statement result)
1226
        {
1227
            System.Diagnostics.Debug.Assert(result is Assignment);
1228
            pState.PushResolveStack((Assignment)result);
1229
        }
1230
1231
1232
        /* adds a nondet-assignment constraint */
1233
        internal void addConstraintToAssignment(Statement result, Expression ndexp)
1234
        {
1235
            ((Assignment)result).SetNondetExpression(ndexp);
1236
        }
1237
1238
        /* add a named action call to do-od block */
1239
        internal void addNamedActionCallToBlockList(Block top, IToken aname, List<Expression> m_params, IToken maptoken, Expression amapexpression)
1240
        {
1241
            Identifier id = pState.Lookup(aname);
1242
            if (id == null)
1243
            {
1244
                doError(aname, "Could not find named action");
1245
                return;
1246
            }
1247
            Expression callexpr;
1248
            if (id.kind == IdentifierKind.MethodIdentifier)
1249
            {
1250
                doError(aname, "Method access in do-od block not allowed.");
1251
                return;
1252
                // access via self
1253
                /*
1254
                Identifier self = pState.Lookup("self");
1255
                if (self == null)
1256
                    doError(aname, "Self access of method: Can not find 'self' symbol! (internal error)");
1257
                IdentifierExpression aself = new IdentifierExpression(self, aname.Line, aname.CharPositionInLine);
1258
                aself.setIsSelf(true);
1259
                callexpr = new CallExpression(
1260
                    new AccessExpression(aself,
1261
                        new IdentifierExpression(id, aname.Line, aname.CharPositionInLine), aname.Line, aname.CharPositionInLine),
1262
                        m_params, aname.Line, aname.CharPositionInLine, GetScope());
1263
                 */
1264
            }
1265
            else
1266
                callexpr = new CallExpression(
1267
                   new IdentifierExpression(id, aname.Line, aname.CharPositionInLine),
1268
                       m_params, aname.Line, aname.CharPositionInLine, GetScope());
1269
1270
            if (amapexpression != null)
1271
            {
1272
                ExpressionKind akind = ExpressionKind.foldLR;
1273
                if (maptoken.Type == ooaLexer.T_FOLDLR)
1274
                    akind = ExpressionKind.foldLR;
1275
                else if (maptoken.Type == ooaLexer.T_FOLDRL)
1276
                    akind = ExpressionKind.foldRL;
1277
                else
1278
                    System.Diagnostics.Debug.Assert(false);
1279
1280
                callexpr = new TernaryOperator(akind, callexpr, null, amapexpression,
1281
                    currentLine, currentPos, GetScope());
1282
            }
1283
            Call statement = new Call(callexpr, currentLine, currentPos);
1284
            top.AddStatement(statement);
1285
        }
1286
1287
        /*adds skip statement instead of call to do-od block*/
1288
        internal void addSkipStatementToBlockList(Block top)
1289
        {
1290
            top.AddStatement(new SkipStatement(currentLine, currentPos));
1291
        }
1292
1293
1294
        /* add anonymous action to do-od block */
1295
        internal void addToBlockList(Block top, Statement gcmd)
1296
        {
1297
            if (gcmd != null)
1298
                top.AddStatement(gcmd);
1299
        }
1300
1301
        /* add the do-od block to the action system type */
1302
        internal void addActionBlock(OoActionSystemType aTypeSymbol, Block bl)
1303
        {
1304
            aTypeSymbol.SetDoOdBlock(bl);
1305
        }
1306
1307
        /* push block */
1308
        internal void pushBlockToResolveStack(Block toPush)
1309
        {
1310
            pState.PushResolveStack(toPush);
1311
        }
1312
1313
        /* pop block */
1314
        internal void popBlockFromResolveStack(Block toPop)
1315
        {
1316
            if (toPop != null)
1317
            {
1318
                object anobject = pState.currentScope as Block;
1319
                System.Diagnostics.Debug.Assert(Object.ReferenceEquals(anobject, toPop));
1320
1321
                pState.PopResolveStack();
1322
            }
1323
        }
1324
1325
        /* add block var */
1326
        internal void addBlockVariable(Block seqList, IToken varname, UlyssesType aType)
1327
        {
1328
            if (aType == null)
1329
            {
1330
                doError(varname, String.Format("{0} lacks type!", varname.Text));
1331
            }
1332
            try
1333
            {
1334
                seqList.AddIdentifier(new LocalVariableIdentifier(varname, aType, GetScope()));
1335
            }
1336
            catch (ArgumentException)
1337
            {
1338
                doError(varname, String.Format("{0} redefined!", varname.Text));
1339
            }
1340
        }
1341
1342
1343
        internal QualitativeConstraintStatement createTwoVarConstraintStatement(IToken id1, IToken id2, QualitativeConstraintOperation op)
1344
        {
1345
            Identifier var1 = pState.Lookup(id1);
1346
            if (var1 == null)
1347
            {
1348
                var1 = new ExpressionVariableIdentifier(id1.Text, id1.Line, id1.CharPositionInLine);
1349
                var1.SetType(new AnyType((ExpressionVariableIdentifier)var1));
1350
1351
                GetScope().AddIdentifier(var1, null);
1352
1353
                doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id1.Text));
1354
            }
1355
1356
            Identifier var2 = pState.Lookup(id2);
1357
            if (var2 == null)
1358
            {
1359
                var2 = new ExpressionVariableIdentifier(id2.Text, id2.Line, id2.CharPositionInLine);
1360
                var2.SetType(new AnyType((ExpressionVariableIdentifier)var2));
1361
1362
                GetScope().AddIdentifier(var2, null);
1363
1364
                doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id2.Text));
1365
            }
1366
1367
            QualitativeConstraintStatement result = new QualitativeConstraintStatement(var1, var2, op, id1.Line, id1.CharPositionInLine);
1368
            return result;
1369
        }
1370
1371
1372
        internal QualitativeConstraintStatement createQualEqualConstraintStatement(IToken id1, IToken id2)
1373
        {
1374
            return createTwoVarConstraintStatement(id1, id2, QualitativeConstraintOperation.Equal);
1375
        }
1376
1377
        internal QualitativeConstraintStatement createQualArithConstraintStatement(IToken id1, IToken id2, IToken id3, IToken op)
1378
        {
1379
            Identifier var1 = pState.Lookup(id1);
1380
            if (var1 == null)
1381
            {
1382
                var1 = new ExpressionVariableIdentifier(id1.Text, id1.Line, id1.CharPositionInLine);
1383
                var1.SetType(new AnyType((ExpressionVariableIdentifier)var1));
1384
1385
                GetScope().AddIdentifier(var1, null);
1386
1387
                doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id1.Text));
1388
            }
1389
1390
            Identifier var2 = pState.Lookup(id2);
1391
            if (var2 == null)
1392
            {
1393
                var2 = new ExpressionVariableIdentifier(id2.Text, id2.Line, id2.CharPositionInLine);
1394
                var2.SetType(new AnyType((ExpressionVariableIdentifier)var2));
1395
1396
                GetScope().AddIdentifier(var2, null);
1397
1398
                doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id2.Text));
1399
            }
1400
1401
            Identifier var3 = pState.Lookup(id3);
1402
            if (var3 == null)
1403
            {
1404
                var3 = new ExpressionVariableIdentifier(id3.Text, id3.Line, id3.CharPositionInLine);
1405
                var3.SetType(new AnyType((ExpressionVariableIdentifier)var3));
1406
1407
                GetScope().AddIdentifier(var3, null);
1408
1409
                doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id3.Text));
1410
            }
1411
            QualitativeConstraintOperation operation;
1412
            switch (op.Type)
1413
            {
1414
                case ooaParser.T_SUM:
1415
                    operation = QualitativeConstraintOperation.Sum;
1416
                    break;
1417
                case ooaParser.T_DIFF:
1418
                    operation = QualitativeConstraintOperation.Diff;
1419
                    break;
1420
                case ooaParser.T_PROD:
1421
                    operation = QualitativeConstraintOperation.Prod;
1422
                    break;
1423
                default:
1424
                    doError(op, String.Format("'{0}' unknown operation", op.Text));
1425
                    return null;
1426
            }
1427
1428
            QualitativeConstraintStatement result = new QualitativeConstraintStatement(var1, var2, var3, operation, id1.Line, id1.CharPositionInLine);
1429
            return result;
1430
        }
1431
1432
        internal QualitativeConstraintStatement createQualDerivConstraintStatement(IToken id1, IToken derivid)
1433
        {
1434
            return createTwoVarConstraintStatement(id1, derivid, QualitativeConstraintOperation.Deriv);
1435
        }
1436
1437
1438
1439
        /* creates a general binary operator without any children */
1440
        internal BinaryOperator createBinaryOperator(ExpressionKind akind)
1441
        {
1442
            IToken token = input.LT(-1);
1443
            return new BinaryOperator(akind, null, null, token.Line, token.CharPositionInLine);
1444
        }
1445
1446
1447
        /* creates a general unary operator without child */
1448
        internal UnaryOperator createUnaryOperator(ExpressionKind unaryOperatorType)
1449
        {
1450
            IToken token = input.LT(-1);
1451
            return new UnaryOperator(unaryOperatorType, null, token.Line, token.CharPositionInLine);
1452
        }
1453
1454
        /* create a conditional expression */
1455
        internal Expression createConditionalExpression(Expression ce, Expression te, Expression ee, IToken ef)
1456
        {
1457
            return new TernaryOperator(ExpressionKind.conditional, ce, te, ee, ef.Line, ef.CharPositionInLine, GetScope());
1458
        }
1459
1460
        /* create a quantifier expression */
1461
        internal Quantifier createQuantifierExpression(IToken t)
1462
        {
1463
            Quantifier result = null;
1464
            if (t.Type == T_FORALL)
1465
                result = new ForallQuantifier(null, t.Line, t.CharPositionInLine);
1466
            else
1467
                result = new ExistsQuantifier(null, t.Line, t.CharPositionInLine);
1468
1469
1470
            pState.PushResolveStack(result);
1471
            return result;
1472
        }
1473
1474
        /* add a bound variable to the quantifier */
1475
        internal void addBoundVarToQuantifierExpression(Quantifier result, IToken id, UlyssesType id_type)
1476
        {
1477
            /*note: this might be a bit harsh, but for now it's easier to demand uniquely named vars,
1478
                    without any hiding. Could be fixed in searching only the first resolve level for
1479
                    dupes..
1480
             */
1481
            Identifier sym = pState.Lookup(id);
1482
            if (sym != null)
1483
                doError(id, String.Format("{0} already defined!", id.Text));
1484
            else
1485
            {
1486
                if (id_type == null)
1487
                    doError(id, String.Format("{0} lacks type (null).", id.Text));
1488
                Identifier newvar = new ExpressionVariableIdentifier(id, id_type, GetScope());
1489
                result.AddIdentifier(newvar, null);
1490
            }
1491
        }
1492
1493
        /* add the expression to the quantifier */
1494
        internal void addExpressionToQuantifier(Quantifier result, Expression e)
1495
        {
1496
            result.SetChild(e);
1497
        }
1498
1499
        /* remove local variables from resolve stack */
1500
        internal void removeBoundVarsFromResolveStack(Quantifier result)
1501
        {
1502
            if (result != null)
1503
                pState.PopResolveStack();
1504
        }
1505
1506
1507
        /* create a bool constant */
1508
        internal LeafExpression createBoolConstant(bool p)
1509
        {
1510
            IToken token = input.LT(-1);
1511
            return new ValueExpression<bool>(p, token.Line, token.CharPositionInLine);
1512
        }
1513
1514
        /* create a nil */
1515
        internal LeafExpression createNullPointerConstant()
1516
        {
1517
            IToken token = input.LT(-1);
1518
            return new ValueExpression<object>(null, token.Line, token.CharPositionInLine);
1519
        }
1520
1521
        /* create a 'self' identifier */
1522
        internal LeafExpression createSelfPointer()
1523
        {
1524
            IToken token = input.LT(-1);
1525
            Identifier self = pState.Lookup("self");
1526
            if (self == null)
1527
            {
1528
                doError(token, "Could not resolve 'self'");
1529
                return new UnresolvedIdentifierExpression(token, GetScope());
1530
            }
1531
1532
            IdentifierExpression result = new IdentifierExpression(self, token.Line, token.CharPositionInLine);
1533
            result.setIsSelf(true);
1534
1535
            return result;
1536
        }
1537
1538
        /* create a float const */
1539
        internal LeafExpression createFloatConstant(IToken t_fl)
1540
        {
1541
            return new ValueExpression<double>(double.Parse(t_fl.Text, System.Globalization.CultureInfo.InvariantCulture), t_fl.Line, t_fl.CharPositionInLine);
1542
        }
1543
1544
        /* create int const */
1545
        internal LeafExpression createIntConstant(IToken t_in)
1546
        {
1547
            return new ValueExpression<int>(int.Parse(t_in.Text), t_in.Line, t_in.CharPositionInLine);
1548
        }
1549
1550
        /* set children of binary operator*/
1551
        internal Expression addBinaryExpression(BinaryOperator binexpr, Expression expr, Expression e2)
1552
        {
1553
            binexpr.SetLeftChild(expr);
1554
            binexpr.SetRightChild(e2);
1555
            return binexpr;
1556
        }
1557
1558
        /* set child of unary expr */
1559
        internal Expression addUnaryExpression(UnaryOperator unexpr, Expression e)
1560
        {
1561
            if (unexpr != null)
1562
            {
1563
                unexpr.SetChild(e);
1564
                return unexpr;
1565
            }
1566
            else
1567
                return e;
1568
        }
1569
1570
1571
1572
        /* create a list */
1573
        internal ListConstructor createInitializedList()
1574
        {
1575
            IToken nexttoken = input.LT(1);
1576
            return new ListConstructor(nexttoken.Line, nexttoken.CharPositionInLine);
1577
        }
1578
1579
        /* add an element to the list */
1580
        internal void addListElement(ListConstructor result, Expression e)
1581
        {
1582
            result.AddElement(e);
1583
        }
1584
1585
        /* push list comprehension vars on resolve stack */
1586
        internal void pushListVarsOnResolveStack(ListConstructor result)
1587
        {
1588
            pState.PushResolveStack(result);
1589
        }
1590
1591
        /* pop list comprehension vars from resolve stack */
1592
        internal void popListVarsFromResolveStack(ListConstructor result)
1593
        {
1594
            if (result != null)
1595
                pState.PopResolveStack();
1596
        }
1597
1598
        /* set list comprehension expression */
1599
        internal void addListComprExpr(ListConstructor result, Expression e)
1600
        {
1601
            result.SetComprehension(e);
1602
        }
1603
1604
        /* add list comprehension variable */
1605
        internal void addListComprVar(ListConstructor result, IToken id, UlyssesType t1)
1606
        {
1607
            Identifier sym = pState.Lookup(id);
1608
            if (sym != null)
1609
            {
1610
                /* see notes in quantifier*/
1611
                doError(id, String.Format("{0} already defined.", id.Text));
1612
            }
1613
            else
1614
            {
1615
                ExpressionVariableIdentifier newvar = new ExpressionVariableIdentifier(id, t1, GetScope());
1616
                result.AddIdentifier(newvar, null);
1617
            }
1618
        }
1619
1620
        /* converts a string into a list of char */
1621
        internal ListConstructor createStringConstant(IToken t_l)
1622
        {
1623
            ListConstructor result = new ListConstructor(t_l.Line, t_l.CharPositionInLine);
1624
            foreach (char c in t_l.Text.Substring(1, t_l.Text.Length - 2))
1625
                result.AddElement(new ValueExpression<char>(c, t_l.Line, t_l.CharPositionInLine));
1626
            return result;
1627
        }
1628
1629
        /* creates an empty map */
1630
        internal Expression createEmptyMap()
1631
        {
1632
            IToken token = input.LT(-1);
1633
            return new MapConstructor(token.Line, token.CharPositionInLine);
1634
        }
1635
1636
        /* create a map and populate it with two items.. */
1637
        internal Expression createMap(Expression e1, Expression e2, IToken am)
1638
        {
1639
            MapConstructor result = new MapConstructor(am.Line, am.CharPositionInLine);
1640
            result.AddItem(e1, e2);
1641
            return result;
1642
        }
1643
1644
        /* add a key/value pair to a map */
1645
        internal void addToMap(Expression map, Expression e3, Expression e4)
1646
        {
1647
            ((MapConstructor)map).AddItem(e3, e4);
1648
        }
1649
1650
        /* create a set */
1651
        internal SetConstructor createSet()
1652
        {
1653
            IToken nexttoken = input.LT(1);
1654
            SetConstructor result = new SetConstructor(nexttoken.Line, nexttoken.CharPositionInLine);
1655
            return result;
1656
        }
1657
1658
        /* add item to set */
1659
        internal void addToSet(Expression result, Expression e2)
1660
        {
1661
            ((SetConstructor)result).AddItem(e2);
1662
        }
1663
1664
        /* remove set comprehension variables from resolution stack */
1665
        internal void popSetVarsFromResolveStack(SetConstructor _set)
1666
        {
1667
            if (_set != null)
1668
                pState.PopResolveStack();
1669
        }
1670
1671
        /* add set comprehension variables to resolution stack */
1672
        internal void pushSetVarsOnResolveStack(SetConstructor _set)
1673
        {
1674
            pState.PushResolveStack(_set);
1675
        }
1676
1677
        /* set comprehension expression fro set */
1678
        internal void addSetComprExpr(SetConstructor _set, Expression epx)
1679
        {
1680
            _set.SetComprehension(epx);
1681
        }
1682
1683
        /* add local set compr. variable */
1684
        internal void addSetComprVar(SetConstructor _set, IToken id1, UlyssesType t1)
1685
        {
1686
            Identifier sym = pState.Lookup(id1);
1687
            if (sym != null)
1688
                doError(id1, String.Format("{0} already defined!", id1.Text));
1689
            else
1690
            {
1691
                ExpressionVariableIdentifier newvar = new ExpressionVariableIdentifier(id1, t1, GetScope());
1692
                _set.AddIdentifier(newvar, null);
1693
            }
1694
        }
1695
1696
        /* check whether identifier p is a tuple type */
1697
        internal bool isTuple(string p)
1698
        {
1699
            Identifier sym = pState.Lookup(p);
1700
            return (sym != null)
1701
                && (sym.kind == IdentifierKind.TypeIdentifier)
1702
                && (sym.type.kind == TypeKind.TupleType);
1703
        }
1704
1705
        /* create an initialized tuple */
1706
        internal Expression createInitializedTuple(IToken aName, System.Collections.Generic.List<Expression> m_params)
1707
        {
1708
            Identifier sym = pState.Lookup(aName);
1709
            if ((sym == null) || !(sym.type is TupleType))
1710
            {
1711
                doError(aName, "Not a tuple type!");
1712
                return null;
1713
            }
1714
1715
            TupleType atuple = (TupleType)sym.type;
1716
            if (atuple.innerTypes.Count != m_params.Count)
1717
            {
1718
                doError(aName, "Number of parameters does not match type definition!");
1719
                return null;
1720
            }
1721
1722
            return new TupleConstructor(sym, m_params, aName.Line, aName.CharPositionInLine);
1723
        }
1724
1725
1726
        /* create an reference expression: (<expression>).xyz */
1727
        internal Expression createExpressionReference(Expression e, Expression aref, IToken atoken)
1728
        {
1729
            AccessExpression result = new AccessExpression(e, aref, atoken.Line, atoken.CharPositionInLine);
1730
            return result;
1731
        }
1732
1733
1734
        /* gets called when we are parsing attributes */
1735
        internal void BeginParsingAttributes()
1736
        {
1737
            pState.parsingAttributes = true;
1738
        }
1739
1740
        /* gets called when we stop parsing attributes */
1741
        internal void EndParsingAttributes()
1742
        {
1743
            pState.parsingAttributes = false;
1744
        }
1745
1746
        /*dummy*/
1747
        internal bool notIsAttributeInitialization()
1748
        {
1749
            return !pState.parsingAttributes;
1750
        }
1751
1752
        /* create a new(anid) constructor */
1753
        private Expression createObject(IToken anid)
1754
        {
1755
            if (!pState.parsingAttributes)
1756
            {
1757
                doError(anid, "Object creation with 'new' only allowed in variable initializers.");
1758
                return null;
1759
            }
1760
1761
1762
            OpaqueType atype = new OpaqueType(new TypeIdentifier(anid, null, GetScope()));
1763
            pState.typesToFixUp.Add(atype);
1764
            return new ObjectConstructor(atype, anid.Line, anid.CharPositionInLine);
1765
        }
1766
1767
1768
        private Expression createNamedObject(IToken anid, IToken aname)
1769
        {
1770
            if (!pState.parsingAttributes)
1771
            {
1772
                doError(anid, "Object creation with 'new' only allowed in variable initializers.");
1773
                return null;
1774
            }
1775
1776
            Regex validid = new Regex("\"[_]*[a-zA-Z][a-zA-Z0-9_]*\"");
1777
            if (!validid.IsMatch(aname.Text))
1778
            {
1779
                doError(aname, "Not a valid identifier");
1780
                return null;
1781
            }
1782
1783
            OpaqueType atype = new OpaqueType(new TypeIdentifier(anid, null, GetScope()));
1784
            pState.typesToFixUp.Add(atype);
1785
            return new ObjectConstructor(atype, aname.Text, anid.Line, anid.CharPositionInLine);
1786
        }
1787
1788
1789
        internal void setQualitativeDerivDec(QValConstructor result)
1790
        {
1791
            result.SetDerivation(QValDeriv.Dec);
1792
        }
1793
1794
        internal void setQualitativeDerivInc(QValConstructor result)
1795
        {
1796
            result.SetDerivation(QValDeriv.Inc);
1797
        }
1798
1799
        internal void setQualitativeDerivSteady(QValConstructor result)
1800
        {
1801
            result.SetDerivation(QValDeriv.Steady);
1802
        }
1803
1804
        internal void setQualitativeDerivDontCare(QValConstructor result)
1805
        {
1806
            result.SetDerivation(QValDeriv.DonTCare);
1807
        }
1808
1809
        internal void setQualitativeValueRangeInfinity(QValConstructor result, bool p)
1810
        {
1811
            throw new NotImplementedException();
1812
        }
1813
1814
        internal void setQualitativeValueRange(QValConstructor result, Expression expr2)
1815
        {
1816
            result.AddRange(expr2);
1817
        }
1818
1819
        internal void setQualitativeValueInfinity(QValConstructor result, bool minus)
1820
        {
1821
            throw new NotImplementedException();
1822
        }
1823
1824
        internal void setQualitativeValueLandmark(QValConstructor result, Expression expr)
1825
        {
1826
            result.SetValue(expr);
1827
        }
1828
1829
        internal void setQualitativeValueDontCare(QValConstructor result)
1830
        {
1831
            throw new NotImplementedException();
1832
        }
1833
1834
        internal QValConstructor createQualitativeValue(IToken aval)
1835
        {
1836
            return new QValConstructor(aval.Line, aval.CharPositionInLine);
1837
        }
1838
1839
        /* add a local variable to a named action */
1840
        internal void addLocalVariableToNamedAction(FunctionIdentifier newMethod, IToken id1, UlyssesType t1)
1841
        {
1842
            if (t1 == null)
1843
            {
1844
                doError(id1, "Variable lacks type");
1845
                return;
1846
            }
1847
1848
            LocalVariableIdentifier lvar = new LocalVariableIdentifier(id1, t1, GetScope());
1849
            newMethod.AddIdentifier(lvar, null);
1850
        }
1851
1852
        /* ====== */
1853
        /* ====== */
1854
1855
        public Dictionary<string, string> readableTokens = new Dictionary<string, string>();
1856
1857
1858
        private void SetUpTokenDictionary()
1859
        {
1860
            if (readableTokens.Count > 0)
1861
                return;
1862
            readableTokens.Add("<invalid>", "<invalid>");
1863
            readableTokens.Add("<EOR>", "<EOR>");
1864
            readableTokens.Add("<DOWN>", "<DOWN>");
1865
            readableTokens.Add("<UP>", "<UP>");
1866
            readableTokens.Add("T_TYPES", "'types'");
1867
            readableTokens.Add("T_SYSTEM", "'system'");
1868
            readableTokens.Add("T_SEMICOLON", "';'");
1869
            readableTokens.Add("T_IDENTIFIER", "<identifier>");
1870
            readableTokens.Add("T_EQUAL", "'='");
1871
            readableTokens.Add("T_PRIO", "'//'");
1872
            readableTokens.Add("T_NONDET", "'[]'");
1873
            readableTokens.Add("T_LPAREN", "'('");
1874
            readableTokens.Add("T_RPAREN", "')'");
1875
            readableTokens.Add("T_LIST", "'list'");
1876
            readableTokens.Add("T_LSQPAREN", "'['");
1877
            readableTokens.Add("T_INTNUMBER", "<integer>");
1878
            readableTokens.Add("T_RSQPAREN", "']'");
1879
            readableTokens.Add("T_OF", "'of'");
1880
            readableTokens.Add("T_COMMA", "','");
1881
            readableTokens.Add("T_MAP", "'map'");
1882
            readableTokens.Add("T_TO", "'to'");
1883
            readableTokens.Add("T_QUANTITY", "'quantity'");
1884
            readableTokens.Add("T_INFTY", "'inf'");
1885
            readableTokens.Add("T_BOOL", "'bool'");
1886
            readableTokens.Add("T_INT", "'int'");
1887
            readableTokens.Add("T_RANGETO", "'..'");
1888
            readableTokens.Add("T_FLOAT", "'float'");
1889
            readableTokens.Add("T_FLOATNUMBER", "<floating point number>");
1890
            readableTokens.Add("T_CHAR", "'char'");
1891
            readableTokens.Add("T_CBRL", "'{'");
1892
            readableTokens.Add("T_CBRR", "'}'");
1893
            readableTokens.Add("T_AUTOCONS", "'autocons'");
1894
            readableTokens.Add("T_VAR", "'var'");
1895
            readableTokens.Add("T_METHODS", "'methods'");
1896
            readableTokens.Add("T_ACTIONS", "'actions'");
1897
            readableTokens.Add("T_DO", "'do'");
1898
            readableTokens.Add("T_OD", "'od'");
1899
            readableTokens.Add("T_STATIC", "'static'");
1900
            readableTokens.Add("T_COLON", "':'");
1901
            readableTokens.Add("T_END", "'end'");
1902
            readableTokens.Add("T_CONT", "'cont'");
1903
            readableTokens.Add("T_CTRL", "'ctr'");
1904
            readableTokens.Add("T_OBS", "'obs'");
1905
            readableTokens.Add("T_REQUIRES", "'requires'");
1906
            readableTokens.Add("T_AND", "'and'");
1907
            readableTokens.Add("T_ABORT", "'abort'");
1908
            readableTokens.Add("T_SKIP", "'skip'");
1909
            readableTokens.Add("T_KILL", "'kill'");
1910
            readableTokens.Add("T_SELF", "'self'");
1911
            readableTokens.Add("T_ASSIGNMENT", "':='");
1912
            readableTokens.Add("T_WITH", "'with'");
1913
            readableTokens.Add("T_IF", "'if'");
1914
            readableTokens.Add("T_THEN", "'then'");
1915
            readableTokens.Add("T_ELSE", "'else'");
1916
            readableTokens.Add("T_FORALL", "'forall'");
1917
            readableTokens.Add("T_EXISTS", "'exists'");
1918
            readableTokens.Add("T_TRUE", "'true'");
1919
            readableTokens.Add("T_FALSE", "'false'");
1920
            readableTokens.Add("T_NIL", "'nil'");
1921
            readableTokens.Add("T_STRINGLITERAL", "'\"<string>\"'");
1922
            readableTokens.Add("T_NEW", "'new'");
1923
            readableTokens.Add("T_BAR", "'|'");
1924
            readableTokens.Add("T_MAPS", "'->'");
1925
            readableTokens.Add("T_PRIMED", "'''");
1926
            readableTokens.Add("T_POINT", "'.'");
1927
            readableTokens.Add("T_NOTEQUAL", "'<>'");
1928
            readableTokens.Add("T_SEQMOD_MAPOVERRIDE", "'++'");
1929
            readableTokens.Add("T_BIIMPLIES", "'<=>'");
1930
            readableTokens.Add("T_IMPLIES", "'=>'");
1931
            readableTokens.Add("T_OR", "'or'");
1932
            readableTokens.Add("T_ABS", "'abs'");
1933
            readableTokens.Add("T_DIV", "'/'");
1934
            readableTokens.Add("T_GREATER", "'>'");
1935
            readableTokens.Add("T_GREATEREQUAL", "'>='");
1936
            readableTokens.Add("T_IDIV", "'div'");
1937
            readableTokens.Add("T_LESS", "'<'");
1938
            readableTokens.Add("T_LESSEQUAL", "'<='");
1939
            readableTokens.Add("T_MINUS", "'-'");
1940
            readableTokens.Add("T_MOD", "'mod'");
1941
            readableTokens.Add("T_POW", "'**'");
1942
            readableTokens.Add("T_PROD", "'*'");
1943
            readableTokens.Add("T_SUM", "'+'");
1944
            readableTokens.Add("T_CONC", "'^'");
1945
            readableTokens.Add("T_DIFF", "'\\'");
1946
            readableTokens.Add("T_INTER", "'inter'");
1947
            readableTokens.Add("T_IN", "'in'");
1948
            readableTokens.Add("T_SET", "'set'");
1949
            readableTokens.Add("T_NOT", "'not'");
1950
            readableTokens.Add("T_SUBSET", "'subset'");
1951
            readableTokens.Add("T_UNION", "'union'");
1952
            readableTokens.Add("T_DOMRESBY", "'<-:'");
1953
            readableTokens.Add("T_DOMRESTO", "'<:'");
1954
            readableTokens.Add("T_RNGRESBY", "':->'");
1955
            readableTokens.Add("T_RNGRESTO", "':>'");
1956
            readableTokens.Add("T_MUNION", "'munion'");
1957
            readableTokens.Add("T_CARD", "'card'");
1958
            readableTokens.Add("T_DCONC", "'conc'");
1959
            readableTokens.Add("T_DINTER", "'dinter'");
1960
            readableTokens.Add("T_DUNION", "'dunion'");
1961
            readableTokens.Add("T_ELEMS", "'elems'");
1962
            readableTokens.Add("T_HEAD", "'hd'");
1963
            readableTokens.Add("T_INDS", "'inds'");
1964
            readableTokens.Add("T_LEN", "'len'");
1965
            readableTokens.Add("T_TAIL", "'tl'");
1966
            readableTokens.Add("T_DOM", "'dom'");
1967
            readableTokens.Add("T_RNG", "'rng'");
1968
            readableTokens.Add("T_MERGE", "'merge'");
1969
            readableTokens.Add("T_WS", "<space>");
1970
            readableTokens.Add("T_COMMENT", "'/*<comment>*/'");
1971
            readableTokens.Add("LINE_COMMENT", "'#<line comment>'");
1972
            readableTokens.Add("T_DIGIT", "<0..9>");
1973
            readableTokens.Add("FLOAT_OR_INT_OR_RANGE", "<float_int_range>");
1974
            readableTokens.Add("T_LETTER", "<a..z,A..Z>");
1975
            readableTokens.Add("'|['", "'|['");
1976
            readableTokens.Add("']|'", "']|'");
1977
            readableTokens.Add("'add'", "'add'");
1978
            readableTokens.Add("'mult'", "'mult'");
1979
            readableTokens.Add("'deriv'", "'deriv'");
1980
            readableTokens.Add("'mon+'", "'mon+'");
1981
            readableTokens.Add("'mon-'", "'mon-'");
1982
            readableTokens.Add("'id'", "'id'");
1983
            readableTokens.Add("'qval'", "'qval'");
1984
            readableTokens.Add("'\"'", "'\"'");
1985
            readableTokens.Add("as", "as");
1986
        }
1987
1988
        /* override routine that displays recongition errors.. */
1989
        public override void DisplayRecognitionError(String[] tokenNames, RecognitionException e)
1990
        {
1991
            int i;
1992
            System.Text.StringBuilder result = new System.Text.StringBuilder();
1993
            SetUpTokenDictionary();
1994
1995
1996
            if (e is MismatchedTokenException)
1997
            {
1998
                result.Append("Found '");
1999
                result.Append(e.Token.Text);
2000
                result.Append("'");
2001
                i = ((MismatchedTokenException)e).Expecting;
2002
                result.Append(" Expected: ");
2003
                result.Append(readableTokens[tokenNames[i]]);
2004
                result.Append(" ("); result.Append(tokenNames[i]); result.Append(") ");
2005
2006
            }
2007
            else
2008
            {
2009
                /*if (e is NoViableAltException)
2010
                {
2011
                    result.Append("Unexpected '");
2012
                    result.Append(e.Token.Text);
2013
                    result.Append("' (");
2014
                    i = ((NoViableAltException)e).UnexpectedType;
2015
                    result.Append(tokenNames[i]);
2016
                    result.Append(")");
2017
                }
2018
                else*/
2019
                if (e is RecognitionException)
2020
                {
2021
                    result.Append("Unexpected '");
2022
                    result.Append(e.Token.Text);
2023
                    result.Append("' (");
2024
                    i = ((RecognitionException)e).UnexpectedType;
2025
                    result.Append(tokenNames[i]);
2026
                    result.Append(") ");
2027
                }
2028
                else
2029
                    result.Append(e.Message);
2030
            }
2031
2032
            pState.AddErrorMessage(new ParserError(pState.filename, e.Line, e.CharPositionInLine, result.ToString()));
2033
        }
2034
2035
2036
        /* just run over once */
2037
        public static int FirstPass(ParserState pState)
2038
        {
2039
            pState.parser.ooActionSystems();
2040
2041
            return pState.listOfParserErrors.Count; // + pState.lexer.NumberOfSyntaxErrors;
2042
        }
2043
2044
2045
2046
        /* print syntax tree */
2047
        public static string PrintSyntaxTree(ParserState pState)
2048
        {
2049
            if ((pState != null) && (pState.ooaSystem != null))
2050
            {
2051
                return pState.ooaSystem.ToString();
2052
            }
2053
            else
2054
                return String.Empty;
2055
        }
2056
    }
2057
}