1grammar t042ast;
2options {
3    language = Python;
4    output = AST;
5}
6
7tokens {
8    VARDEF;
9    FLOAT;
10    EXPR;
11    BLOCK;
12    VARIABLE;
13    FIELD;
14    CALL;
15    INDEX;
16    FIELDACCESS;
17}
18
19@init {
20self.flag = False
21}
22
23r1
24    : INT ('+'^ INT)*
25    ;
26
27r2
28    : 'assert'^ x=expression (':'! y=expression)? ';'!
29    ;
30
31r3
32    : 'if'^ expression s1=statement ('else'! s2=statement)?
33    ;
34
35r4
36    : 'while'^ expression statement
37    ;
38
39r5
40    : 'return'^ expression? ';'!
41    ;
42
43r6
44    : (INT|ID)+
45    ;
46
47r7
48    : INT ->
49    ;
50
51r8
52    : 'var' ID ':' type -> ^('var' type ID)
53    ;
54
55r9
56    : type ID ';' -> ^(VARDEF type ID)
57    ;
58
59r10
60    : INT -> {CommonTree(CommonToken(type=FLOAT, text=$INT.text + ".0"))}
61    ;
62
63r11
64    : expression -> ^(EXPR expression)
65    | -> EXPR
66    ;
67
68r12
69    : ID (',' ID)* -> ID+
70    ;
71
72r13
73    : type ID (',' ID)* ';' -> ^(type ID+)
74    ;
75
76r14
77    :   expression? statement* type+
78        -> ^(EXPR expression? statement* type+)
79    ;
80
81r15
82    : INT -> INT INT
83    ;
84
85r16
86    : 'int' ID (',' ID)* -> ^('int' ID)+
87    ;
88
89r17
90    : 'for' '(' start=statement ';' expression ';' next=statement ')' statement
91        -> ^('for' $start expression $next statement)
92    ;
93
94r18
95    : t='for' -> ^(BLOCK)
96    ;
97
98r19
99    : t='for' -> ^(BLOCK[$t])
100    ;
101
102r20
103    : t='for' -> ^(BLOCK[$t,"FOR"])
104    ;
105
106r21
107    : t='for' -> BLOCK
108    ;
109
110r22
111    : t='for' -> BLOCK[$t]
112    ;
113
114r23
115    : t='for' -> BLOCK[$t,"FOR"]
116    ;
117
118r24
119    : r=statement expression -> ^($r expression)
120    ;
121
122r25
123    : r+=statement (',' r+=statement)+ expression -> ^($r expression)
124    ;
125
126r26
127    : r+=statement (',' r+=statement)+ -> ^(BLOCK $r+)
128    ;
129
130r27
131    : r=statement expression -> ^($r ^($r expression))
132    ;
133
134r28
135    : ('foo28a'|'foo28b') ->
136    ;
137
138r29
139    : (r+=statement)* -> ^(BLOCK $r+)
140    ;
141
142r30
143    : statement* -> ^(BLOCK statement?)
144    ;
145
146r31
147    : modifier type ID ('=' expression)? ';'
148        -> {self.flag == 0}? ^(VARDEF ID modifier* type expression?)
149        -> {self.flag == 1}? ^(VARIABLE ID modifier* type expression?)
150        ->                   ^(FIELD ID modifier* type expression?)
151    ;
152
153r32[which]
154  : ID INT -> {which==1}? ID
155           -> {which==2}? INT
156           -> // yield nothing as else-clause
157  ;
158
159r33
160    :   modifiers! statement
161    ;
162
163r34
164    :   modifiers! r34a[$modifiers.tree]
165    //|   modifiers! r33b[$modifiers.tree]
166    ;
167
168r34a[mod]
169    :   'class' ID ('extends' sup=type)?
170        ( 'implements' i+=type (',' i+=type)*)?
171        '{' statement* '}'
172        -> ^('class' ID {$mod} ^('extends' $sup)? ^('implements' $i+)? statement* )
173    ;
174
175r35
176    : '{' 'extends' (sup=type)? '}'
177        ->  ^('extends' $sup)?
178    ;
179
180r36
181    : 'if' '(' expression ')' s1=statement
182        ( 'else' s2=statement -> ^('if' ^(EXPR expression) $s1 $s2)
183        |                     -> ^('if' ^(EXPR expression) $s1)
184        )
185    ;
186
187r37
188    : (INT -> INT) ('+' i=INT -> ^('+' $r37 $i) )*
189    ;
190
191r38
192    : INT ('+'^ INT)*
193    ;
194
195r39
196    : (primary->primary) // set return tree to just primary
197        ( '(' arg=expression ')'
198            -> ^(CALL $r39 $arg)
199        | '[' ie=expression ']'
200            -> ^(INDEX $r39 $ie)
201        | '.' p=primary
202            -> ^(FIELDACCESS $r39 $p)
203        )*
204    ;
205
206r40
207    : (INT -> INT) ( ('+' i+=INT)* -> ^('+' $r40 $i*) ) ';'
208    ;
209
210r41
211    : (INT -> INT) ( ('+' i=INT) -> ^($i $r41) )* ';'
212    ;
213
214r42
215    : ids+=ID (','! ids+=ID)*
216    ;
217
218r43 returns [res]
219    : ids+=ID! (','! ids+=ID!)* {$res = [id.text for id in $ids]}
220    ;
221
222r44
223    : ids+=ID^ (','! ids+=ID^)*
224    ;
225
226r45
227    : primary^
228    ;
229
230r46 returns [res]
231    : ids+=primary! (','! ids+=primary!)* {$res = [id.text for id in $ids]}
232    ;
233
234r47
235    : ids+=primary (','! ids+=primary)*
236    ;
237
238r48
239    : ids+=. (','! ids+=.)*
240    ;
241
242r49
243    : .^ ID
244    ;
245
246r50
247    : ID
248        -> ^({CommonTree(CommonToken(type=FLOAT, text="1.0"))} ID)
249    ;
250
251/** templates tested:
252    tokenLabelPropertyRef_tree
253*/
254r51 returns [res]
255    : ID t=ID ID
256        { $res = $t.tree }
257    ;
258
259/** templates tested:
260    rulePropertyRef_tree
261*/
262r52 returns [res]
263@after {
264    $res = $tree
265}
266    : ID
267    ;
268
269/** templates tested:
270    ruleLabelPropertyRef_tree
271*/
272r53 returns [res]
273    : t=primary
274        { $res = $t.tree }
275    ;
276
277/** templates tested:
278    ruleSetPropertyRef_tree
279*/
280r54 returns [res]
281@after {
282    $tree = $t.tree;
283}
284    : ID t=expression ID
285    ;
286
287/** backtracking */
288r55
289options { backtrack=true; k=1; }
290    : (modifier+ INT)=> modifier+ expression
291    | modifier+ statement
292    ;
293
294
295/** templates tested:
296    rewriteTokenRef with len(args)>0
297*/
298r56
299    : t=ID* -> ID[$t,'foo']
300    ;
301
302/** templates tested:
303    rewriteTokenRefRoot with len(args)>0
304*/
305r57
306    : t=ID* -> ^(ID[$t,'foo'])
307    ;
308
309/** templates tested:
310    ???
311*/
312r58
313    : ({CommonTree(CommonToken(type=FLOAT, text="2.0"))})^
314    ;
315
316/** templates tested:
317    rewriteTokenListLabelRefRoot
318*/
319r59
320    : (t+=ID)+ statement -> ^($t statement)+
321    ;
322
323primary
324    : ID
325    ;
326
327expression
328    : r1
329    ;
330
331statement
332    : 'fooze'
333    | 'fooze2'
334    ;
335
336modifiers
337    : modifier+
338    ;
339
340modifier
341    : 'public'
342    | 'private'
343    ;
344
345type
346    : 'int'
347    | 'bool'
348    ;
349
350ID : 'a'..'z' + ;
351INT : '0'..'9' +;
352WS: (' ' | '\n' | '\t')+ {$channel = HIDDEN;};
353
354