Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / ooa.g

1 3 krennw
/*
2
			ANTLR Grammar for OO-Action Systems
3
			 (C) Willibald Krenn, 2009 - 2010
4
5
6
  Notes
7
  ~~~~~
8
  	(*) No recursion
9
  	(*) float acutally is fixed-point!
10
	(*) Named actions can only be "called" within the do-od block
11
	(*) Methods can be called from within an action and a method.
12
	    Attention: Mutual Recursion not supported!
13
14
  FixMe
15
  ~~~~~
16
  	(*) List-Enum: Length Restriction! (Defaults to 500 for now)
17
	(*) subseteq missing
18
19
20
21
  History
22
  ~~~~~~~
23
  Changes 1.03 to 1.04
24
  	~ Fix bug with set constuctor: set with only one element produced wrong AST (inner element wasn't added correctly).
25
26
  Changes 1.02 to 1.03
27
  	+ option to name objects when they are constructed: new (<class>,"<name>")
28
29
  Changes 1.00 to 1.02
30
  	+ cast operator for objects ( ... as <typename> )
31
32
  Changes 1.00 to 1.01
33
  	+ enum-type with fixed integer values
34
35
  Changes 0.99b to 1.00
36
  	+ constant section added (consts a=4; b=4)
37
  	+ limits of simple types and lists can be const
38
  	+ local vars allowed in methods (... = var... begin...end)
39
  	+ prioritized composition on statement level
40
  	+ skip in do-od block
41
  	+ filter expression in do-od block sequential var statement
42
  	+ fold operator
43
44
  Changes 0.99 to 0.99b
45
        - disabled sequential composition of action systems (remains in grammar, though out-commented)
46
47
  Changes 0.98 to 0.99
48
        ~ changed QR syntax.
49
50
  Changes 0.97 to 0.98
51
  	~ changed syntax for list and set comprehension
52
  	  list comprehension:
53
  	  '[' expression '|' 'var' id ':' type (';' id ':' type)* ('&' expression)? ']'
54
  	  set comprehension
55
  	  '{' expression '|' 'var' id ':' type (';' id ':' type)* ('&' expression)? '}'
56
57
  	  Usage: defined variables will sweep over value-range. If the latter expression
58
  	  (after '&') evaluates to true (hence this expression must return a bool) with
59
  	  the current valuation of the defined vars, the values are used to evaluate the
60
  	  first expression, which has to return a value of the correct type.
61
62
  	  Example:
63
  	  type
64
  	    myint = int [0..300000];
65
  	    mytuple = (myint, myint)
66
  	  var
67
  	     l_tuple : list of mytuple = [nil];
68
  	     l_int : list of myint = [nil];
69
  	    ...
70
  	      l_int := [l_tuple[x][0] | var x: myint & x < len l_tuple ]
71
72
73
  	+ list element access by '[int]' allowed!
74
75
76
  Changes 0.96 to 0.97
77
  	+ tuple-type initialization now properly supported
78
  	+ binary operator precedence handling
79
  	+ local variables in named actions
80
  	+ support for (<expression>).<reference> and
81
  	              (<expression>).<accessExpression>
82
  	~ conditional expression: End required.
83
  	- remove support for power-operator
84
  	  (may be we need to do calculation backwards)
85
86
  Changes 0.95 to 0.96
87
  	~ string literals now ".."
88
  	~ priming of identifier access only supported at the end of the
89
  	  expression
90
91
  Changes 0.9 to 0.95
92
  	+ composition of action systems in 'system' block
93
  	~ Produce C# code
94
  	~ Operator Precedence
95
  	~ vars in action composition
96
  	~ forall/extists now with colon instead of in
97
98
99
  Earlier changes  removed.
100
101
*/
102
103
104
grammar ooa;
105
106
options {
107
  language = CSharp2;
108
  k = 2;
109
//  output = AST;
110
}
111
112
113
@lexer::namespace { TUG.Mogentes }
114
115
@lexer::header
116
{
117
/*
118
    Ulysses OO-Action System Parser
119
120
    Copyright Willibald Krenn 2009
121
122
 */
123
}
124
125
@parser::namespace { TUG.Mogentes }
126
127
@parser::header
128
{
129
/*
130
    Ulysses OO-Action System Parser
131
132
    Copyright Willibald Krenn 2009
133
134
 */
135
}
136
137
ooActionSystems
138
	:	{initializeTopLevelParserState();}
139
140
	         (T_CONSTS namedConstList)?
141
142
		 T_TYPES
143
		  	namedTypeList
144
		 T_SYSTEM
145
			comp=asTypeComposition[null]
146
			{fixUpRun(comp);}
147
	;
148
149
150
151
//
152
//  ------------   named consts  ------------
153
//
154
155
namedConstList
156
	:	namedConst (T_SEMICOLON namedConst)*
157
	;
158
159
namedConst
160
	:	aName=T_IDENTIFIER
161
		T_EQUAL
162
		anExpr=expression
163
		{addNamedConst(aName,anExpr);}
164
	;
165
166
167
//
168
//  ------------   named types  ------------
169
//
170
namedTypeList
171
	:	namedType (T_SEMICOLON namedType)*
172
	;
173
174
namedType
175
	:	aName=T_IDENTIFIER
176
		T_EQUAL
177
		(
178
			aType=complexType 	 {createNamedType(aName,aType);}
179
		|	anOoaType=ooActionSystem {createNamedType(aName,anOoaType);}
180
		)
181
182
	;
183
184
185
asTypeComposition [IdentifierList top]
186
	returns [IdentifierList prioList]
187
	:  	{prioList = new PrioIdentifierList(top);}
188
		asTypeCompositionParallel[prioList]  (T_PRIO asTypeCompositionParallel[prioList] )*
189
	;
190
191
asTypeCompositionParallel [IdentifierList top]
192
	:  	{IdentifierList parList = new NondetIdentifierList(top);}
