AF3Expression.g 11.6 KB
Newer Older
Florian Hölzl's avatar
Florian Hölzl committed
1
2
3
4
grammar AF3Expression;

options {
	superClass = AF3ExpressionParserBase ;
5
6
	backtrack=true;
    memoize=true;
Florian Hölzl's avatar
Florian Hölzl committed
7
8
9
10
11
}

@header {
package org.fortiss.af3.expression.model.parser;

Florian Hölzl's avatar
cleanup    
Florian Hölzl committed
12
13
import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.*;

Florian Hölzl's avatar
Florian Hölzl committed
14
15
16
17
18
19
20
import org.fortiss.af3.project.model.typesystem.*;
import org.fortiss.af3.project.model.typesystem.impl.*;

import org.fortiss.af3.expression.model.*;
import org.fortiss.af3.expression.model.definitions.*;
import org.fortiss.af3.expression.model.terms.*;
import org.fortiss.af3.expression.model.terms.imperative.*;
21
import org.fortiss.af3.expression.model.terms.collection.*;
Florian Hölzl's avatar
Florian Hölzl committed
22
23
24
25
26
27
import org.fortiss.af3.expression.model.types.*;

import org.fortiss.af3.expression.model.impl.*;
import org.fortiss.af3.expression.model.definitions.impl.*;
import org.fortiss.af3.expression.model.terms.impl.*;
import org.fortiss.af3.expression.model.terms.imperative.impl.*;
28
import org.fortiss.af3.expression.model.terms.collection.impl.*;
Florian Hölzl's avatar
Florian Hölzl committed
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import org.fortiss.af3.expression.model.types.impl.*;

import java.util.ArrayList;

}

@lexer::header{
package org.fortiss.af3.expression.model.parser;
}

/*
 * @rulecatch disables recovery in ANTLR 3.0
 */
@rulecatch {
43
44
45
46
	catch ( RecognitionException ex ) {
		reportError(ex);
		throw ex;
	}
Florian Hölzl's avatar
Florian Hölzl committed
47
}
48
49


Florian Hölzl's avatar
Florian Hölzl committed
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/

UNDERSCORE : '_' ;

fragment DIGIT 	:	'0'..'9' ;
fragment LOWER	:	'a'..'z';
fragment UPPER	: 	'A'..'Z';

fragment LETTER : LOWER | UPPER ;
fragment ALPHANUM : LETTER | DIGIT | UNDERSCORE;

INTEGER : DIGIT+ ;
DOUBLE    : ( ( DIGIT+ '.' DIGIT* | '.' DIGIT+ ) ( ( 'e' | 'E' ) ( '-' | '+' ) ? DIGIT+ ) ? ) ;

NOVAL : 'NoVal' ;
ID  :   LETTER ALPHANUM* ;
VARID : UNDERSCORE ALPHANUM* ;

// white space
WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ;


/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/

/* 
 * EXPRESSION TERM
 */
termEOF returns [IExpressionTerm result] :
	term EOF {$result = $term.result;};
	
term returns [IExpressionTerm result] :
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
	implication {$result = $implication.term;} ;

//right-associative
implication returns [IExpressionTerm term] :
	(a1=equivalence {$term = $a1.term;})
	( '->' a2=implication 
		{
			$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.OR), 
				FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.NOT), $a1.term), 
				$a2.term);
		}
	)? ;

equivalence returns [IExpressionTerm term] :
	(a1=orTerm {$term = $a1.term;})
	(
		'<->' a2=orTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.EQUAL), $term, $a2.term);}
	)* ;
	
Florian Hölzl's avatar
Florian Hölzl committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
orTerm returns [IExpressionTerm term] :
	(a1=andTerm {$term = $a1.term;})
	(
		'||' a2=andTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.OR), $term, $a2.term);}
	)* ;

andTerm returns [IExpressionTerm term] :
	(b1=equalTerm {$term = $b1.term;})
	(
		'&&' b2=equalTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.AND), $term, $b2.term);}
	)* ;

equalTerm returns [IExpressionTerm term] :
	(c1=compareTerm {$term = $c1.term;})
	(
		'==' c2=compareTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.EQUAL), $term, $c2.term);} |
		'!=' c3=compareTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.NOT_EQUAL), $term, $c3.term);}
	)* ;
	
compareTerm returns [IExpressionTerm term] :
	(s1=addTerm {$term = $s1.term;})
	(
		'<' s2=addTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.LOWER_THAN), $term, $s2.term);} |
		'<=' s3=addTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.LOWER_EQUAL), $term, $s3.term);} |
		'>' s4=addTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.GREATER_THAN), $term, $s4.term); } |
		'>=' s5=addTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.GREATER_EQUAL), $term, $s5.term); }
	)* ;
		
