Project

General

Profile

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

1
/*  
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';
1203