193
		asTypeCompositionSequential[parList] (T_NONDET asTypeCompositionSequential[parList])*
194
	;
195
196
asTypeCompositionSequential [IdentifierList top]
197
	:  	{IdentifierList seqList = new SeqIdentifierList(top);}
198
		asTypeCompositionBlockParen[seqList] //(T_SEMICOLON asTypeCompositionBlockParen[seqList])*
199
	;
200
201
asTypeCompositionBlockParen [IdentifierList top]
202
	: T_LPAREN asTypeComposition[top] T_RPAREN
203
	| aName=T_IDENTIFIER {addToIdentifierList(top,aName);}
204
	;
205
206
207
//
208
//  ------------   basic types    ------------
209
//
210
211
complexType
212
	returns [UlyssesType aTypeSymbol]
213
	@init{
214
		aTypeSymbol = null;
215
		alandmark = null;
216
	}
217
	:	T_LIST  T_LSQPAREN numOfElements=(T_INTNUMBER|T_IDENTIFIER) T_RSQPAREN T_OF  innertype=complexType
218
			{aTypeSymbol = createListType(numOfElements,innertype);}
219
220
		// list type with predefined elements (dupes of each element as many as needed) FIXME: Length Restriction!
221
	|	T_LSQPAREN alistelem=T_IDENTIFIER {aTypeSymbol = createListEnumType(alistelem);}
222
			(T_COMMA otherlistelem=T_IDENTIFIER {addToListEnumType(aTypeSymbol,otherlistelem);})* T_RSQPAREN // set of identifiers..
223
224
		// maps do not really need a length restriction, as simpleType already is restricted..
225
	|	T_MAP   (T_LSQPAREN numOfElements=(T_INTNUMBER|T_IDENTIFIER) T_RSQPAREN)? mapfromtype=simpleType T_TO maptotype=complexType
226
			{aTypeSymbol = createMapType(numOfElements,mapfromtype,maptotype);}
227
		// quantity space
228
	|	T_QUANTITY T_OF	T_LSQPAREN (alandmark=T_IDENTIFIER| alandmark=T_MINUS T_INFTY) {aTypeSymbol = createQrType(alandmark);}
229
			(T_COMMA (otherlandmark=T_IDENTIFIER|otherlandmark=T_INFTY) {addToQrType(aTypeSymbol,otherlandmark);})* T_RSQPAREN
230
		// tuple
231
	|	 T_LPAREN aType=complexType {aTypeSymbol = createTupleType(aType);}
232
			(T_COMMA anotherType=complexType {addToTupleType(aTypeSymbol,anotherType);})*  T_RPAREN
233
234
		// some simple type (note that this includes identifiers, which may be complex object types..)
235
	|	r=simpleType {aTypeSymbol = r;}
236
	;
237
	finally
238
		{fixupComplexType(aTypeSymbol);}
239
240
241
simpleType
242
	returns [UlyssesType aTypeSymbol]
243
	@init{
244
		aTypeSymbol = null;
245
	}
246
	:	T_BOOL  {aTypeSymbol = createBoolType();}
247
248
		// ints plus subtypes
249
	|	T_INT T_LSQPAREN rangeLow=(T_INTNUMBER|T_INFTY|T_IDENTIFIER) T_RANGETO rangeHigh=(T_INTNUMBER|T_INFTY|T_IDENTIFIER) T_RSQPAREN
250
			{aTypeSymbol = createIntType(rangeLow,rangeHigh);}
251
252
		// floats plus subtypes
253
	|	T_FLOAT  T_LSQPAREN rangeLow=(T_FLOATNUMBER|T_INFTY|T_IDENTIFIER) T_RANGETO rangeHigh=(T_FLOATNUMBER|T_INFTY|T_IDENTIFIER) T_RSQPAREN
254
			{aTypeSymbol = createFloatType(rangeLow,rangeHigh);}
255
256
		// char
257
	|	T_CHAR {aTypeSymbol = createCharType();}
258
259
		// simple type, domain restricted to the values within the given set. (operators supported: equal, not equal) - may be casted to integer if
260
		// explicit int values are given
261
	|	T_CBRL aRangeValue=T_IDENTIFIER (T_EQUAL optVal=T_INTNUMBER)? {aTypeSymbol = createEnumType(aRangeValue, optVal);}
262
			(T_COMMA otherRangeValue=T_IDENTIFIER (T_EQUAL otherOptVal=T_INTNUMBER)? {addToEnumType(aTypeSymbol,otherRangeValue,otherOptVal); otherOptVal=null;})* T_CBRR
263
264
	|	aType=T_IDENTIFIER {aTypeSymbol = getNamedType(aType);} // alias could be simple type - otherwise, it's a complex type!!
265
	;
266
	finally
267
		{fixupSimpleType(aTypeSymbol);}
268
269
270
271
272
273
274
ooActionSystem
275
	returns [OoActionSystemType aTypeSymbol]
276
	@init{
277
		bool autoCons = false;
278
		aTypeSymbol = null;
279
		refinesSystemName = null;
280
	}
281
	:      (T_AUTOCONS {autoCons = true;})?
282
		T_SYSTEM (T_LPAREN refinesSystemName=T_IDENTIFIER T_RPAREN)?
283
		{aTypeSymbol = createOoaType(refinesSystemName,autoCons);}
284
		'|['
285
			(T_VAR attrList)?
286
			(T_METHODS methodList)?
287
			(T_ACTIONS namedActionList)?
288
			(T_DO (bl=actionBlock[null] {addActionBlock(aTypeSymbol,bl);})? T_OD)?
289
		']|'
290
	;
291
	finally
292
		{fixupOoaType(aTypeSymbol);}
293
294
295
296
297
//
298
//  ------------   variables (objects and simple types)    ------------
299
//
300
attrList
301
	:	{BeginParsingAttributes();}
302
	 	attr (T_SEMICOLON attr)*
303
	;
304
	finally {
305
		EndParsingAttributes();
306
	}