addTerm returns [IExpressionTerm term] :
	(m1=multiplyTerm {$term = $m1.term;})
	(
		'+' m2=multiplyTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.ADD), $term, $m2.term);} |
		'-' m3=multiplyTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.SUBTRACT), $term, $m3.term); }
	)* ;

multiplyTerm returns [IExpressionTerm term] :
140
	(c1=unaryTerm {$term = $c1.term;})
Florian Hölzl's avatar
Florian Hölzl committed
141
	(
142
143
144
		'*' c2=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.MULTIPLY), $term, $c2.term);} |
		'/' c3=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.DIVIDE), $term, $c3.term);} |
		'%' c4=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.MODULO), $term, $c4.term);}
Florian Hölzl's avatar
Florian Hölzl committed
145
146
	)* ; 
	
147
148
149
unaryTerm returns [IExpressionTerm term]
	: funcallTerm {$term = $funcallTerm.result;}
	| '!' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.NOT), $v1.term);}
Vivek Nigam's avatar
Vivek Nigam committed
150
	|  'sin' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.SIN), $v1.term);}
151
152
153
154
155
156
157
158
159
160
	|  'cos' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.COS), $v1.term);}
	|  'tan' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.TAN), $v1.term);}
	|  'asin' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.ASIN), $v1.term);}
	|  'acos' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.ACOS), $v1.term);}
	|  'atan' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.ATAN), $v1.term);}
	|  'sqrt' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.SQRT), $v1.term);}
	|  'round' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.ROUND), $v1.term);}
	|  'abs' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.ABS), $v1.term);}
	|  'floor' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.FLOOR), $v1.term);}
	|  'ceil' v1=unaryTerm {$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.CEIL), $v1.term);}
161
162
163
164
165
	| '-' v1=unaryTerm {
		if ($v1.term instanceof IntConst) {
			$term = IntConstStaticImpl.create(-((IntConst)$v1.term).getValue());
		} else if ($v1.term instanceof DoubleConst) {
			$term = DoubleConstStaticImpl.create(-((DoubleConst)$v1.term).getValue());
Florian Hölzl's avatar
Florian Hölzl committed
166
		} else {
167
			$term = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.NEGATE), $v1.term);
Florian Hölzl's avatar
Florian Hölzl committed
168
		}
169
	  } ;
Florian Hölzl's avatar
Florian Hölzl committed
170
	
171
funcallTerm returns [IExpressionTerm result]
Georgetta Igna's avatar
Georgetta Igna committed
172
	: varidConstTerm  '(' (funcallArgList)? ')' {$result = FunctionCallStaticImpl.create(UserdefinedFunctionStaticImpl.create($varidConstTerm.text)); if ($funcallArgList.result != null) {((FunctionCall)$result).getArguments().addAll($funcallArgList.result);}}
173
	| primaryTerm {$result = $primaryTerm.result;}
174
175
		( '.' varidConstTerm {$result = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.MEMBER), $result, $varidConstTerm.result);}
		| '[' term ']' {$result = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.INDEX), $result, $term.result);}
176
		)*
177
	;
Florian Hölzl's avatar
Florian Hölzl committed
178

179
180
181
182
183
primaryTerm returns [IExpressionTerm result]
	: groundTerm {$result = $groundTerm.result;}
	| '(' term ')' {$result = $term.result;}
	;
	
Florian Hölzl's avatar
Florian Hölzl committed
184
185
186
187
188
189
funcallArgList returns [List<IExpressionTerm> result] :
	{$result = new ArrayList<IExpressionTerm>();}
	t1=term {$result.add($t1.result);}
	(
		',' t2=term {$result.add($t2.result);}
	)* ;
190
191
192
193
194
195
196
197
198
		
groundTerm returns [IExpressionTerm result] :
	NOVAL { $result = DefinedConstStaticImpl.create("NoVal"); } |
	varidConstTerm {$result = $varidConstTerm.result; } |
	integerConstTerm {$result = $integerConstTerm.result; } |
	doubleConstTerm {$result = $doubleConstTerm.result; } |
	booleanConstTerm {$result = $booleanConstTerm.result; } |
	structConstTerm {$result = $structConstTerm.result; } |
	arrayConstTerm {$result = $arrayConstTerm.result; };
Florian Hölzl's avatar
Florian Hölzl committed
199
200
201
202
203
204
205
206
207
208
209
210
211
212
	
booleanConstTerm returns [IExpressionTerm result] :
	'true' {$result = BoolConstStaticImpl.create(true); } |
	'false' {$result = BoolConstStaticImpl.create(false); } ;

