Project

General

Profile

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

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

    
27

    
28
package org.momut.ooas.parser;
29

    
30
import java.util.LinkedHashMap;
31
import java.util.LinkedList;
32
import java.util.List;
33

    
34
import org.antlr.runtime.MismatchedTokenException;
35
import org.antlr.runtime.Parser;
36
import org.antlr.runtime.RecognitionException;
37
import org.antlr.runtime.RecognizerSharedState;
38
import org.antlr.runtime.Token;
39
import org.antlr.runtime.TokenStream;
40
import org.momut.ooas.ast.IScope;
41
import org.momut.ooas.ast.expressions.AccessExpression;
42
import org.momut.ooas.ast.expressions.BinaryOperator;
43
import org.momut.ooas.ast.expressions.CallExpression;
44
import org.momut.ooas.ast.expressions.ExistsQuantifier;
45
import org.momut.ooas.ast.expressions.Expression;
46
import org.momut.ooas.ast.expressions.ExpressionKind;
47
import org.momut.ooas.ast.expressions.ForallQuantifier;
48
import org.momut.ooas.ast.expressions.IdentifierExpression;
49
import org.momut.ooas.ast.expressions.LeafExpression;
50
import org.momut.ooas.ast.expressions.ListConstructor;
51
import org.momut.ooas.ast.expressions.MapConstructor;
52
import org.momut.ooas.ast.expressions.ObjectConstructor;
53
import org.momut.ooas.ast.expressions.QValConstructor;
54
import org.momut.ooas.ast.expressions.Quantifier;
55
import org.momut.ooas.ast.expressions.SetConstructor;
56
import org.momut.ooas.ast.expressions.TernaryOperator;
57
import org.momut.ooas.ast.expressions.TupleConstructor;
58
import org.momut.ooas.ast.expressions.TupleMapAccessExpression;
59
import org.momut.ooas.ast.expressions.UnaryOperator;
60
import org.momut.ooas.ast.expressions.UnresolvedIdentifierExpression;
61
import org.momut.ooas.ast.expressions.ValueExpression;
62
import org.momut.ooas.ast.expressions.QValConstructor.QValDeriv;
63
import org.momut.ooas.ast.identifiers.AttributeIdentifier;
64
import org.momut.ooas.ast.identifiers.ConstantIdentifier;
65
import org.momut.ooas.ast.identifiers.EnumIdentifier;
66
import org.momut.ooas.ast.identifiers.ExpressionVariableIdentifier;
67
import org.momut.ooas.ast.identifiers.FunctionIdentifier;
68
import org.momut.ooas.ast.identifiers.Identifier;
69
import org.momut.ooas.ast.identifiers.IdentifierKind;
70
import org.momut.ooas.ast.identifiers.IdentifierList;
71
import org.momut.ooas.ast.identifiers.LandmarkIdentifier;
72
import org.momut.ooas.ast.identifiers.LocalVariableIdentifier;
73
import org.momut.ooas.ast.identifiers.MainModule;
74
import org.momut.ooas.ast.identifiers.MethodIdentifier;
75
import org.momut.ooas.ast.identifiers.NamedActionIdentifier;
76
import org.momut.ooas.ast.identifiers.ParameterIdentifier;
77
import org.momut.ooas.ast.identifiers.SelfTypeIdentifier;
78
import org.momut.ooas.ast.identifiers.TypeIdentifier;
79
import org.momut.ooas.ast.statements.AbortStatement;
80
import org.momut.ooas.ast.statements.Assignment;
81
import org.momut.ooas.ast.statements.Block;
82
import org.momut.ooas.ast.statements.BreakStatement;
83
import org.momut.ooas.ast.statements.Call;
84
import org.momut.ooas.ast.statements.GuardedCommand;
85
import org.momut.ooas.ast.statements.KillStatement;
86
import org.momut.ooas.ast.statements.NondetBlock;
87
import org.momut.ooas.ast.statements.PrioBlock;
88
import org.momut.ooas.ast.statements.QualitativeConstraintStatement;
89
import org.momut.ooas.ast.statements.SeqBlock;
90
import org.momut.ooas.ast.statements.SkipStatement;
91
import org.momut.ooas.ast.statements.Statement;
92
import org.momut.ooas.ast.statements.QualitativeConstraintStatement.QualitativeConstraintOperation;
93
import org.momut.ooas.ast.types.AnyType;
94
import org.momut.ooas.ast.types.BoolType;
95
import org.momut.ooas.ast.types.CharType;
96
import org.momut.ooas.ast.types.EnumType;
97
import org.momut.ooas.ast.types.FloatType;
98
import org.momut.ooas.ast.types.FunctionType;
99
import org.momut.ooas.ast.types.IntType;
100
import org.momut.ooas.ast.types.ListType;
101
import org.momut.ooas.ast.types.MapType;
102
import org.momut.ooas.ast.types.OoActionSystemType;
103
import org.momut.ooas.ast.types.OpaqueType;
104
import org.momut.ooas.ast.types.QrType;
105
import org.momut.ooas.ast.types.TupleType;
106
import org.momut.ooas.ast.types.TypeKind;
107
import org.momut.ooas.ast.types.UlyssesType;
108
import org.momut.ooas.ast.types.ValuedEnumType;
109
import org.momut.ooas.ast.types.FunctionType.FunctionTypeEnum;
110
import org.momut.ooas.utils.exceptions.ArgumentException;
111
import org.momut.ooas.utils.exceptions.NotImplementedException;
112
import org.momut.ooas.visitors.OoaResolveExpressionsVisitor;
113

    
114
public class ooaCustomParser extends Parser
115
{
116
        public ParserState pState;
117

    
118

    
119
        public boolean IsRightToLeft(ExpressionKind type)
120
        {
121
                return type == ExpressionKind.implies; // implication has right grouping
122
        }
123

    
124
        public int GetOperatorPrecedence(ExpressionKind type)
125
        {
126
                switch (type)
127
                {
128
                /*Family of Evaluators*/
129

    
130
                case abs:    // T_ABS:
131
                case card:   // T_CARD:
132
                case dom:    // T_DOM:
133
                case range:  // T_RNG:
134
                case merge:  // T_MERGE:
135
                case len:    // T_LEN:
136
                case elems:  // T_ELEMS:
137
                case head:   // T_HEAD:
138
                case tail:   // T_TAIL:
139
                case conc:   // T_CONC:
140
                case inds:   // T_INDS:
141
                case dinter: // T_DINTER:
142
                case dunion: // T_DUNION:
143
                        return 1;
144

    
145
                case domresby:   // T_DOMRESBY:
146
                case domresto:   // T_DOMRESTO:
147
                case rngresby:   // T_RNGRESBY:
148
                case rngresto:   // T_RNGRESTO:
149
                        return 2;
150

    
151
                case div:    // T_DIV:
152
                case idiv:   // T_IDIV:
153
                case mod:    // T_MOD:
154
                case prod:   // T_PROD:
155
                case inter:  // T_INTER:
156
                        return 3;
157

    
158
                case sum:    // T_SUM:
159
                case minus:  // T_MINUS:
160
                case union:  // T_UNION:
161
                case diff:   // T_DIFF:
162
                case munion: // T_MUNION:
163
                case seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE:
164
                        return 4;
165

    
166
                        /*Family of Relations*/
167

    
168
                case less:
169
                case lessequal:
170
                case greater:
171
                case greaterequal:
172
                case equal:
173
                case notequal:
174
                case subset:
175
                case elemin:
176
                case notelemin:
177
                        return 5;
178

    
179
                        /*Family of Connectives*/
180

    
181
                case and:    // T_AND:
182
                        return 6;
183

    
184
                case or:     // T_OR:
185
                        return 7;
186

    
187
                case implies:    // T_IMPLIES:
188
                        return 8;
189

    
190
                case biimplies:  // T_BIIMPLIES:
191
                        return 9;
192

    
193
                default:
194
                        throw new NotImplementedException("operator not supported: " + type.toString());
195
                        // return 0;
196
                }
197
        }
198

    
199
        /*taken from antlr homepage:
200
     http://www.antlr.org/wiki/display/ANTLR3/Operator+precedence+parser
201
         */
202
        int findPivot(List<BinaryOperator> operators, int startIndex, int stopIndex)
203
        {
204
                int pivot = startIndex;
205
                final BinaryOperator binop = operators.get(pivot);
206
                int pivotRank = GetOperatorPrecedence(binop.kind());
207
                for (int i = startIndex + 1; i <= stopIndex; i++)
208
                {
209
                        final ExpressionKind type = operators.get(i).kind();
210
                        final int current = GetOperatorPrecedence(type);
211
                        final boolean rtl = IsRightToLeft(type);
212
                        if (current > pivotRank || (current == pivotRank && rtl))
213
                        {
214
                                pivot = i;
215
                                pivotRank = current;
216
                        }
217
                }
218
                return pivot;
219
        }
220

    
221
        Expression createPrecedenceTree(
222
                        List<Expression> expressions,
223
                        List<BinaryOperator> operators,
224
                        int startIndex,
225
                        int stopIndex)
226
        {
227
                if (stopIndex == startIndex)
228
                        return expressions.get(startIndex);
229

    
230
                final int pivot = findPivot(operators, startIndex, stopIndex - 1);
231

    
232
                final BinaryOperator result = operators.get(pivot);
233
                result.SetLeftChild(createPrecedenceTree(expressions, operators, startIndex, pivot));
234
                result.SetRightChild(createPrecedenceTree(expressions, operators, pivot + 1, stopIndex));
235
                return result;
236
        }
237

    
238
        Expression createPrecedenceTree(List<Expression> expressions, List<BinaryOperator> operators)
239
        {
240
                return createPrecedenceTree(expressions, operators, 0, expressions.size() - 1);
241
        }
242

    
243

    
244
        /* add error message to state. */
245
        private void doError(Token aToken, String aMessage)
246
        {
247
                pState.AddErrorMessage(
248
                                new ParserError(pState.filename, aToken, aMessage));
249
        }
250

    
251
        /* add warning message to state */
252
        private void doWarning(Token id1, String p)
253
        {
254
                pState.AddWarningMessage(new ParserWarning(pState.filename, id1, p));
255
        }
256

    
257
        private void doError(String aMessage)
258
        {
259
                pState.AddErrorMessage(
260
                                new ParserError(pState.filename, 0, 0, aMessage));
261
        }
262

    
263
        /* init global state */
264
         void initializeTopLevelParserState()
265
        {
266
                pState.ooaSystem = new MainModule();
267
                pState.PushResolveStack(pState.ooaSystem);
268
        }
269

    
270

    
271
        private IScope GetScope()
272
        {
273
                return pState.currentScope;
274
        }
275

    
276

    
277
        /*create a named constant*/
278
         void addNamedConst(Token aName, Expression anExpr)
279
        {
280
                if (pState.currentScope.ResolveIdentifier(aName.getText()) == null)
281
                {
282
                        /* needs to be a constant... */
283
                        final ConstantIdentifier aConst = new ConstantIdentifier(aName, anExpr, GetScope());
284

    
285
                        final OoaResolveExpressionsVisitor resolver = new OoaResolveExpressionsVisitor(pState);
286
                        aConst.Accept(resolver);
287

    
288
                        if (aConst.Value() == null || aConst.Value().type() == null || aConst.Value().kind() != ExpressionKind.Value)
289
                        {
290
                                doError(aName, String.format("%s not a constant!", aName.getText()));
291
                        }
292
                        else
293
                        {
294
                                aConst.SetType(aConst.Value().type());
295
                                pState.currentScope.AddIdentifier(aConst, null);
296
                        }
297
                }
298
                else
299
                        doError(aName, String.format("%s already defined!", aName.getText()));
300
        }
301

    
302

    
303

    
304
        /* create a named type; we're on top-level here */
305
         void createNamedType(Token aName, UlyssesType aType)
306
        {
307
                // precond..
308
                assert(aName != null);
309

    
310
                if (aType == null)
311
                {
312
                        doError(aName, String.format("%s lacks a type! (Type not added)", aName.getText()));
313
                        return;
314
                }
315

    
316

    
317
                if (pState.currentScope.ResolveIdentifier(aName.getText()) == null)
318
                {
319
                        final TypeIdentifier newid = new TypeIdentifier(aName, aType, GetScope());
320
                        aType.SetTypeIdentifier(newid);
321
                        pState.currentScope.AddIdentifier(newid, null);
322
                }
323
                else
324
                        doError(aName, String.format("%s already defined!", aName.getText()));
325

    
326
        }
327

    
328
        /* create basic structure for an ooa-system descr. resolve stack TOS is now ooa-system symbols */
329
        OoActionSystemType createOoaType(Token refinesSystemName, boolean autoCons)
330
        {
331
                final Identifier refinedSystem = pState.Lookup(refinesSystemName);
332
                OoActionSystemType refinedSystemType = null;
333
                if ((refinedSystem != null) && (refinedSystem.type() != null))
334
                {
335
                        if (refinedSystem.type().kind() != TypeKind.OoActionSystemType)
336
                                doError(refinesSystemName,
337
                                                String.format("%s not an object oriented action system", refinesSystemName.getText()));
338
                        else
339
                                refinedSystemType = (OoActionSystemType)refinedSystem.type();
340
                }
341
                else if (refinesSystemName != null)
342
                {
343
                        pState.AddErrorMessage(
344
                                        new ParserError(pState.filename, refinesSystemName,
345
                                                        String.format("Type that's being refined (%s) not found!", refinesSystemName.getText())));
346
                }
347

    
348
                final OoActionSystemType result = new OoActionSystemType(autoCons, refinedSystemType, null);
349

    
350
                // add 'self' to the symbols.. (self is a keyword, so it can't be defined)
351
                result.AddIdentifier(new SelfTypeIdentifier("self", result, GetScope()), null);
352

    
353
                pState.PushResolveStack(result);
354
                return result;
355
        }
356

    
357
        /* remove ooa-system symbols from resolve stack TOS */
358
        void fixupOoaType(OoActionSystemType aTypeSymbol)
359
        {
360
                if (aTypeSymbol == null)
361
                        return;
362

    
363
                aTypeSymbol.SetupAnonymousName();
364
                if (aTypeSymbol != null)
365
                        pState.PopResolveStack();
366
        }
367

    
368
        Expression addCastExpression(Expression e, Token cid)
369
        {
370
                assert(e != null);
371

    
372
                final Expression result = new UnaryOperator(ExpressionKind.Cast, e, cid.getLine(), cid.getCharPositionInLine());
373
                result.SetType(new OpaqueType(new TypeIdentifier(cid, null, GetScope())));
374
                pState.typesToFixUp.add((OpaqueType)result.type());
375
                return result;
376
        }
377

    
378

    
379
        /* add a new ooa to the list describing the composition of action systems */
380
         void addToIdentifierList(IdentifierList top, Token aName)
381
        {
382
                assert(top != null);
383

    
384
                final Identifier aSym = pState.Lookup(aName);
385
                if (aSym == null)
386
                {
387
                        doError(aName, String.format("Could not find ooa-system %s!", aName.getText()));
388
                }
389
                else if ((aSym.type() == null) || !(aSym.type().kind() == TypeKind.OoActionSystemType))
390
                {
391
                        doError(aName, String.format("Referenced type (%s) does not have correct type!", aName.getText()));
392
                }
393
                else
394
                {
395
                        final OoActionSystemType aType = (OoActionSystemType)aSym.type();
396
                        if (aType.isInSystemDescription())
397
                                doError(aName, String.format("Referenced type (%s) already used in composition!", aName.getText()));
398
                        else
399
                                aType.SetIsInSystemDescription(true);
400
                        top.AddElement(aSym);
401
                }
402
        }
403

    
404
        /* does a fixup run after parsing */
405
         void fixUpRun(IdentifierList sysDescr)
406
        {
407
                // set system descr.
408
                pState.ooaSystem.SetSystemDescription(sysDescr);
409

    
410
                // fixup named types
411
                FixupNamedTypes();
412
        }
413

    
414
        private void FixupNamedTypes()
415
        {
416
                /*named type refs that could not be resolved in the first run, have to
417
          be resolved now. */
418
                for (final OpaqueType ntype: pState.typesToFixUp)
419
                {
420
                        if (ntype.resolvedType() == null)
421
                        {
422
                                //ntype.identifier
423
                                final Identifier asym = pState.Lookup(ntype.identifier().tokenText(), ntype.identifier().definingScope());
424
                                if ((asym == null) || (asym.kind() != IdentifierKind.TypeIdentifier))
425
                                {
426
                                        final ParserError error = new ParserError(pState.filename, ntype.identifier().line(), ntype.identifier().column(),
427
                                                        String.format("Can not resolve %s to a named type", ntype.identifier().tokenText()));
428
                                        pState.AddErrorMessage(error);
429
                                }
430
                                else
431
                                        ntype.SetResolvedType(asym.type());
432
                        }
433
                }
434
                pState.typesToFixUp.clear();
435
        }
436

    
437

    
438
        private boolean TosIsActionSystem()
439
        {
440
                return pState.currentScope instanceof OoActionSystemType;
441
        }
442

    
443

    
444
        private int currentLine()
445
        {
446
                final Token token = input.LT(-1);
447
                return token == null ? 0 : token.getLine();
448
        }
449

    
450
        private int currentPos()
451
        {
452
                final Token token = input.LT(-1);
453
                return token == null ? 0 : token.getCharPositionInLine();
454
        }
455

    
456
        /* add var symbol to the current action system */
457
        void createAttribute(Token varname, boolean isStatic, boolean isObs, boolean isCtr, UlyssesType aType, Expression anExpr)
458
        {
459
                if (!TosIsActionSystem())
460
                        return;
461

    
462
                if (aType == null)
463
                {
464
                        doError(varname, String.format("%s lacks type!", varname.getText()));
465
                }
466
                if (anExpr == null)
467
                {
468
                        doError(varname, String.format("%s lacks initializer!", varname.getText()));
469
                }
470
                if (isObs == true || isCtr == true)
471
                        if (aType.kind() != TypeKind.QrType)
472
                                doError(varname, "'obs' or 'ctr' on attributes only allowed for qualitative types");
473

    
474

    
475
                final AttributeIdentifier var = new AttributeIdentifier(varname, aType, GetScope(), anExpr, isStatic, isObs, isCtr);
476
                if (pState.currentScope.ResolveIdentifier(varname.getText()) == null)
477
                        pState.currentScope.AddIdentifier(var, null);
478
                else
479
                        doError(varname, String.format("Can not add %s: Symbol already defined!", varname.getText()));
480
        }
481

    
482

    
483
        /* create a boolean type */
484
        BoolType createBoolType()
485
        {
486
                return new BoolType(null);
487
        }
488

    
489
        /* create a char type */
490
        CharType createCharType()
491
        {
492
                return new CharType(null);
493
        }
494

    
495
        /* create an int type */
496
        @SuppressWarnings("unchecked")
497
        UlyssesType createIntType(Token rangeLow, Token rangeHigh)
498
        {
499
                int low = 0;
500
                int high = 0;
501

    
502
                if (rangeLow.getType() == ooaLexer.T_INFTY)
503
                        doError(rangeLow, "Infinity not supported.");
504
                if (rangeLow.getType() == ooaLexer.T_INFTY)
505
                        doError(rangeHigh, "Infinity not supported.");
506

    
507
                if (rangeLow.getType() == ooaLexer.T_IDENTIFIER)
508
                {
509
                        // see whether we can find the constant
510
                        final Identifier aconst = pState.currentScope.ResolveIdentifier(rangeLow.getText());
511
                        if (aconst == null || aconst.kind() != IdentifierKind.Constant)
512
                                doError(rangeLow, String.format("Constant %s not found", rangeLow.getText()));
513
                        else if (aconst.type().kind() != TypeKind.IntType)
514
                                doError(rangeLow, "Constant must be integer");
515
                        else
516
                                low = ((ValueExpression<Integer>)((ConstantIdentifier)aconst).Value()).value();
517
                }
518
                else
519
                        try {
520
                                low = Integer.parseInt(rangeLow.getText());
521
                        } catch (final NumberFormatException e) {
522
                                doError(rangeLow, "Can not convert to integer");
523
                        }
524

    
525
                if (rangeHigh.getType() == ooaLexer.T_IDENTIFIER)
526
                {
527
                        // see whether we can find the constant
528
                        final Identifier aconst = pState.currentScope.ResolveIdentifier(rangeHigh.getText());
529
                        if (aconst == null || aconst.kind() != IdentifierKind.Constant)
530
                                doError(rangeHigh, String.format("Constant %s not found", rangeHigh.getText()));
531
                        else if (aconst.type().kind() != TypeKind.IntType)
532
                                doError(rangeHigh, "Constant must be integer");
533
                        else
534
                                high = ((ValueExpression<Integer>)((ConstantIdentifier)aconst).Value()).value();
535
                }
536
                else
537
                        try {
538
                                high = Integer.parseInt(rangeHigh.getText());
539
                        } catch (final NumberFormatException e) {
540
                                doError(rangeLow, "Can not convert to integer");
541
                        }
542

    
543
                if (high < low)
544
                        doError(rangeHigh, "Lower bound greater than upper bound");
545

    
546
                return new IntType(low, high, null);
547
        }
548

    
549
        /* create a float type */
550
         @SuppressWarnings("unchecked")
551
        UlyssesType createFloatType(Token rangeLow, Token rangeHigh)
552
        {
553
                float low = 0;
554
                float high = 0;
555

    
556
                if (rangeLow.getType() == ooaLexer.T_INFTY)
557
                        doError(rangeLow, "Infinity not supported.");
558
                if (rangeLow.getType() == ooaLexer.T_INFTY)
559
                        doError(rangeHigh, "Infinity not supported.");
560

    
561
                if (rangeLow.getType() == ooaLexer.T_IDENTIFIER)
562
                {
563
                        // see whether we can find the constant
564
                        final Identifier aconst = pState.currentScope.ResolveIdentifier(rangeLow.getText());
565
                        if (aconst == null || aconst.kind() != IdentifierKind.Constant)
566
                                doError(rangeLow, String.format("Constant %s not found", rangeLow.getText()));
567
                        else if (aconst.type().kind() != TypeKind.FloatType)
568
                                doError(rangeLow, "Constant must be float");
569
                        else
570
                                low = ((ValueExpression<Integer>)((ConstantIdentifier)aconst).Value()).value();
571
                }
572
                else
573
                        try {
574
                                low = Float.parseFloat(rangeLow.getText());
575
                        } catch (final NumberFormatException e) {
576
                                doError(rangeLow, "Can not convert to float (single)");
577
                        }
578

    
579
                if (rangeHigh.getType() == ooaLexer.T_IDENTIFIER)
580
                {
581
                        // see whether we can find the constant
582
                        final Identifier aconst = pState.currentScope.ResolveIdentifier(rangeHigh.getText());
583
                        if (aconst == null || aconst.kind() != IdentifierKind.Constant)
584
                                doError(rangeHigh, String.format("Constant %s not found", rangeHigh.getText()));
585
                        else if (aconst.type().kind() != TypeKind.FloatType)
586
                                doError(rangeHigh, "Constant must be integer");
587
                        else
588
                                high = ((ValueExpression<Integer>)((ConstantIdentifier)aconst).Value()).value();
589
                }
590
                else
591
                        try {
592
                                high = Float.parseFloat(rangeHigh.getText());
593
                        } catch (final NumberFormatException e){
594
                                doError(rangeHigh, "Can not convert to float (single)");
595
                        }
596

    
597
                if (high < low)
598
                        doError(rangeHigh, "Lower bound greater than upper bound");
599

    
600
                /* precision */
601
                final float afterc_low = low -  (float)Math.floor(low); //(float)Convert.ToInt32(low);
602
                final float afterc_high = high - (float)Math.floor(high); //(float)Convert.ToInt32(high);
603
                final float precision = afterc_low < afterc_high ? afterc_low : afterc_high;
604

    
605
                return new FloatType(low, high, precision, null);
606
        }
607

    
608
        /* create a list of an enumerated type */
609
         UlyssesType createListEnumType(Token alistelem)
610
        {
611
                final EnumType hiddenEnumType = new EnumType(null);
612

    
613
                final ListType result = new ListType(hiddenEnumType, 500, null);
614
                addToListEnumType(result, alistelem);
615
                return result;
616
        }
617

    
618
        /* add a new enum symbol to a list with an anonymous enumerated type */
619
         void addToListEnumType(UlyssesType aTypeSymbol, Token otherlistelem)
620
        {
621
                final EnumType enumtype = (EnumType)((ListType)aTypeSymbol).innerType();
622
                addToEnumType(enumtype, otherlistelem, null);
623
        }
624

    
625
        /* create a new enumerated type */
626
         UlyssesType createEnumType(Token aRangeValue, Token anIntegerValue)
627
        {
628
                EnumType result;
629

    
630
                if (anIntegerValue == null)
631
                        result = new EnumType(null);
632
                else
633
                        result = new ValuedEnumType(null);
634

    
635
                addToEnumType(result, aRangeValue, anIntegerValue);
636
                return result;
637
        }
638

    
639
        /* add a new enum symbol to the enumerated type */
640
         void addToEnumType(UlyssesType aTypeSymbol, Token otherRangeValue, Token anIntegerValue)
641
        {
642
                final EnumType anEnum = (EnumType)aTypeSymbol;
643
                if (anEnum.symbolTable().Defined(otherRangeValue.getText()))
644
                {
645
                        doError(otherRangeValue, String.format("Element '%s' already defined!", otherRangeValue.getText()));
646
                        return;
647
                }
648

    
649
                /* for now we allow the usage of enum-ids without specifying the actual enum type,
650
                 * e.g., x = some_enum_id, hence all enum identifier must be globally unique.
651
                 * This decision could be reverted at later time...
652
                 */
653
                final Identifier sym = pState.Lookup(otherRangeValue);
654
                if (sym != null)
655
                {
656
                        doError(otherRangeValue, String.format("Element '%s' already defined!", otherRangeValue.getText()));
657
                        return;
658
                }
659

    
660
                EnumIdentifier enumval;
661
                if (anIntegerValue == null)
662
                {
663
                        if (aTypeSymbol instanceof ValuedEnumType)
664
                        {
665
                                doError(otherRangeValue, String.format("Element '%s' needs integer value!", otherRangeValue.getText()));
666
                                return;
667
                        }
668

    
669
                        enumval = new EnumIdentifier(otherRangeValue, (EnumType)aTypeSymbol, GetScope());
670
                }
671
                else
672
                {
673
                        if (!(aTypeSymbol instanceof ValuedEnumType))
674
                        {
675
                                doError(otherRangeValue, String.format("Element '%s' must not have integer value!", otherRangeValue.getText()));
676
                                return;
677
                        }
678
                        enumval = new EnumIdentifier(otherRangeValue, Integer.parseInt(anIntegerValue.getText()), (EnumType)aTypeSymbol, GetScope());
679
                }
680

    
681
                ((EnumType)aTypeSymbol).AddEnumSymbol(enumval);
682

    
683
                /* add the enum id to 'global' state */
684
                pState.currentScope.AddIdentifier(enumval, null);
685
        }
686

    
687
        /* get a named type */
688
         UlyssesType getNamedType(Token aType)
689
        {
690
                UlyssesType result = null;
691
                final Identifier sym = pState.Lookup(aType);
692
                if (sym == null)
693
                {
694
                        /* we might not have seen this type yet - so do a fixup run later */
695
                        result = new OpaqueType(new TypeIdentifier(aType, null, GetScope()));
696
                        pState.typesToFixUp.add((OpaqueType)result);
697
                }
698
                else if (sym.kind() == IdentifierKind.TypeIdentifier)
699
                        result = ((TypeIdentifier)sym).type();
700
                else
701
                        doError(aType, "Not a named type symbol: " + aType.getText());
702

    
703
                return result;
704
        }
705

    
706
        /* create a list type */
707
         @SuppressWarnings("unchecked")
708
        UlyssesType createListType(Token numOfElements, UlyssesType innertype)
709
        {
710
                if (innertype == null)
711
                        doError(numOfElements, "List type lacks proper element type (null)");
712

    
713
                int numElems = 0;
714

    
715
                if (numOfElements.getType() == ooaLexer.T_IDENTIFIER)
716
                {
717
                        // see whether we can find the constant
718
                        final Identifier aconst = pState.currentScope.ResolveIdentifier(numOfElements.getText());
719
                        if (aconst == null || aconst.kind() != IdentifierKind.Constant)
720
                                doError(numOfElements, String.format("Constant %s not found", numOfElements.getText()));
721
                        else if (aconst.type().kind() != TypeKind.IntType)
722
                                doError(numOfElements, "Constant must be integer");
723
                        else
724
                                numElems = ((ValueExpression<Integer>)((ConstantIdentifier)aconst).Value()).value();
725
                }
726
                else
727
                {
728
                        try {
729
                                numElems = Integer.parseInt(numOfElements.getText());
730
                        } catch (final NumberFormatException e) {
731
                                doError(numOfElements, "Not an integer");
732
                        }
733
                        if (numElems <= 0)
734
                                doError(numOfElements, "Number of elements in a list must be >= 1");
735
                }
736

    
737
                final ListType result = new ListType(innertype, numElems, null);
738
                return result;
739
        }
740

    
741
        /* create a map type */
742
         @SuppressWarnings("unchecked")
743
        UlyssesType createMapType(Token numOfElements, UlyssesType mapfromtype, UlyssesType maptotype)
744
        {
745
                if (mapfromtype == null)
746
                        doError(numOfElements, "Map: From-type not set (null)");
747
                if (maptotype == null)
748
                        doError(numOfElements, "Map: To-type not set (null)");
749

    
750
                int max = 0;
751

    
752
                if (numOfElements.getType() == ooaLexer.T_IDENTIFIER)
753
                {
754
                        // see whether we can find the constant
755
                        final Identifier aconst = pState.currentScope.ResolveIdentifier(numOfElements.getText());
756
                        if (aconst == null || aconst.kind() != IdentifierKind.Constant)
757
                                doError(numOfElements, String.format("Constant %s not found", numOfElements.getText()));
758
                        else if (aconst.type().kind() != TypeKind.IntType)
759
                                doError(numOfElements, "Constant must be integer");
760
                        else
761
                                max = ((ValueExpression<Integer>)((ConstantIdentifier)aconst).Value()).value();
762
                }
763
                else
764
                        try {
765
                                max = Integer.parseInt(numOfElements.getText());
766
                        } catch (final NumberFormatException e) {
767
                                doError(numOfElements, "Not an integer");
768
                        }
769

    
770
                final MapType result = new MapType(mapfromtype, maptotype, max, null);
771
                return result;
772
        }
773

    
774
        /* create a tuple type */
775
         UlyssesType createTupleType(UlyssesType aType)
776
        {
777
                final TupleType result = new TupleType(null);
778
                addToTupleType(result, aType);
779
                return result;
780
        }
781

    
782
        /* add inner type to tuple */
783
         void addToTupleType(UlyssesType aTypeSymbol, UlyssesType anotherType)
784
        {
785
                final TupleType tuple = (TupleType)aTypeSymbol;
786
                if (anotherType != null)
787
                        tuple.AddType(anotherType);
788
                else
789
                        doError("Unknown inner type in tuple");
790
        }
791

    
792
        /* create a QR type */
793
        UlyssesType createQrType(Token alandmark)
794
        {
795
                final QrType result = new QrType(null);
796
                addToQrType(result, alandmark);
797
                return result;
798
        }
799

    
800
        /* add another landmark to QR type */
801
        protected void addToQrType(UlyssesType aTypeSymbol, Token otherlandmark)
802
        {
803
                final Identifier sym = pState.Lookup(otherlandmark);
804
                if (sym != null)
805
                {
806
                        doError(otherlandmark, String.format("Redifinition of %s", otherlandmark.getText()));
807
                        return;
808
                }
809

    
810
                final LandmarkIdentifier lndmrk = new LandmarkIdentifier(otherlandmark, (QrType)aTypeSymbol, GetScope());
811
                ((QrType)aTypeSymbol).AddLandmark(lndmrk);
812
        }
813

    
814
        /* gets called after a simple type has been constructed. used to define an internal name*/
815
         void fixupSimpleType(UlyssesType aTypeSymbol)
816
        {
817
                if (aTypeSymbol != null)
818
                        aTypeSymbol.SetupAnonymousName();
819
        }
820

    
821
        /* gets called after a simple or complex type has been constructed. used to define an internal name */
822
         void fixupComplexType(UlyssesType aTypeSymbol)
823
        {
824
                if (aTypeSymbol != null)
825
                        aTypeSymbol.SetupAnonymousName();
826
        }
827

    
828

    
829
        /* create a method symbol */
830
         FunctionIdentifier createMethodSymbol(Token mname)
831
        {
832
                final Identifier sym = pState.Lookup(mname);
833
                if (sym != null)
834
                {
835
                        doError(mname, String.format("Redefinition of %s", mname.getText()));
836
                        return null;
837
                }
838

    
839
                final FunctionType funtype = new FunctionType(FunctionTypeEnum.Method, new LinkedList<UlyssesType>(), null);
840
                final MethodIdentifier msym = new MethodIdentifier(mname, funtype, GetScope());
841
                // funtype.SetTypeIdentifier(msym); -- the type of this function doesn't have a name!
842

    
843
                pState.currentScope.AddIdentifier(msym, null);
844

    
845
                pState.PushResolveStack(msym);
846
                return msym;
847
        }
848

    
849
        /* remove local method symbols from resolution stack again */
850
        protected void popResolveStack(FunctionIdentifier newMethod)
851
        {
852
                if (newMethod != null)
853
                        pState.PopResolveStack();
854
        }
855

    
856

    
857
        /* add a return type to a method */
858
         void setMethodReturnType(FunctionIdentifier newMethod, UlyssesType rt)
859
        {
860
                if (newMethod == null)
861
                        return;
862

    
863
                if (rt == null)
864
                        doError(String.format("Method %s has no return type (null)", newMethod.tokenText()));
865

    
866
                /* set return type */
867
                ((FunctionType)newMethod.type()).SetReturnType(rt);
868

    
869

    
870
                /* add hidden return parameter */
871
                if (newMethod.symbolTable().Defined("result"))
872
                {
873
                        doError(String.format("Method %s defines 'result'", newMethod.tokenText()));
874
                        return;
875
                }
876

    
877
                final ParameterIdentifier returnval = new ParameterIdentifier("result", rt, GetScope());
878
                newMethod.symbolTable().AddIdentifier(returnval);
879
        }
880

    
881
        /* add a parameter to a method */
882
         void addMethodParameter(FunctionIdentifier newMethod, Token paramName, UlyssesType atype)
883
        {
884
                if (newMethod == null)
885
                        return;
886

    
887
                if (atype == null)
888
                        doError(paramName, "Parameter has no type (null)");
889

    
890

    
891
                if (newMethod.symbolTable().Defined(paramName.getText()) == true)
892
                {
893
                        doError(paramName, String.format("Parameter '%s' already defined", paramName.getText()));
894
                        return;
895
                }
896

    
897
                // add parameter to scope
898
                final ParameterIdentifier param = new ParameterIdentifier(paramName, atype, GetScope());
899
                newMethod.AddParameter(param);
900

    
901
                // add type of param to signature
902
                final FunctionType ftype = (FunctionType)newMethod.type();
903
                ftype.AddParameterType(atype);
904
        }
905

    
906
        /* set method body of a method */
907
         void addMethodBody(FunctionIdentifier newMethod, Block statements)
908
        {
909
                if (newMethod == null)
910
                        return;
911

    
912
                if (statements == null)
913
                        doError(String.format("%s has empty body (null)",
914
                                        ((FunctionType)newMethod.type()).functionType() == FunctionTypeEnum.Method ? "Method" : "Action"));
915

    
916
                newMethod.SetBody(statements);
917
        }
918

    
919
        /* create a continuous action */
920
         FunctionIdentifier createNamedContinuousAction(Token cactionname, FunctionTypeEnum actionTypeEnum)
921
        {
922
                return createNamedAction(cactionname, actionTypeEnum);
923
        }
924

    
925
        /* create a named action */
926
         FunctionIdentifier createNamedAction(Token actionname, FunctionTypeEnum actionType)
927
        {
928
                final Identifier sym = pState.Lookup(actionname);
929
                if (sym != null)
930
                {
931
                        doError(actionname, String.format("Symbol '%s' already defined.", sym.tokenText()));
932
                        return null;
933
                }
934

    
935
                final FunctionType atype = new FunctionType(actionType, new LinkedList<UlyssesType>(), null);
936
                final NamedActionIdentifier action = new NamedActionIdentifier(actionname, atype, GetScope());
937
                // atype.SetTypeIdentifier(action); -- the type of this action doesn't have a name!
938

    
939
                pState.currentScope.AddIdentifier(action, null);
940
                pState.PushResolveStack(action);
941
                return action;
942
        }
943

    
944
        /* add body of action */
945
         void addActionBody(FunctionIdentifier newAction, GuardedCommand body)
946
        {
947
                // we need a wrapper around the guarded command..
948
                final Block bdy = new SeqBlock(currentLine(), currentPos());
949
                addMethodBody(newAction, bdy);
950
                body.SetParentScope(bdy);
951
                bdy.AddStatement(body);
952
        }
953

    
954
        /* add constraints of cont. action */
955
         void addContinuousActionBody(FunctionIdentifier newAction, GuardedCommand constraints)
956
        {
957
                final Block bdy = new SeqBlock(currentLine(), currentPos());
958
                bdy.AddStatement(constraints);
959
                addMethodBody(newAction, bdy);
960
        }
961

    
962
        /* create a guarded command */
963
         GuardedCommand createGuardedCommandStatement()
964
         {
965
                 return new GuardedCommand(null, null, currentLine(), currentPos());
966
         }
967

    
968
         void addExprAndBlockToGuardedCommand(GuardedCommand cmd, Expression expr, Block bdy)
969
        {
970
                if (bdy == null)
971
                        doError("Guarded command without body (null)!");
972

    
973
                if (expr == null)
974
                        doError("Guarded command without guard (null)!");
975

    
976
                cmd.SetGuard(expr);
977
                cmd.SetBody(bdy);
978
        }
979
         GuardedCommand createGuardedCommandStatement(Expression expr, Block bdy, boolean isQualitative)
980
        {
981
                final GuardedCommand result = createGuardedCommandStatement();
982
                addExprAndBlockToGuardedCommand(result, expr, bdy);
983
                result.SetIsQualitative(isQualitative);
984
                return result;
985
        }
986

    
987
        /* add statements to list */
988
         void addToStatementList(Block top, Statement stmt)
989
        {
990
                if (stmt == null)
991
                        doError("Can not add statement: null!");
992

    
993
                top.AddStatement(stmt);
994
        }
995

    
996
        /* create a Kill statement */
997
         Statement createKillStatement(Token aname)
998
        {
999
                final Identifier sym = pState.Lookup(aname);
1000
                if (sym == null)
1001
                        doError(aname, "Not defined");
1002

    
1003
                final KillStatement result = new KillStatement(sym, aname.getLine(), aname.getCharPositionInLine());
1004
                return result;
1005
        }
1006

    
1007
        /* create a Skip statement */
1008
         Statement createSkipStatement()
1009
        {
1010
                return new SkipStatement(currentLine(), currentPos());
1011
        }
1012

    
1013
        /* create a Break statement */
1014
         Statement createBreakStatement()
1015
        {
1016
                return new BreakStatement(currentLine(), currentPos());
1017
        }
1018

    
1019
        /* create an Abort statement */
1020
         Statement createAbortStatement()
1021
        {
1022
                return new AbortStatement(currentLine(), currentPos());
1023
        }
1024

    
1025
        /* creates a prioritized composition block */
1026
         Block createPrioBlock(Block top)
1027
        {
1028
                return new PrioBlock(top, currentLine(), currentPos());
1029
        }
1030

    
1031
        /* creates a nondeterministically composed block */
1032
         Block createNondetBlock(Block top)
1033
        {
1034
                return new NondetBlock(top, currentLine(), currentPos());
1035
        }
1036

    
1037
        /* creates a sequentially composed block */
1038
         SeqBlock createSeqBlock(Block top)
1039
        {
1040
                return new SeqBlock(top, currentLine(), currentPos());
1041
        }
1042

    
1043

    
1044
        /* adds a filter expression to seq block */
1045
        protected void addSeqBlockExpression(Block seqList, Expression sexpr)
1046
        {
1047
                seqList.SetFilter(sexpr); /*gets transformed to guarded command in resolvevisitor!*/
1048
        }
1049

    
1050

    
1051
        /* create a self identifier */
1052
         IdentifierExpression createSelfIdentifierExpression(Token self)
1053
        {
1054
                final Identifier id = pState.Lookup("self");
1055
                if (id == null)
1056
                {
1057
                        doError(self, "Can not resolve 'self'");
1058
                        return null;
1059
                }
1060

    
1061
                final IdentifierExpression result = new IdentifierExpression(id, self.getLine(), self.getCharPositionInLine());
1062
                result.setIsSelf(true);
1063
                return result;
1064
        }
1065

    
1066
        /* build up identifier tree... */
1067
         Expression createIdentifierAccessExpression(IdentifierExpression aself, Token token)
1068
        {
1069
                final Identifier someid = pState.Lookup(token.getText(), GetScope());
1070
                final Identifier self = pState.Lookup("self");
1071

    
1072
                if (someid != null)
1073
                {
1074
                        switch (someid.kind())
1075
                        {
1076
                        /* all method and attribute accesses are prefixed by self */
1077
                        case AttributeIdentifier:
1078
                        case MethodIdentifier:
1079
                                if (self == null)
1080
                                        doError(token, "Self access of method: Can not find 'self' symbol! (internal error)");
1081
                                aself = new IdentifierExpression(self, token.getLine(), token.getCharPositionInLine());
1082
                                aself.setIsSelf(true);
1083
                                break;
1084
                        default:
1085
                                break;
1086
                        }
1087
                }
1088

    
1089
                final IdentifierExpression ident = new UnresolvedIdentifierExpression(token, GetScope());
1090
                if (aself != null)
1091
                        return new AccessExpression(aself, ident, token.getLine(), token.getCharPositionInLine());
1092
                else
1093
                        return ident;
1094
        }
1095

    
1096
         AccessExpression addIdentifierAccessExpression(Expression parent, Token token)
1097
        {
1098
                final IdentifierExpression ident = new UnresolvedIdentifierExpression(token, GetScope());
1099
                return new AccessExpression(parent, ident, token.getLine(), token.getCharPositionInLine());
1100
        }
1101

    
1102
        /* we have a primed id; prime the complete subtree.. */
1103
        Expression setIdentifierExpressionPrimed(Expression oldExpr, Token token)
1104
        {
1105
                return new UnaryOperator(ExpressionKind.Primed, oldExpr, token.getLine(), token.getCharPositionInLine());
1106
        }
1107

    
1108
        /* create a fold operation */
1109
         Expression createFoldExpression(Expression result, Token afold, Expression initval, Expression anexpr)
1110
        {
1111
                ExpressionKind akind = ExpressionKind.foldLR;
1112
                if (afold.getType() == ooaLexer.T_FOLDLR)
1113
                        akind = ExpressionKind.foldLR;
1114
                else if (afold.getType() == ooaLexer.T_FOLDRL)
1115
                        akind = ExpressionKind.foldRL;
1116
                else
1117
                        assert(false);
1118

    
1119
                final TernaryOperator op = new TernaryOperator(akind, result, initval, anexpr, currentLine(), currentPos(), GetScope());
1120
                return op;
1121
        }
1122

    
1123

    
1124
        /* create a method access */
1125
         CallExpression createMethodAccessExpression(Expression subexpr, List<Expression> m_params, Token token)
1126
        {
1127
                assert(subexpr != null);
1128

    
1129
                return new CallExpression(subexpr, m_params, token.getLine(), token.getCharPositionInLine(), GetScope());
1130
        }
1131

    
1132
        /* create a tuple or map access */
1133
         TupleMapAccessExpression createTupleMapAccessExpression(Expression subexpr, Expression ac, Token token)
1134
        {
1135
                assert(subexpr != null);
1136

    
1137
                return new TupleMapAccessExpression(subexpr, ac, token.getLine(), token.getCharPositionInLine());
1138
        }
1139

    
1140
        /* create a method call statement; has to be resolved in a second run */
1141
         Statement createCallStatement(Expression aqname)
1142
        {
1143
                return new Call(aqname, currentLine(), currentPos());
1144
        }
1145

    
1146
        /* create a single assignment statement */
1147
         Statement createSingleAssignmentStatement(Expression aqname, Expression aexp)
1148
        {
1149
                final Assignment result = new Assignment(aqname, aexp, null, currentLine(), currentPos());
1150
                return result;
1151
        }
1152

    
1153
        /* create a multi-assignment statement; has to be resolved in a second run */
1154
         Statement createMultipleAssignmentStatementLHS(Expression aqname)
1155
        {
1156
                return new Assignment(aqname, null, null, currentLine(), currentPos());
1157
        }
1158

    
1159
        /* adds an expression to the multi-assign */
1160
         void addMutlipleAssignmentStatementRHS(Statement result, Expression mexp)
1161
        {
1162
                ((Assignment)result).AddValue(mexp);
1163
        }
1164

    
1165
        /* adds a LHS-var to the multi assign */
1166
         void addMultipleAssignmentStatementLHS(Statement result, Expression malhs)
1167
        {
1168
                ((Assignment)result).AddPlace(malhs);
1169
        }
1170

    
1171
        /* pop an assignment statement from the resolve stack */
1172
         void popAssignmentOffResolveStack(Statement result)
1173
        {
1174
                assert(result == pState.currentScope); // ref eq.
1175
                pState.PopResolveStack();
1176
        }
1177

    
1178
        /* pushes the assignment statement onto resolve stack. */
1179
         void pushAssignmentOnResolveStack(Statement result)
1180
        {
1181
                assert(result instanceof Assignment);
1182
                pState.PushResolveStack((Assignment)result);
1183
        }
1184

    
1185

    
1186
        /* adds a nondet-assignment constraint */
1187
         void addConstraintToAssignment(Statement result, Expression ndexp)
1188
        {
1189
                ((Assignment)result).SetNondetExpression(ndexp);
1190
        }
1191

    
1192
        /* add a named action call to do-od block */
1193
         void addNamedActionCallToBlockList(Block top, Token aname, List<Expression> m_params, Token maptoken, Expression amapexpression)
1194
        {
1195
                final Identifier id = pState.Lookup(aname);
1196
                if (id == null)
1197
                {
1198
                        doError(aname, String.format("Could not find named action '%s'", aname.getText()));
1199
                        return;
1200
                }
1201
                Expression callexpr;
1202
                if (id.kind() == IdentifierKind.MethodIdentifier)
1203
                {
1204
                        doError(aname, "Method access in do-od block not allowed.");
1205
                        return;
1206
                        // access via self
1207
                        /*
1208
            Identifier self = pState.Lookup("self");
1209
            if (self == null)
1210
                doError(aname, "Self access of method: Can not find 'self' symbol! (internal error)");
1211
            IdentifierExpression aself = new IdentifierExpression(self, aname.getLine(), aname.getCharPositionInLine());
1212
            aself.setIsSelf(true);
1213
            callexpr = new CallExpression(
1214
                new AccessExpression(aself,
1215
                    new IdentifierExpression(id, aname.getLine(), aname.getCharPositionInLine()), aname.getLine(), aname.getCharPositionInLine()),
1216
                    m_params, aname.getLine(), aname.getCharPositionInLine(), GetScope());
1217
                         */
1218
                }
1219
                else
1220
                        callexpr = new CallExpression(
1221
                                        new IdentifierExpression(id, aname.getLine(), aname.getCharPositionInLine()),
1222
                                        m_params, aname.getLine(), aname.getCharPositionInLine(), GetScope());
1223

    
1224
                if (amapexpression != null)
1225
                {
1226
                        ExpressionKind akind = ExpressionKind.foldLR;
1227
                        if (maptoken.getType() == ooaLexer.T_FOLDLR)
1228
                                akind = ExpressionKind.foldLR;
1229
                        else if (maptoken.getType() == ooaLexer.T_FOLDRL)
1230
                                akind = ExpressionKind.foldRL;
1231
                        else
1232
                                assert(false);
1233

    
1234
                        callexpr = new TernaryOperator(akind, callexpr, null, amapexpression,
1235
                                        currentLine(), currentPos(), GetScope());
1236
                }
1237
                final Call statement = new Call(callexpr, currentLine(), currentPos());
1238
                top.AddStatement(statement);
1239
        }
1240

    
1241
        /*adds skip statement instead of call to do-od block*/
1242
         void addSkipStatementToBlockList(Block top)
1243
        {
1244
                top.AddStatement(new SkipStatement(currentLine(), currentPos()));
1245
        }
1246

    
1247

    
1248
        /* add anonymous action to do-od block */
1249
         void addToBlockList(Block top, Statement gcmd)
1250
        {
1251
                if (gcmd != null)
1252
                        top.AddStatement(gcmd);
1253
        }
1254

    
1255
        /* add the do-od block to the action system type */
1256
         void addActionBlock(OoActionSystemType aTypeSymbol, Block bl)
1257
        {
1258
                aTypeSymbol.SetDoOdBlock(bl);
1259
        }
1260

    
1261
        /* push block */
1262
         void pushBlockToResolveStack(IScope toPush)
1263
        {
1264
                pState.PushResolveStack(toPush);
1265
        }
1266

    
1267
        /* pop block */
1268
         void popBlockFromResolveStack(IScope toPop)
1269
        {
1270
                if (toPop != null)
1271
                {
1272
                        assert(pState.currentScope == toPop); // ref eq.
1273
                        pState.PopResolveStack();
1274
                }
1275
        }
1276

    
1277
        /* add block var */
1278
         void addBlockVariable(Block seqList, Token varname, UlyssesType aType)
1279
        {
1280
                if (aType == null)
1281
                {
1282
                        doError(varname, String.format("%s lacks type!", varname.getText()));
1283
                }
1284
                try
1285
                {
1286
                        seqList.AddIdentifier(new LocalVariableIdentifier(varname, aType, GetScope()));
1287
                }
1288
                catch (final ArgumentException e)
1289
                {
1290
                        doError(varname, String.format("%s redefined!", varname.getText()));
1291
                }
1292
        }
1293

    
1294

    
1295
         QualitativeConstraintStatement createTwoVarConstraintStatement(Token id1, Token id2, QualitativeConstraintOperation op)
1296
        {
1297
                Identifier var1 = pState.Lookup(id1);
1298
                if (var1 == null)
1299
                {
1300
                        var1 = new ExpressionVariableIdentifier(id1.getText(), id1.getLine(), id1.getCharPositionInLine());
1301
                        var1.SetType(new AnyType((ExpressionVariableIdentifier)var1));
1302

    
1303
                        GetScope().AddIdentifier(var1, null);
1304

    
1305
                        doWarning(id1, String.format("Free variable in qualitative constraint: '%s'.", id1.getText()));
1306
                }
1307

    
1308
                Identifier var2 = pState.Lookup(id2);
1309
                if (var2 == null)
1310
                {
1311
                        var2 = new ExpressionVariableIdentifier(id2.getText(), id2.getLine(), id2.getCharPositionInLine());
1312
                        var2.SetType(new AnyType((ExpressionVariableIdentifier)var2));
1313

    
1314
                        GetScope().AddIdentifier(var2, null);
1315

    
1316
                        doWarning(id1, String.format("Free variable in qualitative constraint: '%s'.", id2.getText()));
1317
                }
1318

    
1319
                final QualitativeConstraintStatement result = new QualitativeConstraintStatement(var1, var2, op, id1.getLine(), id1.getCharPositionInLine());
1320
                return result;
1321
        }
1322

    
1323

    
1324
         QualitativeConstraintStatement createQualEqualConstraintStatement(Token id1, Token id2)
1325
        {
1326
                return createTwoVarConstraintStatement(id1, id2, QualitativeConstraintOperation.Equal);
1327
        }
1328

    
1329
         QualitativeConstraintStatement createQualArithConstraintStatement(Token id1, Token id2, Token id3, Token op)
1330
        {
1331
                Identifier var1 = pState.Lookup(id1);
1332
                if (var1 == null)
1333
                {
1334
                        var1 = new ExpressionVariableIdentifier(id1.getText(), id1.getLine(), id1.getCharPositionInLine());
1335
                        var1.SetType(new AnyType((ExpressionVariableIdentifier)var1));
1336

    
1337
                        GetScope().AddIdentifier(var1, null);
1338

    
1339
                        doWarning(id1, String.format("Free variable in qualitative constraint: '%s'.", id1.getText()));
1340
                }
1341

    
1342
                Identifier var2 = pState.Lookup(id2);
1343
                if (var2 == null)
1344
                {
1345
                        var2 = new ExpressionVariableIdentifier(id2.getText(), id2.getLine(), id2.getCharPositionInLine());
1346
                        var2.SetType(new AnyType((ExpressionVariableIdentifier)var2));
1347

    
1348
                        GetScope().AddIdentifier(var2, null);
1349

    
1350
                        doWarning(id1, String.format("Free variable in qualitative constraint: '%s'.", id2.getText()));
1351
                }
1352

    
1353
                Identifier var3 = pState.Lookup(id3);
1354
                if (var3 == null)
1355
                {
1356
                        var3 = new ExpressionVariableIdentifier(id3.getText(), id3.getLine(), id3.getCharPositionInLine());
1357
                        var3.SetType(new AnyType((ExpressionVariableIdentifier)var3));
1358

    
1359
                        GetScope().AddIdentifier(var3, null);
1360

    
1361
                        doWarning(id1, String.format("Free variable in qualitative constraint: '%s'.", id3.getText()));
1362
                }
1363
                QualitativeConstraintOperation operation;
1364
                switch (op.getType())
1365
                {
1366
                case ooaParser.T_SUM:
1367
                        operation = QualitativeConstraintOperation.Sum;
1368
                        break;
1369
                case ooaParser.T_DIFF:
1370
                        operation = QualitativeConstraintOperation.Diff;
1371
                        break;
1372
                case ooaParser.T_PROD:
1373
                        operation = QualitativeConstraintOperation.Prod;
1374
                        break;
1375
                default:
1376
                        doError(op, String.format("'%s' unknown operation", op.getText()));
1377
                        return null;
1378
                }
1379

    
1380
                final QualitativeConstraintStatement result = new QualitativeConstraintStatement(var1, var2, var3, operation, id1.getLine(), id1.getCharPositionInLine());
1381
                return result;
1382
        }
1383

    
1384
         QualitativeConstraintStatement createQualDerivConstraintStatement(Token id1, Token derivid)
1385
        {
1386
                return createTwoVarConstraintStatement(id1, derivid, QualitativeConstraintOperation.Deriv);
1387
        }
1388

    
1389

    
1390

    
1391
        /* creates a general binary operator without any children */
1392
         BinaryOperator createBinaryOperator(ExpressionKind akind)
1393
        {
1394
                final Token token = input.LT(-1);
1395
                return new BinaryOperator(akind, null, null, token.getLine(), token.getCharPositionInLine());
1396
        }
1397

    
1398

    
1399
        /* creates a general unary operator without child */
1400
         UnaryOperator createUnaryOperator(ExpressionKind unaryOperatorType)
1401
        {
1402
                final Token token = input.LT(-1);
1403
                return new UnaryOperator(unaryOperatorType, null, token.getLine(), token.getCharPositionInLine());
1404
        }
1405

    
1406
        /* create a conditional expression */
1407
         Expression createConditionalExpression(Expression ce, Expression te, Expression ee, Token ef)
1408
        {
1409
                return new TernaryOperator(ExpressionKind.conditional, ce, te, ee, ef.getLine(), ef.getCharPositionInLine(), GetScope());
1410
        }
1411

    
1412
        /* create a quantifier expression */
1413
         Quantifier createQuantifierExpression(Token t)
1414
        {
1415
                Quantifier result = null;
1416
                if (t.getType() == ooaLexer.T_FORALL)
1417
                        result = new ForallQuantifier(null, t.getLine(), t.getCharPositionInLine());
1418
                else
1419
                        result = new ExistsQuantifier(null, t.getLine(), t.getCharPositionInLine());
1420

    
1421

    
1422
                pState.PushResolveStack(result);
1423
                return result;
1424
        }
1425

    
1426
        /* add a bound variable to the quantifier */
1427
         void addBoundVarToQuantifierExpression(Quantifier result, Token id, UlyssesType id_type)
1428
        {
1429
                /*note: this might be a bit harsh, but for now it's easier to demand uniquely named vars,
1430
                without any hiding. Could be fixed in searching only the first resolve level for
1431
                dupes..
1432
                 */
1433
                final Identifier sym = pState.Lookup(id);
1434
                if (sym != null)
1435
                        doError(id, String.format("'%s' already defined!", id.getText()));
1436
                else
1437
                {
1438
                        if (id_type == null)
1439
                                doError(id, String.format("%s lacks type (null).", id.getText()));
1440
                        final Identifier newvar = new ExpressionVariableIdentifier(id, id_type, GetScope());
1441
                        result.AddIdentifier(newvar, null);
1442
                }
1443
        }
1444

    
1445
        /* add the expression to the quantifier */
1446
         void addExpressionToQuantifier(Quantifier result, Expression e)
1447
        {
1448
                result.SetChild(e);
1449
        }
1450

    
1451
        /* remove local variables from resolve stack */
1452
         void removeBoundVarsFromResolveStack(Quantifier result)
1453
        {
1454
                if (result != null)
1455
                        pState.PopResolveStack();
1456
        }
1457

    
1458

    
1459
        /* create a boolean constant */
1460
         LeafExpression createBoolConstant(boolean p)
1461
        {
1462
                final Token token = input.LT(-1);
1463
                return new ValueExpression<Boolean>(p, token.getLine(), token.getCharPositionInLine(), Boolean.class);
1464
        }
1465

    
1466
        /* create a nil */
1467
         LeafExpression createNullPointerConstant()
1468
        {
1469
                final Token token = input.LT(-1);
1470
                return new ValueExpression<Object>(null, token.getLine(), token.getCharPositionInLine(), Object.class);
1471
        }
1472

    
1473
        /* create a 'self' identifier */
1474
         LeafExpression createSelfPointer()
1475
        {
1476
                final Token token = input.LT(-1);
1477
                final Identifier self = pState.Lookup("self");
1478
                if (self == null)
1479
                {
1480
                        doError(token, "Could not resolve 'self'");
1481
                        return new UnresolvedIdentifierExpression(token, GetScope());
1482
                }
1483

    
1484
                final IdentifierExpression result = new IdentifierExpression(self, token.getLine(), token.getCharPositionInLine());
1485
                result.setIsSelf(true);
1486

    
1487
                return result;
1488
        }
1489

    
1490
        /* create a float const */
1491
         LeafExpression createFloatConstant(Token t_fl)
1492
        {
1493
                return new ValueExpression<Double>(Double.parseDouble(t_fl.getText()), t_fl.getLine(), t_fl.getCharPositionInLine(), Double.class);
1494
        }
1495

    
1496
        /* create int const */
1497
         LeafExpression createIntConstant(Token t_in)
1498
        {
1499
                return new ValueExpression<Integer>(Integer.parseInt(t_in.getText()), t_in.getLine(), t_in.getCharPositionInLine(), Integer.class);
1500
        }
1501

    
1502
        /* set children of binary operator*/
1503
         Expression addBinaryExpression(BinaryOperator binexpr, Expression expr, Expression e2)
1504
        {
1505
                binexpr.SetLeftChild(expr);
1506
                binexpr.SetRightChild(e2);
1507
                return binexpr;
1508
        }
1509

    
1510
        /* set child of unary expr */
1511
         Expression addUnaryExpression(UnaryOperator unexpr, Expression e)
1512
        {
1513
                if (unexpr != null)
1514
                {
1515
                        unexpr.SetChild(e);
1516
                        return unexpr;
1517
                }
1518
                else
1519
                        return e;
1520
        }
1521

    
1522

    
1523

    
1524
        /* create a list */
1525
         ListConstructor createInitializedList()
1526
        {
1527
                final Token nexttoken = input.LT(1);
1528
                return new ListConstructor(nexttoken.getLine(), nexttoken.getCharPositionInLine());
1529
        }
1530

    
1531
        /* add an element to the list */
1532
         void addListElement(ListConstructor result, Expression e)
1533
        {
1534
                result.AddElement(e);
1535
        }
1536

    
1537
        /* push list comprehension vars on resolve stack */
1538
         void pushListVarsOnResolveStack(ListConstructor result)
1539
        {
1540
                pState.PushResolveStack(result);
1541
        }
1542

    
1543
        /* pop list comprehension vars from resolve stack */
1544
         void popListVarsFromResolveStack(ListConstructor result)
1545
        {
1546
                if (result != null)
1547
                        pState.PopResolveStack();
1548
        }
1549

    
1550
        /* set list comprehension expression */
1551
         void addListComprExpr(ListConstructor result, Expression e)
1552
        {
1553
                result.SetComprehension(e);
1554
        }
1555

    
1556
        /* add list comprehension variable */
1557
         void addListComprVar(ListConstructor result, Token id, UlyssesType t1)
1558
        {
1559
                final Identifier sym = pState.Lookup(id);
1560
                if (sym != null)
1561
                {
1562
                        /* see notes in quantifier*/
1563
                        doError(id, String.format("'%s' already defined.", id.getText()));
1564
                }
1565
                else
1566
                {
1567
                        final ExpressionVariableIdentifier newvar = new ExpressionVariableIdentifier(id, t1, GetScope());
1568
                        result.AddIdentifier(newvar, null);
1569
                }
1570
        }
1571

    
1572
        /* converts a String into a list of char */
1573
         ListConstructor createStringConstant(Token t_l)
1574
        {
1575
                final ListConstructor result = new ListConstructor(t_l.getLine(), t_l.getCharPositionInLine());
1576
                final String substr = t_l.getText().substring(1, t_l.getText().length() - 2);
1577
                for (int cntr = 0; cntr < substr.length(); cntr++) {
1578
                        final char c = substr.charAt(cntr);
1579
                        result.AddElement(new ValueExpression<Character>(c, t_l.getLine(), t_l.getCharPositionInLine(), Character.class));
1580
                }
1581
                return result;
1582
        }
1583

    
1584
        /* creates an empty map */
1585
         Expression createEmptyMap()
1586
        {
1587
                final Token token = input.LT(-1);
1588
                return new MapConstructor(token.getLine(), token.getCharPositionInLine());
1589
        }
1590

    
1591
        /* create a map and populate it with two items.. */
1592
         Expression createMap(Expression e1, Expression e2, Token am)
1593
        {
1594
                final MapConstructor result = new MapConstructor(am.getLine(), am.getCharPositionInLine());
1595
                result.AddItem(e1, e2);
1596
                return result;
1597
        }
1598

    
1599
        /* add a key/value pair to a map */
1600
         void addToMap(Expression map, Expression e3, Expression e4)
1601
        {
1602
                ((MapConstructor)map).AddItem(e3, e4);
1603
        }
1604

    
1605
        /* create a set */
1606
         SetConstructor createSet()
1607
        {
1608
                final Token nexttoken = input.LT(1);
1609
                final SetConstructor result = new SetConstructor(nexttoken.getLine(), nexttoken.getCharPositionInLine());
1610
                return result;
1611
        }
1612

    
1613
        /* add item to set */
1614
         void addToSet(Expression result, Expression e2)
1615
        {
1616
                ((SetConstructor)result).AddItem(e2);
1617
        }
1618

    
1619
        /* remove set comprehension variables from resolution stack */
1620
         void popSetVarsFromResolveStack(SetConstructor _set)
1621
        {
1622
                if (_set != null)
1623
                        pState.PopResolveStack();
1624
        }
1625

    
1626
        /* add set comprehension variables to resolution stack */
1627
         void pushSetVarsOnResolveStack(SetConstructor _set)
1628
        {
1629
                pState.PushResolveStack(_set);
1630
        }
1631

    
1632
        /* set comprehension expression fro set */
1633
         void addSetComprExpr(SetConstructor _set, Expression epx)
1634
        {
1635
                _set.SetComprehension(epx);
1636
        }
1637

    
1638
        /* add local set compr. variable */
1639
         void addSetComprVar(SetConstructor _set, Token id1, UlyssesType t1)
1640
        {
1641
                final Identifier sym = pState.Lookup(id1);
1642
                if (sym != null)
1643
                        doError(id1, String.format("'%s' already defined!", id1.getText()));
1644
                else
1645
                {
1646
                        final ExpressionVariableIdentifier newvar = new ExpressionVariableIdentifier(id1, t1, GetScope());
1647
                        _set.AddIdentifier(newvar, null);
1648
                }
1649
        }
1650

    
1651
        /* check whether identifier p is a tuple type */
1652
         boolean isTuple(String p)
1653
        {
1654
                final Identifier sym = pState.Lookup(p);
1655
                return (sym != null)
1656
                                && (sym.kind() == IdentifierKind.TypeIdentifier)
1657
                                && (sym.type().kind() == TypeKind.TupleType);
1658
        }
1659

    
1660
        /* create an initialized tuple */
1661
         Expression createInitializedTuple(Token aName, List<Expression> m_params)
1662
        {
1663
                final Identifier sym = pState.Lookup(aName);
1664
                if ((sym == null) || !(sym.type() instanceof TupleType))
1665
                {
1666
                        doError(aName, "Not a tuple type!");
1667
                        return null;
1668
                }
1669

    
1670
                final TupleType atuple = (TupleType)sym.type();
1671
                if (atuple.innerTypes().size() != m_params.size())
1672
                {
1673
                        doError(aName, "Number of parameters does not match type definition!");
1674
                        return null;
1675
                }
1676

    
1677
                return new TupleConstructor(sym, m_params, aName.getLine(), aName.getCharPositionInLine());
1678
        }
1679

    
1680

    
1681
        /* create an reference expression: (<expression>).xyz */
1682
         Expression createExpressionReference(Expression e, Expression aref, Token atoken)
1683
        {
1684
                final AccessExpression result = new AccessExpression(e, aref, atoken.getLine(), atoken.getCharPositionInLine());
1685
                return result;
1686
        }
1687

    
1688

    
1689
        /* gets called when we are parsing attributes */
1690
         void BeginParsingAttributes()
1691
        {
1692
                pState.parsingAttributes = true;
1693
        }
1694

    
1695
        /* gets called when we stop parsing attributes */
1696
         void EndParsingAttributes()
1697
        {
1698
                pState.parsingAttributes = false;
1699
        }
1700

    
1701
        /*dummy*/
1702
         boolean notIsAttributeInitialization()
1703
        {
1704
                return !pState.parsingAttributes;
1705
        }
1706

    
1707
        /* create a new(anid) constructor */
1708
        protected Expression createObject(Token anid)
1709
        {
1710
                if (!pState.parsingAttributes)
1711
                {
1712
                        doError(anid, "Object creation with 'new' only allowed in variable initializers.");
1713
                        return null;
1714
                }
1715

    
1716

    
1717
                final OpaqueType atype = new OpaqueType(new TypeIdentifier(anid, null, GetScope()));
1718
                pState.typesToFixUp.add(atype);
1719
                return new ObjectConstructor(atype, anid.getLine(), anid.getCharPositionInLine());
1720
        }
1721

    
1722

    
1723
        protected Expression createNamedObject(Token anid, Token aname)
1724
        {
1725
                if (!pState.parsingAttributes)
1726
                {
1727
                        doError(anid, "Object creation with 'new' only allowed in variable initializers.");
1728
                        return null;
1729
                }
1730

    
1731
                if (! aname.getText().matches("\"[_]*[a-zA-Z][a-zA-Z0-9_]*\""))
1732
                {
1733
                        doError(aname, "Not a valid identifier");
1734
                        return null;
1735
                }
1736

    
1737
                final OpaqueType atype = new OpaqueType(new TypeIdentifier(anid, null, GetScope()));
1738
                pState.typesToFixUp.add(atype);
1739
                return new ObjectConstructor(atype, aname.getText(), anid.getLine(), anid.getCharPositionInLine());
1740
        }
1741

    
1742

    
1743
         void setQualitativeDerivDec(QValConstructor result)
1744
        {
1745
                result.SetDerivation(QValDeriv.Dec);
1746
        }
1747

    
1748
         void setQualitativeDerivInc(QValConstructor result)
1749
        {
1750
                result.SetDerivation(QValDeriv.Inc);
1751
        }
1752

    
1753
         void setQualitativeDerivSteady(QValConstructor result)
1754
        {
1755
                result.SetDerivation(QValDeriv.Steady);
1756
        }
1757

    
1758
         void setQualitativeDerivDontCare(QValConstructor result)
1759
        {
1760
                result.SetDerivation(QValDeriv.DonTCare);
1761
        }
1762

    
1763
         void setQualitativeValueRangeInfinity(QValConstructor result, boolean p)
1764
        {
1765
                throw new NotImplementedException();
1766
        }
1767

    
1768
         void setQualitativeValueRange(QValConstructor result, Expression expr2)
1769
        {
1770
                result.AddRange(expr2);
1771
        }
1772

    
1773
         void setQualitativeValueInfinity(QValConstructor result, boolean minus)
1774
        {
1775
                throw new NotImplementedException();
1776
        }
1777

    
1778
         void setQualitativeValueLandmark(QValConstructor result, Expression expr)
1779
        {
1780
                result.SetValue(expr);
1781
        }
1782

    
1783
         void setQualitativeValueDontCare(QValConstructor result)
1784
        {
1785
                throw new NotImplementedException();
1786
        }
1787

    
1788
         QValConstructor createQualitativeValue(Token aval)
1789
        {
1790
                return new QValConstructor(aval.getLine(), aval.getCharPositionInLine());
1791
        }
1792

    
1793
        /* add a local variable to a named action */
1794
         void addLocalVariableToNamedAction(FunctionIdentifier newMethod, Token id1, UlyssesType t1)
1795
        {
1796
                if (t1 == null)
1797
                {
1798
                        doError(id1, "Variable lacks type");
1799
                        return;
1800
                }
1801

    
1802
                final LocalVariableIdentifier lvar = new LocalVariableIdentifier(id1, t1, GetScope());
1803
                newMethod.AddIdentifier(lvar, null);
1804
        }
1805

    
1806
        /* ====== */
1807
        /* ====== */
1808

    
1809
        public static final LinkedHashMap<String, String> readableTokens = new LinkedHashMap<String, String>();
1810

    
1811

    
1812
//        private void SetUpTokenDictionary()
1813
        static
1814
        {
1815
//                if (readableTokens.size() > 0)
1816
//                        return;
1817
                readableTokens.put("<invalid>", "<invalid>");
1818
                readableTokens.put("<EOR>", "<EOR>");
1819
                readableTokens.put("<DOWN>", "<DOWN>");
1820
                readableTokens.put("<UP>", "<UP>");
1821
                readableTokens.put("T_TYPES", "'types'");
1822
                readableTokens.put("T_SYSTEM", "'system'");
1823
                readableTokens.put("T_SEMICOLON", "';'");
1824
                readableTokens.put("T_IDENTIFIER", "<identifier>");
1825
                readableTokens.put("T_EQUAL", "'='");
1826
                readableTokens.put("T_PRIO", "'//'");
1827
                readableTokens.put("T_NONDET", "'[]'");
1828
                readableTokens.put("T_LPAREN", "'('");
1829
                readableTokens.put("T_RPAREN", "')'");
1830
                readableTokens.put("T_LIST", "'list'");
1831
                readableTokens.put("T_LSQPAREN", "'['");
1832
                readableTokens.put("T_INTNUMBER", "<integer>");
1833
                readableTokens.put("T_RSQPAREN", "']'");
1834
                readableTokens.put("T_OF", "'of'");
1835
                readableTokens.put("T_COMMA", "','");
1836
                readableTokens.put("T_MAP", "'map'");
1837
                readableTokens.put("T_TO", "'to'");
1838
                readableTokens.put("T_QUANTITY", "'quantity'");
1839
                readableTokens.put("T_INFTY", "'inf'");
1840
                readableTokens.put("T_BOOL", "'bool'");
1841
                readableTokens.put("T_INT", "'int'");
1842
                readableTokens.put("T_RANGETO", "'..'");
1843
                readableTokens.put("T_FLOAT", "'float'");
1844
                readableTokens.put("T_FLOATNUMBER", "<floating point number>");
1845
                readableTokens.put("T_CHAR", "'char'");
1846
                readableTokens.put("T_CBRL", "'{'");
1847
                readableTokens.put("T_CBRR", "'}'");
1848
                readableTokens.put("T_AUTOCONS", "'autocons'");
1849
                readableTokens.put("T_VAR", "'var'");
1850
                readableTokens.put("T_METHODS", "'methods'");
1851
                readableTokens.put("T_ACTIONS", "'actions'");
1852
                readableTokens.put("T_DO", "'do'");
1853
                readableTokens.put("T_OD", "'od'");
1854
                readableTokens.put("T_STATIC", "'static'");
1855
                readableTokens.put("T_COLON", "':'");
1856
                readableTokens.put("T_END", "'end'");
1857
                readableTokens.put("T_CONT", "'cont'");
1858
                readableTokens.put("T_CTRL", "'ctr'");
1859
                readableTokens.put("T_OBS", "'obs'");
1860
                readableTokens.put("T_REQUIRES", "'requires'");
1861
                readableTokens.put("T_AND", "'and'");
1862
                readableTokens.put("T_ABORT", "'abort'");
1863
                readableTokens.put("T_SKIP", "'skip'");
1864
                readableTokens.put("T_KILL", "'kill'");
1865
                readableTokens.put("T_SELF", "'self'");
1866
                readableTokens.put("T_ASSIGNMENT", "':='");
1867
                readableTokens.put("T_WITH", "'with'");
1868
                readableTokens.put("T_IF", "'if'");
1869
                readableTokens.put("T_THEN", "'then'");
1870
                readableTokens.put("T_ELSE", "'else'");
1871
                readableTokens.put("T_FORALL", "'forall'");
1872
                readableTokens.put("T_EXISTS", "'exists'");
1873
                readableTokens.put("T_TRUE", "'true'");
1874
                readableTokens.put("T_FALSE", "'false'");
1875
                readableTokens.put("T_NIL", "'nil'");
1876
                readableTokens.put("T_STRINGLITERAL", "'\"<String>\"'");
1877
                readableTokens.put("T_NEW", "'new'");
1878
                readableTokens.put("T_BAR", "'|'");
1879
                readableTokens.put("T_MAPS", "'->'");
1880
                readableTokens.put("T_PRIMED", "'''");
1881
                readableTokens.put("T_POINT", "'.'");
1882
                readableTokens.put("T_NOTEQUAL", "'<>'");
1883
                readableTokens.put("T_SEQMOD_MAPOVERRIDE", "'++'");
1884
                readableTokens.put("T_BIIMPLIES", "'<=>'");
1885
                readableTokens.put("T_IMPLIES", "'=>'");
1886
                readableTokens.put("T_OR", "'or'");
1887
                readableTokens.put("T_ABS", "'abs'");
1888
                readableTokens.put("T_DIV", "'/'");
1889
                readableTokens.put("T_GREATER", "'>'");
1890
                readableTokens.put("T_GREATEREQUAL", "'>='");
1891
                readableTokens.put("T_IDIV", "'div'");
1892
                readableTokens.put("T_LESS", "'<'");
1893
                readableTokens.put("T_LESSEQUAL", "'<='");
1894
                readableTokens.put("T_MINUS", "'-'");
1895
                readableTokens.put("T_MOD", "'mod'");
1896
                readableTokens.put("T_POW", "'**'");
1897
                readableTokens.put("T_PROD", "'*'");
1898
                readableTokens.put("T_SUM", "'+'");
1899
                readableTokens.put("T_CONC", "'^'");
1900
                readableTokens.put("T_DIFF", "'\\'");
1901
                readableTokens.put("T_INTER", "'inter'");
1902
                readableTokens.put("T_IN", "'in'");
1903
                readableTokens.put("T_SET", "'set'");
1904
                readableTokens.put("T_NOT", "'not'");
1905
                readableTokens.put("T_SUBSET", "'subset'");
1906
                readableTokens.put("T_UNION", "'union'");
1907
                readableTokens.put("T_DOMRESBY", "'<-:'");
1908
                readableTokens.put("T_DOMRESTO", "'<:'");
1909
                readableTokens.put("T_RNGRESBY", "':->'");
1910
                readableTokens.put("T_RNGRESTO", "':>'");
1911
                readableTokens.put("T_MUNION", "'munion'");
1912
                readableTokens.put("T_CARD", "'card'");
1913
                readableTokens.put("T_DCONC", "'conc'");
1914
                readableTokens.put("T_DINTER", "'dinter'");
1915
                readableTokens.put("T_DUNION", "'dunion'");
1916
                readableTokens.put("T_ELEMS", "'elems'");
1917
                readableTokens.put("T_HEAD", "'hd'");
1918
                readableTokens.put("T_INDS", "'inds'");
1919
                readableTokens.put("T_LEN", "'len'");
1920
                readableTokens.put("T_TAIL", "'tl'");
1921
                readableTokens.put("T_DOM", "'dom'");
1922
                readableTokens.put("T_RNG", "'rng'");
1923
                readableTokens.put("T_MERGE", "'merge'");
1924
                readableTokens.put("T_WS", "<space>");
1925
                readableTokens.put("T_COMMENT", "'/*<comment>*/'");
1926
                readableTokens.put("LINE_COMMENT", "'#<line comment>'");
1927
                readableTokens.put("T_DIGIT", "<0..9>");
1928
                readableTokens.put("FLOAT_OR_INT_OR_RANGE", "<float_int_range>");
1929
                readableTokens.put("T_LETTER", "<a..z,A..Z>");
1930
                readableTokens.put("'|['", "'|['");
1931
                readableTokens.put("']|'", "']|'");
1932
                readableTokens.put("'add'", "'add'");
1933
                readableTokens.put("'mult'", "'mult'");
1934
                readableTokens.put("'deriv'", "'deriv'");
1935
                readableTokens.put("'mon+'", "'mon+'");
1936
                readableTokens.put("'mon-'", "'mon-'");
1937
                readableTokens.put("'id'", "'id'");
1938
                readableTokens.put("'qval'", "'qval'");
1939
                readableTokens.put("'\"'", "'\"'");
1940
                readableTokens.put("as", "as");
1941
        }
1942

    
1943
        /* override routine that displays recongition errors.. */
1944
        @Override
1945
        public void displayRecognitionError(String[] tokenNames, RecognitionException e)
1946
        {
1947
                int i;
1948
                final StringBuilder result = new StringBuilder();
1949
//                SetUpTokenDictionary();
1950

    
1951

    
1952
                if (e instanceof MismatchedTokenException)
1953
                {
1954
                        result.append("Found '");
1955
                        result.append(e.token.getText());
1956
                        result.append("'");
1957
                        i = ((MismatchedTokenException)e).expecting;
1958
                        result.append(" Expected: ");
1959
                        result.append(readableTokens.get(tokenNames[i]));
1960
                        result.append(" ("); result.append(tokenNames[i]); result.append(") ");
1961

    
1962
                }
1963
                else
1964
                {
1965
                        /*if (e is NoViableAltException)
1966
            {
1967
                result.Append("Unexpected '");
1968
                result.Append(e.Token.getText());
1969
                result.Append("' (");
1970
                i = ((NoViableAltException)e).UnexpectedType;
1971
                result.Append(tokenNames[i]);
1972
                result.Append(")");
1973
            }
1974
            else*/
1975
                        if (e instanceof RecognitionException)
1976
                        {
1977
                                result.append("Unexpected '");
1978
                                result.append(e.token.getText());
1979
                                result.append("' (");
1980
                                i = e.getUnexpectedType();
1981
                                result.append(tokenNames[i]);
1982
                                result.append(") ");
1983
                        }
1984
                        else
1985
                                result.append(e.getMessage());
1986
                }
1987

    
1988
                pState.AddErrorMessage(new ParserError(pState.filename, e.line, e.charPositionInLine, result.toString()));
1989
        }
1990

    
1991

    
1992
        /* just run over once */
1993
        public static int FirstPass(ParserState pState)
1994
        {
1995
                pState.parser.ooActionSystems();
1996

    
1997
                return pState.listOfParserErrors.size(); // + pState.lexer.NumberOfSyntaxErrors;
1998
        }
1999

    
2000

    
2001

    
2002
        /* print syntax tree */
2003
        public static String PrintSyntaxTree(ParserState pState)
2004
        {
2005
                if ((pState != null) && (pState.ooaSystem != null))
2006
                {
2007
                        return pState.ooaSystem.toString();
2008
                }
2009
                else
2010
                        return "";
2011
        }
2012

    
2013

    
2014
        public ooaCustomParser(TokenStream input, RecognizerSharedState state) {
2015
                super(input, state);
2016
        }
2017
}