307
308
attr
309
	@init{
310
		bool isStatic = false;
311
		bool isCtr = false;
312
		bool isObs = false;
313
314
	}
315
	: 	(T_STATIC {isStatic = true;})? (T_OBS {isObs = true;} | T_CTRL {isCtr = true;})?
316
		varname=T_IDENTIFIER  T_COLON aType=complexType (T_EQUAL anExpr=expression)?
317
		{createAttribute(varname, isStatic, isObs, isCtr, aType, anExpr);}
318
	;
319
320
//
321
//  ------------   methods    ------------
322
//
323
methodList
324
	: 	method (T_SEMICOLON method)*
325
	;
326
327
method
328
	@init {
329
		FunctionIdentifier newMethod = null;
330
	}
331
	:	mname=T_IDENTIFIER  {newMethod = createMethodSymbol(mname);}
332
		(T_LPAREN methodParameterList[newMethod]  T_RPAREN)?
333
		(T_COLON rt=complexType {setMethodReturnType(newMethod,rt);})?	// actions can not have a return type!!
334
		 T_EQUAL
335
		 (T_VAR localActionVars[newMethod] 'begin')?
336
		statements=actionBody[null] {addMethodBody(newMethod,statements);}
337
		T_END
338
	;
339
	finally
340
		{popResolveStack(newMethod);}
341
342
methodParameterList[FunctionIdentifier newMethod]
343
	:	 paramName=T_IDENTIFIER T_COLON atype=complexType {addMethodParameter(newMethod,paramName,atype);}
344
			(T_COMMA otherparam=T_IDENTIFIER T_COLON othertype=complexType
345
			{addMethodParameter(newMethod,otherparam,othertype);} )*
346
	;
347
348
349
//
350
//  ------------   named, anonymous actions    ------------
351
//
352
353
namedActionList
354
	:	namedAction (T_SEMICOLON namedAction)*
355
	;
356
357
namedAction
358
	@init {
359
		FunctionTypeEnum actionType;
360
		FunctionIdentifier newAction = null;
361
	}
362
	:	T_CONT cactionname=T_IDENTIFIER  {newAction = createNamedContinuousAction(cactionname, FunctionTypeEnum.Continuous);}
363
		(T_LPAREN methodParameterList[newAction]  T_RPAREN)?
364
		T_EQUAL	constraints=continuousActionBody {addContinuousActionBody(newAction,constraints);}
365
366
	|	{actionType = FunctionTypeEnum.Internal;}
367
		(T_CTRL {actionType = FunctionTypeEnum.Controllable;}| T_OBS {actionType = FunctionTypeEnum.Observable;}| )
368
		 actionname=T_IDENTIFIER  {newAction = createNamedAction(actionname,actionType);}
369
		(T_LPAREN methodParameterList[newAction]  T_RPAREN)?
370
		T_EQUAL
371
		(T_VAR localActionVars[newAction] )?
372
		body=discreteActionBody
373
		{addActionBody(newAction,body);}
374
	;
375
	finally
376
		{popResolveStack(newAction);}
377
378
379
localActionVars[FunctionIdentifier newMethod]
380
	:	// a named, discrete action may have local variables.
381
		id1=T_IDENTIFIER T_COLON t1=complexType  {addLocalVariableToNamedAction(newMethod,id1,t1);}
382
		 (T_SEMICOLON id2=T_IDENTIFIER T_COLON t2=complexType
383
		 {addLocalVariableToNamedAction(newMethod,id2,t2);} )*
384
	;
385
386
387
388
anonymousAction
389
	returns [GuardedCommand result]
390
	:	a=continuousActionBody {result = a;}
391
	|	b=discreteActionBody {result = b;}
392
	;
393
394
continuousActionBody
395
	returns [GuardedCommand result]
396
	@init {
397
		result = null;
398
	}
399
	:	T_CONT T_REQUIRES expr=expression T_COLON
400
			bdy=qualConstraintList
401
		T_END
402
		{result = createGuardedCommandStatement(expr,bdy,true);}
403
	;
404
405
qualConstraintList
406
	returns [Block result]
407
	@init{
408
		result = createSeqBlock(null);
409
		pushBlockToResolveStack(result);
410
	}
411
	:	stmt=qualConstraint {addToBlockList(result,stmt);}
412
		(T_COMMA ostmt=qualConstraint {addToBlockList(result,ostmt);})*
413
	;
414
	finally
415
		{popBlockFromResolveStack(result);}
416
417
418
419
qualConstraint
420
	returns [QualitativeConstraintStatement result]
421
	:	id1=T_IDENTIFIER T_EQUAL
422
		(	T_DERIV derivid=T_IDENTIFIER
423
			{result = createQualDerivConstraintStatement(id1,derivid);}
424
425
	        |
426
	        	id2=T_IDENTIFIER
427
	        	(
428
	        		(	op=T_SUM
429
	        		|	op=T_DIFF
430
	        		|	op=T_PROD
431
	        		)
432
	        		id3=T_IDENTIFIER
433
	        		{result = createQualArithConstraintStatement(id1,id2,id3,op);}
434
	        	|
435
	        		{result = createQualEqualConstraintStatement(id1,id2);}
436
	        	)
437
	        )
438
	;
439
440
441
442
443
discreteActionBody
444
	returns [GuardedCommand result]
445
	@init{
446
		result = null;
447
	}
448
	:
449
		T_REQUIRES expr=expression T_COLON
450
			bdy=actionBody[null]
451
		T_END
452
		{result = createGuardedCommandStatement(expr,bdy);}
453
	;
454
455
456
//
457
//  ------------   do-od block    ------------
458
//
459
460
actionBlock [Block top]
461
	returns [Block prioList]
462
	:  	{prioList = createPrioBlock(top);}
463
		 actionBlockParallel[prioList] (T_PRIO actionBlockParallel[prioList])*
464
	;