integerConstTerm returns [IExpressionTerm result] :
	INTEGER { $result = IntConstStaticImpl.create(Integer.parseInt($INTEGER.text)); } ;

doubleConstTerm returns [IExpressionTerm result] :
	DOUBLE { $result = DoubleConstStaticImpl.create(Double.parseDouble($DOUBLE.text)); } ;   

varidConstTerm returns [Var result] :
	VARID { $result = VarStaticImpl.create($VARID.text); } |
	ID { $result = VarStaticImpl.create($ID.text); } ;
213
	
214
215
structConstTerm returns [IExpressionTerm result]
	: {$result = StructureConstStaticImpl.create();}
Vincent Aravantinos's avatar
Vincent Aravantinos committed
216
217
	  '{' (id1=ID ':' term1=term {((StructureConst)$result).getMembers().add(create($id1.text, $term1.result)); })
	  (',' id2=ID ':' term2=term {((StructureConst)$result).getMembers().add(create($id2.text, $term2.result)); })*
218
	  '}';
219
220
221
222

arrayConstTerm returns [IExpressionTerm result] :
	{$result = ArrayConstStaticImpl.create();}
	'[' 
Georgetta Igna's avatar
Georgetta Igna committed
223
224
	(term1=term {((ArrayConst)$result).getValues().add($term1.result); })
	(',' term2=term {((ArrayConst)$result).getValues().add($term2.result); })*
225
226
	']';
	
227
nativeJavaInt returns [int result] :
228
229
	'-' a=INTEGER { $result = -Integer.parseInt($a.text); }
	| '+'? a=INTEGER {  $result = Integer.parseInt($a.text); };
230
	
Florian Hölzl's avatar
Florian Hölzl committed
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/*
 * STATEMENT TERM
 */
statementListEOF returns [StatementSequence result] :
	s=statementList {$result = StatementSequenceStaticImpl.create($s.result);} ;
	
statementList returns [List<IStatementTerm> result] :
	{$result = new ArrayList<IStatementTerm>();}
	s1=statement {$result.add($s1.result);}
	(
		s2=statement {$result.add($s2.result);}
	)* ;

statement returns [IStatementTerm result] :
	a=assignmentTerm {$result = $a.result;} |
	i=ifTerm {$result = $i.result;} |
	r=returnTerm {$result = $r.result;};

returnTerm returns [Return result] :
	'return' term? ';' {$result = ReturnStaticImpl.create($term.result); };
	
Dongyue Mou's avatar
Dongyue Mou committed
252
253
254
255
256
assignmentTerm returns [IStatementTerm result] 
	: primaryTerm {$result = $primaryTerm.result;}
		( '.' varidConstTerm {$result = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.MEMBER), $primaryTerm.result, $varidConstTerm.result);}
		| '[' integerConstTerm ']' {$result = FunctionCallStaticImpl.create(PredefinedFunctionStaticImpl.create(EOperator.INDEX), $primaryTerm.result, $integerConstTerm.result);}
		)*
257
	  '=' term {$result = AssignmentStaticImpl.create(VarStaticImpl.create((IExpressionTerm)$result), $term.result);}
Daniel Ratiu's avatar
Daniel Ratiu committed
258
	  ';'
Dongyue Mou's avatar
Dongyue Mou committed
259
	;
Florian Hölzl's avatar
Florian Hölzl committed
260
261
262
263
264
265
266
267
268
	
ifTerm returns [IfThenElse result] :
	'if' '(' cond=term ')' '{'
		ifblock=statementList {$result = IfThenElseStaticImpl.create($cond.result, StatementSequenceStaticImpl.create($ifblock.result));}
	'}'
	(
	'else' '{'
		elseblock=statementList {((IfThenElse)$result).setElseBlock(StatementSequenceStaticImpl.create($elseblock.result));}
	'}')? ;
269
  
Florian Hölzl's avatar
Florian Hölzl committed
270
271
272
273
274
275
/*
 * TYPE
 */
typeEOF returns [IType result] :
	type EOF {$result = $type.result;};
	
276
type returns  [IType result] :
Dongyue Mou's avatar
Dongyue Mou committed
277
	groundType {$result = $groundType.result;} ;
278
	 
279
groundType returns [IType result] :
280
281
    'int' { $result = intType(); } | 
    'int' '[' lower=nativeJavaInt ',' upper=nativeJavaInt ']' {$result = intType(lower, upper);} |
Florian Hölzl's avatar
cleanup    
Florian Hölzl committed
282
283
	'boolean' {$result = boolType();} |
	'double' {$result = doubleType();} |
Vincent Aravantinos's avatar
Vincent Aravantinos committed
284
    ID {$result = createUnboundDefinedType($ID.text);};