465
466
actionBlockParallel [Block top]
467
	:  	{Block parList = createNondetBlock(top);}
468
		actionBlockSequential[parList] (T_NONDET actionBlockSequential[parList])*
469
	;
470
471
// atomic sequential composition of actions
472
actionBlockSequential [Block top]
473
	@init  	{
474
			Block seqList = createSeqBlock(top);
475
			pushBlockToResolveStack(seqList);
476
		}
477
	:	 (T_VAR syms=blockvarlist[seqList] ('&' sexpr=expression {addSeqBlockExpression(seqList,sexpr);} )? T_COLON )?
478
		 actionBlockParen[seqList] (T_SEMICOLON actionBlockParen[seqList])*
479
	;
480
	finally
481
		{popBlockFromResolveStack(seqList);}
482
483
actionBlockParen [Block top]
484
	:	T_LPAREN actionBlock[top] T_RPAREN
485
	|	anonymousOrNamedAction[top]
486
	;
487
488
anonymousOrNamedAction [Block top]
489
	:	gcmd=anonymousAction {addToBlockList(top,gcmd);}
490
	|	aname=T_IDENTIFIER
491
	         (T_LPAREN  m_params=methodCallParams T_RPAREN)?
492
	         (amap=(T_FOLDLR|T_FOLDRL) '(' amapexpr=expression ')')?
493
		{addNamedActionCallToBlockList(top,aname,m_params,amap,amapexpr);}
494
	|	T_SKIP	{addSkipStatementToBlockList(top);}
495
	;
496
497
498
blockvarlist [Block seqList]
499
	:	blockvar[seqList]  (T_SEMICOLON blockvar[seqList] )*
500
	;
501
502
blockvar [Block seqList]
503
	: 	varname=T_IDENTIFIER  T_COLON aType=complexType
504
		{addBlockVariable(seqList,varname,aType);}
505
	;
506
507
508
509
//
510
//  ------------  action body  of non-continuous actions ------------
511
//
512
513
actionBody[Block top]
514
	returns [Block result]
515
	:	{result = createPrioBlock(top);}
516
		actionBodyParallel[result] (T_PRIO actionBodyParallel[result])?
517
	;
518
519
actionBodyParallel[Block top]
520
	returns [Block result]
521
	:	{result = createNondetBlock(top);}
522
		actionBodySequential[result]
523
		(T_NONDET olst=actionBodySequential[result])*
524
	;
525
526
// seq binds stronger than nondet, i.e. a;b;cd;e is read as (a;b;c)[](d;e)
527
actionBodySequential[Block top]
528
	returns [Block result]
529
	:	{result = createSeqBlock(top);}
530
		actionBodyParen[result] (T_SEMICOLON actionBodyParen[result])*
531
	;
532
533
actionBodyParen [Block top]
534
	:	T_LPAREN actionBody[top] T_RPAREN
535
	|	stmt=statement
536
		{addToStatementList(top,stmt);}
537
	;
538
539
540
statement
541
	returns [Statement result]
542
	@init {
543
		bool popFromResolveStack = false;
544
		result = null;
545
	}
546
	:	T_ABORT {result = createAbortStatement();}
547
	|	T_SKIP	{result = createSkipStatement();}
548
	|	T_KILL T_LPAREN aname=(T_IDENTIFIER | T_SELF) T_RPAREN	{result = createKillStatement(aname);}
549
	| 	gc=discreteActionBody {result = gc;}
550
	|	aqname=reference
551
			   ( 	    // single assignment
552
			   	    T_ASSIGNMENT  aexp=expression  {result = createSingleAssignmentStatement(aqname,aexp);}
553
			           (T_WITH ndexp=expression {addConstraintToAssignment(result,ndexp);})? // nondet assignment
554
555
			           // multi assignment
556
				|  {result = createMultipleAssignmentStatementLHS(aqname);}
557
				  (T_COMMA malhs=reference  {addMultipleAssignmentStatementLHS(result,malhs);})+
558
				   T_ASSIGNMENT
559
				   {pushAssignmentOnResolveStack(result); popFromResolveStack = true;}
560
				   mexp=expression
561
				   {addMutlipleAssignmentStatementRHS(result,mexp);}
562
				   (T_COMMA mexp2=expression {addMutlipleAssignmentStatementRHS(result,mexp2);})+
563
				   (T_WITH ndex2=expression {addConstraintToAssignment(result,ndex2);})? // nondet assignment
564
565
				   // just a call of a method.
566
				| {result = createCallStatement(aqname);}
567
		     	    )
568
	;
569
	finally {
570
	       if (popFromResolveStack == true)
571
	            popAssignmentOffResolveStack(result);
572
	}
573
574
//
575
//  ------------   expression    ------------
576
//
577
expression
578
	returns [Expression expr]
579
	@init{
580
		System.Collections.Generic.List<BinaryOperator> operators = new System.Collections.Generic.List<BinaryOperator>();
581
		System.Collections.Generic.List<Expression> expressions = new System.Collections.Generic.List<Expression>();
582
	}
583
	:	left=atomExpression
584
		{expressions.Add(left);}
585
		( op=binoperator
586
		  right=atomExpression
587
		  {
588
		  	operators.Add(op);
589
		  	expressions.Add(right);
590
		  }
591
		)*
592
		{expr = createPrecedenceTree(expressions,operators);}
593
	;
594
595
596
binoperator
597
	returns [BinaryOperator binop]
598
	:	T_BIIMPLIES
599
		{binop = createBinaryOperator(ExpressionKind.biimplies);}
600
	|	T_GREATER
601
		{binop = createBinaryOperator(ExpressionKind.greater);}
602
	|	T_GREATEREQUAL
603
		{binop = createBinaryOperator(ExpressionKind.greaterequal);}
604
	|	T_LESS
605
		{binop = createBinaryOperator(ExpressionKind.less);}
606
	|	T_LESSEQUAL
607
		{binop = createBinaryOperator(ExpressionKind.lessequal);}
608
	|	T_EQUAL			// bool, numeric, char, lists, maps
609
		{binop = createBinaryOperator(ExpressionKind.equal);}
610
	|	T_NOTEQUAL		// bool, numeric, char, lists, maps
611
		{binop = createBinaryOperator(ExpressionKind.notequal);}
612
	|	T_IMPLIES
613
		{binop = createBinaryOperator(ExpressionKind.implies);}
614
	|	T_MINUS
615
		{binop = createBinaryOperator(ExpressionKind.minus);}
616
	|	T_SUM
617
		{binop = createBinaryOperator(ExpressionKind.sum);}
618
	|	T_IN T_SET?	// A * list of A -> bool
619
		{binop = createBinaryOperator(ExpressionKind.elemin);}
620
	|	T_NOT T_IN T_SET?	// A * list of A -> bool
621
		{binop = createBinaryOperator(ExpressionKind.notelemin);}
622
	|	T_SUBSET	// list of A * list of A -> bool (does not respect dupes)
623
		{binop = createBinaryOperator(ExpressionKind.subset);}
624
	|	T_OR
625
		{binop = createBinaryOperator(ExpressionKind.or);}
626
	|	T_DIV
627
		{binop = createBinaryOperator(ExpressionKind.div);}
628
	|	T_PROD
629
		{binop = createBinaryOperator(ExpressionKind.prod);}
630
	|	T_IDIV
631
		{binop = createBinaryOperator(ExpressionKind.idiv);}
632
	|	T_MOD
633
		{binop = createBinaryOperator(ExpressionKind.mod);}
634
	|	T_UNION		// list of A * list of A -> list of A (does not respect dupes)
635
		{binop = createBinaryOperator(ExpressionKind.union);}
636
	|	T_DIFF		// list of A * list of A -> list of A (does not respect dupes)
637
		{binop = createBinaryOperator(ExpressionKind.diff);}
638
	|	T_INTER		// list of A * list of A -> list of A (does not respect dupes)
639
		{binop = createBinaryOperator(ExpressionKind.inter);}
640
	|	T_AND
641
		{binop = createBinaryOperator(ExpressionKind.and);}
642
	|	T_POW
643
		{binop = createBinaryOperator(ExpressionKind.pow);}
644
	|	T_CONC	// list of A * list of A -> list of A
645
		{binop = createBinaryOperator(ExpressionKind.conc);}
646
	|	T_DOMRESBY	// list of A * map A to B -> map A to B
647
		{binop = createBinaryOperator(ExpressionKind.domresby);}
648
	|	T_DOMRESTO	// list of A * map A to B -> map A to B
649
		{binop = createBinaryOperator(ExpressionKind.domresto);}
650
	|	T_RNGRESBY	// map A to B * list of B -> map A to B
651
		{binop = createBinaryOperator(ExpressionKind.rngresby);}
652
	|	T_RNGRESTO	// map A to B * list of B -> map A to B
653
		{binop = createBinaryOperator(ExpressionKind.rngresto);}
654
	|	T_MUNION	// map A to B * map A to B -> map A to B
655
		{binop = createBinaryOperator(ExpressionKind.munion);}
656
	|	T_SEQMOD_MAPOVERRIDE	// list of A * map int to A -> list of A or
657
					// map A to B * map A to B -> map A to B
658
		{binop = createBinaryOperator(ExpressionKind.seqmod_mapoverride);}
659
	;
660
661
662
atomExpression
663
	returns [Expression expr]
664
	@init {
665
		expr = null;
666
	}
667
	:	(unexpr=op_un? (
668
		     e=identifierExpression
669
		  |  e=qvalExpression
670
		  |  e=constant
671
		  |  e=initializedComplexType
672
		  |  e=quantifierExpression
673
		  |  T_LPAREN e=expression T_RPAREN
674
		     (
675
			  (T_POINT
676
			    idn=T_IDENTIFIER
677
			    {e = addIdentifierAccessExpression(e,idn);})+
678
			    (res=accessExpression[e] {e=res;})?
679
			|
680
			  e=accessExpression[e]
681
		      )?
682
		) ('as' cid=T_IDENTIFIER {e=addCastExpression(e,cid);})?
683
		{expr = addUnaryExpression(unexpr,e);}
684
		)
685
		|  ie=T_IF ce=expression T_THEN te=expression T_ELSE ee=expression T_END
686
		{expr = createConditionalExpression(ce,te,ee,ie);}
687
	;
688
689
690
quantifierExpression
691
	returns [Quantifier result]
692
	@init {
693
		result = null;
694
	}
695
	: 	t=(T_FORALL | T_EXISTS)
696
		{result = createQuantifierExpression(t);}
697
		(id=T_IDENTIFIER (T_COLON id_type=simpleType {addBoundVarToQuantifierExpression(result,id,id_type);})
698
		  (T_COMMA id2=T_IDENTIFIER (T_COLON id_type2=simpleType){addBoundVarToQuantifierExpression(result,id2,id_type2);})*)
699
		T_COLON T_LPAREN e=expression T_RPAREN
700
		{addExpressionToQuantifier(result,e);}
701
	;
702
	finally
703
		{removeBoundVarsFromResolveStack(result);}
704
705
constant
706
	returns [LeafExpression result]
707
	@init {
708
		result = null;
709
	}
710
	: 	T_TRUE  {result = createBoolConstant(true);}
711
	|	T_FALSE {result = createBoolConstant(false);}
712
	|	T_NIL 	{result = createNullPointerConstant();}
713
	|	T_SELF  {result = createSelfPointer();}
714
	| 	t_fl=T_FLOATNUMBER {result = createFloatConstant(t_fl);}
715
	|	t_in=T_INTNUMBER {result = createIntConstant(t_in);}
716
	|	t_l=T_STRINGLITERAL {result = createStringConstant(t_l);}
717
	;
718
719
initializedComplexType
720
	returns [Expression result]
721
	@init {
722
		result = null;
723
	}
724
	:	res=initializedListType {result = res;}
725
	|	res=initializedSetType {result = res;}
726
	| 	T_NEW T_LPAREN anid=T_IDENTIFIER
727
			(
728
				T_COMMA  aname=T_STRINGLITERAL T_RPAREN {result = createNamedObject(anid, aname);}
729
			|	T_RPAREN {result = createObject(anid);}	// constructor call..
730
			)
731
	;
732
733
initializedListType
734
	returns [ListConstructor result]
735
	@init {
736
		result = createInitializedList();
737
		pushListVarsOnResolveStack(result); // need this here for list comprehension
738
	}
739
	:	T_LSQPAREN e=expression {addListElement(result,e);} (
740
			(T_COMMA e2=expression {addListElement(result,e2);})+
741
		| 	listComprehension[result]
742
		)? T_RSQPAREN
743
	;
744
	finally
745
		{popListVarsFromResolveStack(result);}
746
747
listComprehension [ListConstructor result]
748
	@init{
749
		result.SetHasComprehension(true);
750
	}
751
	:
752
		T_BAR T_VAR
753
		id=T_IDENTIFIER  T_COLON t1=complexType {addListComprVar(result,id,t1);}
754
			(T_SEMICOLON id2=T_IDENTIFIER  t2=complexType {addListComprVar(result,id2,t2);})*
755
		('&'
756
		e=expression {addListComprExpr(result,e);})?
757
	;
758
759
initializedSetType
760
	returns[Expression result]
761
	@init {
762
		result = null;
763
	}
764
	:	T_CBRL T_MAPS T_CBRR {result = createEmptyMap();}  // empty map
765
	|	res=initializedSet {result = res;}
766
	;
767
768
initializedSet
769
	returns [Expression result]
770
	@init {
771
		SetConstructor theset = createSet();
772
		pushSetVarsOnResolveStack(theset); // need this here for set comprehension
773
		result = theset;
774
	}
775
	:	T_CBRL e1=expression
776
	        (    			// set constructor; empty set: {nil}
777
			{addToSet(result,e1);}
778
			(T_COMMA e2=expression {addToSet(result,e2);})*			  // set constructor for sets > 1 elem
779
		| 	m=map[result, e1] {result = m;}  // we have a set in the resolution stack, but this should be fine (no syms)
780
		|	{addToSet(result,e1);} setComprehension[(SetConstructor)result]   // set comprehension
781
		) T_CBRR
782
	;
783
	finally
784
		{popSetVarsFromResolveStack(theset);}
785
786
787
map[Expression _map, Expression e1]
788
	returns [Expression result]
789
	@init {
790
		result = null;
791
	}
792
	:	am=T_MAPS e2=expression  {result = createMap(e1,e2,am);}   (T_COMMA e3=expression T_MAPS e4=expression {addToMap(result,e3,e4);})*
793
	;
794
795
setComprehension[SetConstructor _set]
796
	@init {
797
		_set.SetHasComprehension(true);
798
	}
799
	:	T_BAR T_VAR (id1=T_IDENTIFIER  T_COLON t1=complexType
800
		{ addSetComprVar(_set, id1, t1); }
801
		T_SEMICOLON id2=T_IDENTIFIER T_COLON t2=complexType
802
		 { addSetComprVar(_set, id2, t2); })*
803
		('&'
804
		epx=expression
805
		{ addSetComprExpr(_set,epx); })?
806
	;
807
808
809
qvalExpression
810
	returns [QValConstructor result]
811
	@init {
812
		bool minus = false;
813
		result = null;
814
	}
815
	:	// constructor for qualitative values
816
		aval='qval' T_LPAREN
817
		{result = createQualitativeValue(aval);}
818
		(
819
			T_NIL
820
			{setQualitativeValueDontCare(result);}
821
		|
822
			(	expr=qualifiedIdentifier
823
			 	{setQualitativeValueLandmark(result,expr);}
824
			|
825
				('-' {minus = true;})? T_INFTY
826
				{setQualitativeValueInfinity(result,minus);}
827
			)
828
			(T_RANGETO
829
			(	expr2=qualifiedIdentifier
830
				{setQualitativeValueRange(result,expr2);}
831
			|
832
				T_INFTY
833
				{setQualitativeValueRangeInfinity(result,false);}
834
			) )?
835
		)
836
		T_COMMA
837
		(
838
			T_NIL
839
			{setQualitativeDerivDontCare(result);}
840
		|
841
			(	'steady'
842
				{setQualitativeDerivSteady(result);}
843
			|	'inc'
844
				{setQualitativeDerivInc(result);}
845
			|	'dec'
846
				{setQualitativeDerivDec(result);}
847
			)
848
		)
849
		T_RPAREN
850
	;
851
852
853
identifierExpression
854
	returns [Expression result]
855
	:  	// if next token is a tuple-type then create an initialized tuple!
856
		{isTuple(input.LT(1).Text)}?
857
		aName=T_IDENTIFIER T_LPAREN m_params=methodCallParams T_RPAREN
858
		{result = createInitializedTuple(aName,m_params);}
859
	| 	// is some sort of reference
860
		res=reference
861
	  	{result = res;}
862
	;
863
864
865
reference
866
	returns [Expression  result]
867
	@init {
868
		result = null;
869
		init = null;
870
	}
871
	:	{!isTuple(input.LT(1).Text)}? // check that the next token is not a reference to a tuple-type
872
		aName=qualifiedIdentifier {result = aName;}
873
		(	output=accessExpression[result] {result = output;}
874
			// call expression
875
		|	// variable access or method call that takes no params? (do we allow for that? - answer: no!)
876
		)
877
		( 	pr=T_PRIMED {setIdentifierExpressionPrimed(ref result,pr);}
878
		 |
879
		 	('::' T_LPAREN init=expression T_RPAREN)? afold=(T_FOLDLR|T_FOLDRL) T_LPAREN anexpr=expression T_RPAREN
880
		 	{result = createFoldExpression(result,afold,init,anexpr);}
881
		)?
882
	;
883
884
accessExpression[Expression subexpr]
885
	returns [Expression result]
886
	@init{
887
		UnaryOperator newExpr = null;
888
		result = subexpr;
889
	}
890
	:
891
    		(	tcall=T_LSQPAREN ac=expression T_RSQPAREN 			// access tuples, maps
892
    			{ result = createTupleMapAccessExpression(result,ac,tcall); }
893
		|     	bcall=T_LPAREN m_params=methodCallParams T_RPAREN // access method
894
			{ result = createMethodAccessExpression(result,m_params,bcall); }
895
		)+
896
		(	// a[1].c.e()...
897
			(T_POINT
898
			idn=T_IDENTIFIER
899
			{result = addIdentifierAccessExpression(result,idn);})+
900
			(res=accessExpression[result] {result=res;})?
901
		)?
902
	;
903
904
qualifiedIdentifier
905
	returns [Expression top]
906
	@init {
907
		IdentifierExpression selfexpr = null;
908
		top = null;
909
	}
910
	:
911
		(self=T_SELF T_POINT		{selfexpr = createSelfIdentifierExpression(self);})?
912
		idb=T_IDENTIFIER 		{top = createIdentifierAccessExpression(selfexpr,idb);}
913
		(T_POINT idd=T_IDENTIFIER 	{top = addIdentifierAccessExpression(top,idd);})*
914
	;
915
916
917
methodCallParams
918
	returns [System.Collections.Generic.List<Expression> result]
919
	@init {
920
		result = new System.Collections.Generic.List<Expression>();
921
	}
922
	:	(expa=expression {result.Add(expa);} (T_COMMA expb=expression {result.Add(expb);})*)?
923
	;
924
925
926
927
//
928
//  ------------  unary  Operators    ------------
929
//
930
931
932
op_un
933
	returns [UnaryOperator expr]
934
	@init {
935
		expr = null;
936
	}
937
	:	r=op_un_set_list {expr = r;}
938
	|	r2=op_un_map 	{expr = r2;}
939
	|	T_MINUS 	{expr = createUnaryOperator(ExpressionKind.unminus);}
940
	|	T_NOT		{expr = createUnaryOperator(ExpressionKind.not);}
941
	|	T_ABS		{expr = createUnaryOperator(ExpressionKind.abs);}
942
	;
943
944
945
op_un_set_list
946
	returns [UnaryOperator expr]
947
	@init {
948
		expr = null;
949
	}
950
	:	T_CARD		// list of A -> int (does not respect dupes, i.e. dupes do not count)
951
		{expr = createUnaryOperator(ExpressionKind.card);}
952
	|	T_DCONC		// list of list of A -> list of A
953
		{expr = createUnaryOperator(ExpressionKind.dconc);}
954
	|	T_DINTER	// list of list of A -> list of A (intersection, does not respect dupes)
955
		{expr = createUnaryOperator(ExpressionKind.dinter);}
956
	|	T_DUNION	// list of list of A -> list of A (union, does not respect dupes)
957
		{expr = createUnaryOperator(ExpressionKind.dunion);}
958
	|	T_ELEMS		// list of A -> list of A (does not respect dupes)
959
		{expr = createUnaryOperator(ExpressionKind.elems);}
960
	|	T_HEAD		// list of A -> A
961
		{expr = createUnaryOperator(ExpressionKind.head);}
962
	|	T_INDS		// list of A -> list of int
963
		{expr = createUnaryOperator(ExpressionKind.inds);}
964
	|	T_LEN		// list of A -> int (dupes count)
965
		{expr = createUnaryOperator(ExpressionKind.len);}
966
	|	T_TAIL		// list of A -> list of A
967
		{expr = createUnaryOperator(ExpressionKind.tail);}
968
	;
969
970
971
op_un_map
972
	returns [UnaryOperator expr]
973
	@init {
974
		expr = null;
975
	}
976
	:	T_DOM		// map A to B -> list of A
977
		{expr = createUnaryOperator(ExpressionKind.dom);}
978
	|	T_RNG		// map A to B -> list of B
979
		{expr = createUnaryOperator(ExpressionKind.range);}
980
	|	T_MERGE		// list of map A to B -> map A to B
981
		{expr = createUnaryOperator(ExpressionKind.merge);}
982
	;
983
984
985
986
987
988
989
//
990
//  ==============   LEXER   =================
991
//
992
T_WS  	: (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}
993
    	;
994
995
T_COMMENT
996
    	: '/*' .* '*/' {$channel=HIDDEN;}
997
    	;
998
999
LINE_COMMENT
1000
    	: '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
1001
    	;
1002
1003
T_PRIMED
1004
	:	'\'';
1005
1006
T_STRINGLITERAL
1007
	:	'"'
1008
		(
1009
     			( '"' '"' )=>  '"'
1010
      		|  	~'"'
1011
  		)*
1012
 		'"'
1013
	;
1014
1015
1016
T_ABORT	:	'abort';
1017
T_ACTIONS
1018
	:	'actions';
1019
T_ASSIGNMENT
1020
	:	':=';
1021
T_AUTOCONS:	'autocons';
1022
T_BAR	:	'|';
1023
T_BOOL	:	'bool';
1024
T_CBRL	:	'{';
1025
T_CBRR	:	'}';
1026
T_COLON	:	':';
1027
T_COMMA	:	',';
1028
T_CONT	:	'qual';
1029
T_CHAR	:	'char';
1030
T_CTRL 	:	'ctr';
1031
T_SYSTEM
1032
	:	'system';
1033
T_DO	:	'do';
1034
T_ELSE	:	'else';
1035
T_END	:	'end';
1036
T_EQUAL	:	'=';
1037
T_EXISTS:	'exists';
1038
T_FLOAT	:	'float';
1039
T_FORALL:	'forall';
1040
T_FALSE :	'false';
1041
T_IF	:	'if';
1042
T_IN	:	'in';
1043
T_INT	:	'int';
1044
T_KILL	:	'kill';
1045
T_LIST	:	'list';
1046
T_LPAREN:	'(';
1047
T_LSQPAREN:	'[';
1048
T_MAP	:	'map';
1049
T_MAPS	:	'->';
1050
T_METHODS
1051
	:	'methods';
1052
T_NEW	:	'new';
1053
T_NIL	:	'nil';
1054
T_NONDET:	'[]';
1055
T_OBS	:	'obs';
1056
T_OD	:	'od';
1057
T_OF	:	'of';
1058
T_PRIO	:	'//';
1059
T_REQUIRES
1060
	:	'requires';
1061
T_RPAREN:	')';
1062
T_RSQPAREN:	']';
1063
T_QUANTITY
1064
	:	'qspace';
1065
T_SELF	:	'self';
1066
T_SET 	:	'set';
1067
T_SEMICOLON
1068
	:	';';
1069
T_STATIC:	'static';
1070
T_SKIP	:	'skip';
1071
T_THEN	:	'then';
1072
T_TRUE  :	'true';
1073
T_TO	:	'to';
1074
T_TYPES	:	'types';
1075
T_VAR	:	'var';
1076
T_WITH	:	'with';     // for nondet assignment
1077
1078
1079
//T_ACTION:	'action';
1080
1081
//BOOL
1082
T_AND	:	'and';
1083
T_BIIMPLIES
1084
	:	'<=>';
1085
T_IMPLIES
1086
	:	'=>';  //VDM-Style
1087
T_NOT	:	'not'; //VDM-Style
1088
T_NOTEQUAL:	'<>';  //VDM-Style
1089
T_OR	:	'or';
1090
1091
//Numeric (equal, not equal same as in BOOL)
1092
T_ABS	:	'abs';
1093
T_DIV	:	'/';
1094
T_GREATER
1095
	:	'>';
1096
T_GREATEREQUAL
1097
	:	'>=';
1098
T_IDIV	:	'div';
1099
T_LESS	:	'<';
1100
T_LESSEQUAL
1101
	:	'<='; //VDM-Style
1102
T_MOD	:	'mod'; //VDM-Style
1103
T_POW	:	'**';
1104
T_PROD	:	'*';
1105
T_DERIV	:	'dt';
1106
1107
// set/list
1108
T_CARD	:	'card';
1109
T_CONC	:	'^';
1110
T_DCONC	:	'conc';
1111
T_DIFF	:	'\\';
1112
T_DINTER:	'dinter';
1113
T_DUNION:	'dunion';
1114
T_ELEMS	:	'elems';
1115
T_HEAD	:	'hd';
1116
T_INDS	:	'inds';
1117
T_INTER	:	'inter';
1118
T_LEN	:	'len'; // differs from T_CARD, as card does not count dupes..
1119
T_SEQMOD_MAPOVERRIDE
1120
	:	'++';
1121
T_SUBSET:	'subset';
1122
T_TAIL	:	'tl';
1123
T_UNION	:	'union';
1124
T_FOLDLR
1125
	:	':>:';
1126
T_FOLDRL
1127
	:	':<:';
1128
1129
1130
// maps
1131
T_DOM	:	'dom';
1132
T_DOMRESBY
1133
	:	'<-:';
1134
T_DOMRESTO
1135
	:	'<:';
1136
T_RNG	:	'rng';
1137
T_RNGRESBY
1138
	:	':->';
1139
T_RNGRESTO
1140
	:	':>';
1141
T_MERGE	:	'merge';
1142
T_MUNION:	'munion';
1143
1144
T_CONSTS:	'consts';
1145
1146
// numbers
1147
1148
T_INFTY	:	(T_MINUS|T_SUM)? 'inf'
1149
	;
1150
1151
1152
// INTNUMBER, FLOATNUMBER, RANGETO, T_MINUS, T_PLUS are set within
1153
// FLOAT_OR_INT_OR_RANGE
1154
fragment T_INTNUMBER
1155
	:	;
1156
fragment T_FLOATNUMBER
1157
	:	;
1158
fragment T_RANGETO
1159
	:	;
1160
1161
FLOAT_OR_INT_OR_RANGE
1162
	: 	(T_MINUS|T_SUM)? T_DIGIT+
1163
		( // at this stage, we could face an int, int..int (=range), int.exp (=float), int.exp..int.exp (=float range) etc..
1164
				(T_POINT T_POINT) => {$type=T_INTNUMBER;}
1165
			|	(T_POINT T_DIGIT) => T_POINT T_DIGIT+ (('e'|'E') (T_MINUS|T_SUM)? T_DIGIT+)? {$type=T_FLOATNUMBER;}
1166
			|	{$type=T_INTNUMBER;}
1167
		)
1168
	|	T_POINT
1169
		( // could be point or range..
1170
				T_POINT {$type=T_RANGETO;}
1171
			| 	      {$type=T_POINT;}
1172
		)
1173
	|	T_MINUS	{$type=T_MINUS;}
1174
	|	T_SUM	{$type=T_SUM;}
1175
	;
1176
1177
1178
1179
fragment T_MINUS:	'-';
1180
fragment T_SUM	:	'+';
1181
fragment T_POINT:	'.';
1182
1183
1184
1185
// identifiers
1186
T_IDENTIFIER
1187
	:	T_LETTER (T_LETTER|T_DIGIT)*
1188
	;
1189
1190
//T_PRIMEDIDENTIFIER
1191
//	:	T_IDENTIFIER '\'';
1192
1193
fragment
1194
T_LETTER
1195
	:	'$'
1196
	|	'A'..'Z'
1197
	|	'a'..'z'
1198
	|	'_'
1199
	;
1200
1201
fragment
1202
T_DIGIT:	'0'..'9';