8de9fc6d6c8aff8bbd6ae133683e750139e75d82
[charm.git] / src / langs / charj / src / charj / translator / CharjEmitter.g
1 /**
2  * ANTLR (v3) Tree Parser for the Charj Language
3  */
4
5 tree grammar CharjEmitter;
6
7 options {
8     backtrack = true; 
9     memoize = true;
10     tokenVocab = Charj;
11     ASTLabelType = CharjAST;
12     output = template;
13 }
14
15
16 @header {
17 package charj.translator;
18 }
19
20
21 @members {
22     SymbolTable symtab = null;
23
24     PackageScope currentPackage = null;
25     ClassSymbol currentClass = null;
26     MethodSymbol currentMethod = null;
27     LocalScope currentLocalScope = null;
28
29     Translator translator_;
30     OutputMode mode_;
31
32     private boolean emitCC() { return mode_ == OutputMode.cc; }
33     private boolean emitCI() { return mode_ == OutputMode.ci; }
34     private boolean emitH() { return mode_ == OutputMode.h; }
35     private boolean debug() { return translator_.debug(); }
36     private String basename() { return translator_.basename(); }
37
38     /**
39      *  Override ANTLR's token mismatch behavior so we throw exceptions early.
40      */
41     protected void mismatch(IntStream input, int ttype, BitSet follow)
42         throws RecognitionException {
43         throw new MismatchedTokenException(ttype, input);
44     }
45
46     /**
47      *  Override ANTLR's set mismatch behavior so we throw exceptions early.
48      */
49     public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow)
50         throws RecognitionException {
51         throw e;
52     }
53
54     /**
55      *  Test a list of CharjAST nodes to see if any of them has the given token
56      *  type.
57      */
58     public boolean listContainsToken(List<CharjAST> list, int tokenType) {
59         if (list == null) return false;
60         for (CharjAST node : list) {
61             if (node.token.getType() == tokenType) {
62                 return true;
63             }
64         }
65         return false;
66     }
67 }
68
69
70 // Replace default ANTLR generated catch clauses with this action, allowing early failure.
71 @rulecatch {
72     catch (RecognitionException re) {
73         reportError(re);
74         throw re;
75     }
76 }
77
78
79 // Starting point for parsing a Charj file.
80 charjSource[SymbolTable symtab, OutputMode m]
81 @init {
82     this.symtab = symtab;
83     this.translator_ = symtab.translator;
84     this.mode_ = m;
85 }
86     :   ^(CHARJ_SOURCE (p=packageDeclaration)? 
87         (i+=importDeclaration)*
88         (r+=readonlyDeclaration)*
89         (t+=typeDeclaration)*)
90         -> {emitCC()}? charjSource_cc(basename={basename()}, pd={$p.names}, imports={$i}, types={$t}, ros={$r}, debug={debug()})
91         -> {emitCI()}? charjSource_ci(basename={basename()}, pd={$p.names}, imports={$i}, types={$t}, ros={$r}, debug={debug()})
92         -> {emitH()}? charjSource_h(basename={basename()}, pd={$p.names}, imports={$i}, types={$t}, ros={$r}, debug={debug()})
93         ->
94     ;
95
96 topLevelDeclaration
97     :   importDeclaration -> {$importDeclaration.st;}
98     |   typeDeclaration -> {$typeDeclaration.st;}
99     ;
100
101 packageDeclaration returns [List names]
102     :   ^('package' (ids+=IDENT)+)
103         {
104             $names = $ids;
105         }
106         ->
107     ;
108
109 readonlyDeclaration
110     :   ^(READONLY lvd=localVariableDeclaration)
111         -> {emitCI()}? template(bn={basename()}, v={$lvd.st}) "readonly <v>"
112         -> {emitH()}? template(v={$lvd.st}) "extern <v>"
113         -> {emitCC()}? {$lvd.st;}
114         ->
115     ;
116     
117 importDeclaration
118 @init {
119     String importID = null;
120 }
121     :   ^('import' qualifiedIdentifier ds='.*'?)
122         {
123             importID = $qualifiedIdentifier.text;
124             if ($ds != null) {
125             }
126         }
127         {$ds == null}? // TODO: add support for importing x.*
128         -> {(emitCC() || emitH())}? importDeclaration_cc_h(
129             inc_id={importID.replace(".","/")},
130             use_id={importID.replace(".","::")})
131         ->
132     ;
133     
134 typeDeclaration
135     :   ^(TYPE CLASS IDENT (^('extends' su=type))? (^('implements' type+))?
136         {
137             currentClass = (ClassSymbol)$IDENT.symbol;
138         }
139         (csds+=classScopeDeclaration)*)
140         -> {emitCC()}? classDeclaration_cc(
141                 sym={currentClass},
142                 ident={$IDENT.text}, 
143                 ext={$su.st}, 
144                 csds={$csds})
145         -> {emitH()}?  classDeclaration_h(
146                 sym={currentClass},
147                 ident={$IDENT.text}, 
148                 ext={$su.st}, 
149                 csds={$csds})
150         ->
151     |   ^(INTERFACE IDENT (^('extends' type+))? interfaceScopeDeclaration*)
152         -> template(t={$text}) "/*INTERFACE-not implemented*/ <t>"
153     |   ^(ENUM IDENT (^('implements' type+))? classScopeDeclaration*)
154         -> template(t={$text}) "/*ENUM-not implemented*/ <t>"
155     |   ^(TYPE chareType IDENT (^('extends' type))? (^('implements' type+))?
156         {
157             currentClass = (ClassSymbol)$IDENT.symbol;
158         }
159         (csds+=classScopeDeclaration)*)
160         -> {emitCC()}? chareDeclaration_cc(
161                 sym={currentClass},
162                 ident={$IDENT.text}, 
163                 ext={$su.st}, 
164                 csds={$csds})
165         -> {emitCI()}? chareDeclaration_ci(
166                 sym={currentClass},
167                 chareType={$chareType.st},
168                 arrayDim={null},
169                 ident={$IDENT.text}, 
170                 ext={$su.st}, 
171                 csds={$csds})
172         -> {emitH()}? chareDeclaration_h(
173                 sym={currentClass},
174                 ident={$IDENT.text}, 
175                 ext={$su.st}, 
176                 csds={$csds})
177         ->
178     ;
179
180 chareType
181 @init {
182 $st = %{$start.getText()};
183 }
184     :   CHARE
185     |   GROUP
186     |   NODEGROUP
187     |   MAINCHARE
188     |   ^(CHARE_ARRAY ARRAY_DIMENSION)
189         -> template(t={$ARRAY_DIMENSION.text}) "array [<t>]"
190     ;
191
192 enumConstant
193     :   ^(IDENT arguments?)
194         -> template(t={$text}) "/*enumConstant-not implemented*/ <t>"
195     ;
196
197 classScopeDeclaration
198 @init
199 {
200     boolean entry = false;
201     boolean migrationCtor = false;
202 }
203     :   ^(FUNCTION_METHOD_DECL m=modifierList? g=genericTypeParameterList? 
204             ty=type IDENT f=formalParameterList a=arrayDeclaratorList? 
205             b=block?)
206         {
207             // determine whether it's an entry method
208             if($m.start != null)
209                 entry = listContainsToken($m.start.getChildren(), CHARJ_MODIFIER_LIST);
210         }
211         -> {emitCC()}? funcMethodDecl_cc(
212                 sym={currentClass},
213                 modl={$m.st}, 
214                 gtpl={$g.st}, 
215                 ty={$ty.st},
216                 id={$IDENT.text}, 
217                 fpl={$f.st}, 
218                 adl={$a.st},
219                 block={$b.st})
220         -> {emitH()}? funcMethodDecl_h(
221                 modl={$m.st}, 
222                 gtpl={$g.st}, 
223                 ty={$ty.st},
224                 id={$IDENT.text}, 
225                 fpl={$f.st}, 
226                 adl={$a.st},
227                 block={$b.st})
228         -> {(emitCI() && entry)}? funcMethodDecl_ci(
229                 modl={$m.st}, 
230                 gtpl={$g.st}, 
231                 ty={$ty.st},
232                 id={$IDENT.text}, 
233                 fpl={$f.st}, 
234                 adl={$a.st},
235                 block={$b.st})
236         ->
237     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList)
238         -> {emitH()}? class_var_decl(
239             modl={$modifierList.st},
240             type={$simpleType.st},
241             declList={$variableDeclaratorList.st})
242         ->
243     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
244         -> {emitH()}? class_var_decl(
245             modl={$modifierList.st},
246             type={$objectType.st},
247             declList={$variableDeclaratorList.st})
248         ->
249     |   ^(CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList b=block)
250         {
251             // determine whether it's an entry method
252             if ($m.start != null) {
253                 entry = listContainsToken($m.start.getChildren(), CHARJ_MODIFIER_LIST);
254             }
255             migrationCtor = currentClass.migrationCtor == $CONSTRUCTOR_DECL;
256         }
257         -> {emitCC()}? ctorDecl_cc(
258                 modl={$m.st},
259                 gtpl={$g.st}, 
260                 id={$IDENT.text}, 
261                 fpl={$f.st}, 
262                 block={$b.st})
263         -> {emitCI() && entry && !migrationCtor}? ctorDecl_ci(
264                 modl={$m.st},
265                 gtpl={$g.st}, 
266                 id={$IDENT.text}, 
267                 fpl={$f.st}, 
268                 block={$b.st})
269         -> {emitH()}? ctorDecl_h(
270                 modl={$m.st},
271                 gtpl={$g.st}, 
272                 id={$IDENT.text}, 
273                 fpl={$f.st}, 
274                 block={$b.st})
275         ->
276     ;
277     
278 interfaceScopeDeclaration
279     :   ^(FUNCTION_METHOD_DECL modifierList? genericTypeParameterList? type IDENT formalParameterList arrayDeclaratorList?)
280         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
281     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList)
282         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
283     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
284         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
285     ;
286
287 variableDeclaratorList
288     :   ^(VAR_DECLARATOR_LIST (var_decls+=variableDeclarator)+)
289         -> var_decl_list(var_decls={$var_decls})
290     ;
291
292 variableDeclarator
293     :   ^(VAR_DECLARATOR id=variableDeclaratorId initializer=variableInitializer?)
294         -> {emitCC()}? var_decl_cc(id={$id.st}, initializer={$initializer.st})
295         -> {emitH()}?  var_decl_h(id={$id.st}, initializer={$initializer.st})
296         -> {emitCI()}? var_decl_ci(id={$id.st}, initializer={$initializer.st})
297         ->
298     ; 
299     
300 variableDeclaratorId
301     :   ^(IDENT adl=arrayDeclaratorList?)
302         -> var_decl_id(id={$IDENT.text}, arrayDeclList={$adl.st})
303     ;
304
305 variableInitializer
306     :   arrayInitializer
307         -> {$arrayInitializer.st}
308     |   expression
309         -> {$expression.st}
310     ;
311
312 arrayDeclaratorList
313     :   ^(ARRAY_DECLARATOR_LIST ARRAY_DECLARATOR*)  
314         -> template(t={$text}) "<t>"
315     ;
316     
317 arrayInitializer
318     :   ^(ARRAY_INITIALIZER variableInitializer*)
319         -> template(t={$text}) "/* arrayInitializer-not implemented */ <t>"
320     ;
321
322 genericTypeParameterList
323     :   ^(GENERIC_TYPE_PARAM_LIST genericTypeParameter+)
324         -> template(t={$text}) "/*GENERIC_TYPE_PARAM_LIST-not implemented*/ <t>"
325     ;
326
327 genericTypeParameter
328     :   ^(IDENT bound?)
329         -> template(t={$text}) "/*genericTypeParameter-not implemented*/ <t>"
330     ;
331         
332 bound
333     :   ^(EXTENDS_BOUND_LIST type+)
334         -> template(t={$text}) "/*EXTENDS_BOUND_LIST-not implemented*/ <t>"
335     ;
336
337 throwsClause
338     :   ^(THROWS_CLAUSE qualifiedIdentifier+)
339         -> template(t={$text}) "/* throwsClause-not implemented */ <t>"
340     ;
341
342 modifierList
343     :   ^(MODIFIER_LIST accessModifierList? localModifierList? charjModifierList? otherModifierList?)
344         ->  {emitCC()}? mod_list_cc(accmods = {$accessModifierList.names}, localmods = {$localModifierList.names}, charjmods = {$charjModifierList.names}, othermods = {$otherModifierList.names})
345         ->  {emitH()}? mod_list_h(accmods = {$accessModifierList.names}, localmods = {$localModifierList.names}, charjmods = {$charjModifierList.names}, othermods = {$otherModifierList.names})
346         ->  {emitCI()}? mod_list_ci(accmods = {$accessModifierList.names}, localmods = {$localModifierList.names}, charjmods = {$charjModifierList.names}, othermods = {$otherModifierList.names})
347         ->
348     ;
349
350 modifier
351     :   accessModifier
352     |   localModifier
353     |   charjModifier
354     |   otherModifier
355     ;
356
357 accessModifierList
358 returns [List names]
359     :   ^(ACCESS_MODIFIER_LIST (m+=accessModifier)+)
360         {
361             $names = $m;
362         }
363     ;
364 localModifierList
365 returns [List names]
366     :   ^(LOCAL_MODIFIER_LIST (m+=localModifier)+)
367         {
368             $names = $m;
369         }
370         ->  local_mod_list(mods = {$names})
371     ;
372
373 charjModifierList
374 returns [List names]
375     :   ^(CHARJ_MODIFIER_LIST (m+=charjModifier)+)
376         {
377             $names = $m;
378         }
379     ;
380
381 otherModifierList
382 returns [List names]
383     :   ^(OTHER_MODIFIER_LIST (m+=otherModifier)+)
384         {
385             $names = $m;
386         }
387     ;
388     
389 localModifier
390 @init
391 {
392     $st = %{$start.getText()};
393 }
394     :   FINAL
395     |   STATIC
396     |   VOLATILE
397     ;
398
399 accessModifier
400 @init
401 {
402     $st = %{$start.getText()};
403 }
404     :   PUBLIC
405     |   PROTECTED
406     |   PRIVATE
407     ;
408
409 charjModifier
410 @init
411 {
412     $st = %{$start.getText()};
413 }
414     :   ENTRY
415     ;
416
417 otherModifier
418 @init
419 {
420     $st = %{$start.getText()};
421 }
422     :   ABSTRACT
423     |   NATIVE
424     ;
425     
426 type
427     :   simpleType
428         -> {$simpleType.st}
429     |   objectType 
430         -> {$objectType.st}
431     |   VOID
432         {
433             $st = %{$start.getText()};
434         }
435     ;
436
437 simpleType
438     :   ^(SIMPLE_TYPE primitiveType arrayDeclaratorList?)
439         -> simple_type(typeID={$primitiveType.st}, arrDeclList={$arrayDeclaratorList.st})
440     ;
441
442 objectType
443     : proxyType -> {$proxyType.st;}
444     | nonProxyType -> {$nonProxyType.st}
445     ;
446
447 nonProxyType
448     :   ^(OBJECT_TYPE qualifiedTypeIdent arrayDeclaratorList?)
449         -> obj_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$arrayDeclaratorList.st})
450     |   ^(POINTER_TYPE qualifiedTypeIdent arrayDeclaratorList?)
451         -> pointer_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$arrayDeclaratorList.st})
452     |   ^(REFERENCE_TYPE qualifiedTypeIdent arrayDeclaratorList?)
453         -> reference_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$arrayDeclaratorList.st})
454     ;
455
456 proxyType
457     :   ^(PROXY_TYPE qualifiedTypeIdent arrayDeclaratorList?)
458         -> proxy_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$arrayDeclaratorList.st})
459     ;
460
461 qualifiedTypeIdent returns [ClassSymbol type]
462     :   ^(QUALIFIED_TYPE_IDENT (t+=typeIdent)+)
463         {$type = (ClassSymbol)$QUALIFIED_TYPE_IDENT.symbol;}
464         -> template(types={$t}) "<types; separator=\"::\">"
465     ;
466
467 typeIdent
468     :   ^(IDENT genericTypeArgumentList?)
469         -> typeIdent(typeID={$IDENT.text}, generics={$genericTypeArgumentList.st})
470     ;
471
472 primitiveType
473 @init {
474 $st = %{$start.getText()};
475 }
476     :   BOOLEAN
477         -> template() "bool"
478     |   CHAR
479     |   BYTE
480         -> template() "char"
481     |   SHORT
482     |   INT
483     |   LONG
484     |   FLOAT
485     |   DOUBLE
486     ;
487
488 genericTypeArgumentList
489     :   ^(GENERIC_TYPE_ARG_LIST (gta+=genericTypeArgument)+)
490         -> template(gtal={$gta}) "\<<gtal; separator=\", \">\>"
491     ;
492     
493 genericTypeArgument
494     :   type
495         -> {$type.st}
496     |   '?'
497         -> template(t={$text}) "/* genericTypeArgument: wildcard bound types not implemented */ <t>"
498     ;
499
500 formalParameterList
501     :   ^(FORMAL_PARAM_LIST (fpsd+=formalParameterStandardDecl)* fpvd=formalParameterVarargDecl?)
502         -> formal_param_list(sdecl={$fpsd}, vdecl={$fpvd.st})
503     ;
504     
505 formalParameterStandardDecl
506     :   ^(FORMAL_PARAM_STD_DECL lms=localModifierList? t=type vdid=variableDeclaratorId)
507         -> formal_param_decl(modList={$lms.st}, type={$t.st}, declID={$vdid.st})
508     ;
509     
510 formalParameterVarargDecl
511     :   ^(FORMAL_PARAM_VARARG_DECL localModifierList? type variableDeclaratorId)
512         -> template(t={$text}) "/*formal parameter varargs not implemented*/ <t>"
513     ;
514     
515 qualifiedIdentifier
516     :   IDENT
517         -> template(t={$text}) "<t>"
518     |   ^(DOT qualifiedIdentifier IDENT)
519         -> template(t={$text}) "<t>"
520     ;
521     
522 block
523 @init { boolean emptyBlock = true; }
524     :   ^(BLOCK (b+=blockStatement)*)
525         { emptyBlock = ($b == null || $b.size() == 0); }
526         -> {emitCC() && emptyBlock}? template(bsl={$b}) "{ }"
527         -> {emitCC()}? block_cc(bsl={$b})
528         ->
529     ;
530     
531 blockStatement
532     :   localVariableDeclaration
533         -> {$localVariableDeclaration.st}
534     |   statement
535         -> {$statement.st}
536     ;
537
538
539 localVariableDeclaration
540     :   ^(PRIMITIVE_VAR_DECLARATION localModifierList? simpleType variableDeclaratorList)
541         -> local_var_decl(
542             modList={$localModifierList.st},
543             type={$simpleType.st},
544             declList={$variableDeclaratorList.st})
545     |   ^(OBJECT_VAR_DECLARATION localModifierList? objectType variableDeclaratorList)
546         -> local_var_decl(
547             modList={$localModifierList.st},
548             type={$objectType.st},
549             declList={$variableDeclaratorList.st})
550     ;
551
552
553 statement
554     :   nonBlockStatement
555         -> {$nonBlockStatement.st}
556     |   block
557         -> {$block.st}
558     ;
559
560 nonBlockStatement
561     :   ^(ASSERT cond=expression msg=expression?)
562         -> assert(cond={$cond.st}, msg={$msg.st})
563     |   ^(IF parenthesizedExpression then=block else_=block?)
564         -> if(cond={$parenthesizedExpression.st}, then={$then.st}, else_={$else_.st})
565     |   ^(FOR forInit? FOR_EXPR cond=expression? FOR_UPDATE (update+=expression)* b=block)
566         -> for(initializer={$forInit.st}, cond={$cond.st}, update={$update}, body={$block.st})
567     |   ^(FOR_EACH localModifierList? type IDENT expression block) 
568         -> template(t={$text}) "/* foreach not implemented */ <t>"
569     |   ^(WHILE pe=parenthesizedExpression b=block)
570         -> while(cond={$pe.st}, body={$b.st})
571     |   ^(DO b=block pe=parenthesizedExpression)
572         -> dowhile(cond={$pe.st}, block={$b.st})
573     |   ^(SWITCH pe=parenthesizedExpression (scls+=switchCaseLabel)*)
574         -> switch(expr={$pe.st}, labels={$scls})
575     |   ^(RETURN e=expression?)
576         -> return(val={$e.st})
577     |   ^(THROW expression)
578         -> template(t={$text}) "/* throw not implemented */ <t>"
579     |   ^(BREAK IDENT?)
580         -> template() "break;" // TODO: support labeling
581     |   ^(CONTINUE IDENT?)
582         -> template() "continue;" // TODO: support labeling
583     |   ^(LABELED_STATEMENT i=IDENT s=statement)
584         -> label(text={$i.text}, stmt={$s.st})
585     |   expression
586         -> template(expr={$expression.st}) "<expr>;"
587     |   ^('delete' qualifiedIdentifier)
588         -> template(t={$qualifiedIdentifier.st}) "delete <t>;"
589     |   ^('embed' STRING_LITERAL EMBED_BLOCK)
590         ->  embed_cc(str={$STRING_LITERAL.text}, blk={$EMBED_BLOCK.text})
591     |   ';' // Empty statement.
592         -> {%{$start.getText()}}
593     |   ^(PRINT (exprs += expression)*)
594         ->  print(exprs = {$exprs})
595     |   ^(PRINTLN (exprs += expression)*)
596         ->  println(exprs = {$exprs})
597     |   ^(EXIT expression?)
598         ->  exit(expr = {$expression.st})
599     |   EXITALL
600         ->  exitall()
601     ;
602         
603 switchCaseLabel
604     :   ^(CASE expression (b+=blockStatement)*)
605         -> case(expr={$expression.st}, block={$b})
606     |   ^(DEFAULT (b+=blockStatement)*)
607         -> template(block={$b}) "default: <block>"
608     ;
609     
610 forInit
611     :   localVariableDeclaration
612         -> template(lvd={$localVariableDeclaration.st}) "<lvd>"
613     |   (ex+=expression)+
614         -> template(ex={$ex}) "<ex; separator=\", \">"
615     ;
616
617 // EXPRESSIONS
618
619 parenthesizedExpression
620     :   ^(PAREN_EXPR exp=expression)
621         -> template(expr={$exp.st}) "(<expr>)"
622     ;
623     
624 expression
625     :   ^(EXPR expr)
626         -> {$expr.st}
627     ;
628
629 expr
630     :   ^(ASSIGNMENT e1=expr e2=expr)
631         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> = <e2>"
632     |   ^('+=' e1=expr e2=expr)
633         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> += <e2>"
634     |   ^('-=' e1=expr e2=expr)
635         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> -= <e2>"
636     |   ^('*=' e1=expr e2=expr)
637         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> *= <e2>"
638     |   ^('/=' e1=expr e2=expr)
639         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> /= <e2>"
640     |   ^('&=' e1=expr e2=expr)
641         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> &= <e2>"
642     |   ^('|=' e1=expr e2=expr)
643         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> |= <e2>"
644     |   ^('^=' e1=expr e2=expr)
645         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> ^= <e2>"
646     |   ^('%=' e1=expr e2=expr)
647         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> %= <e2>"
648     |   ^('>>>=' e1=expr e2=expr)
649         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>\>= <e2>"
650     |   ^('>>=' e1=expr e2=expr)
651         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>= <e2>"
652     |   ^('<<=' e1=expr e2=expr)
653         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<\<= <e2>"
654     |   ^('?' e1=expr e2=expr e3=expr)
655         -> template(e1={$e1.st}, e2={$e2.st}, e3={$e3.st}) "<e1> ? <e2> : <e3>"
656     |   ^('||' e1=expr e2=expr)
657         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> || <e2>"
658     |   ^('&&' e1=expr e2=expr)
659         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> && <e2>"
660     |   ^(BITWISE_OR e1=expr e2=expr)
661         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> | <e2>"
662     |   ^('^' e1=expr e2=expr)
663         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> ^ <e2>"
664     |   ^('&' e1=expr e2=expr)
665         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> & <e2>"
666     |   ^(EQUALS e1=expr e2=expr)
667         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> == <e2>"
668     |   ^('!=' e1=expr e2=expr)
669         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> != <e2>"
670     |   ^('instanceof' expr type)
671         -> template(t={$text}) "/* instanceof not implemented */ <t>"
672     |   ^('<=' e1=expr e2=expr)
673         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<= <e2>"
674     |   ^('>=' e1=expr e2=expr)
675         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>= <e2>"
676     |   ^('>>>' e1=expr e2=expr)
677         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>\> <e2>"
678     |   ^('>>' e1=expr e2=expr)
679         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\> <e2>"
680     |   ^('>' e1=expr e2=expr)
681         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \> <e2>"
682     |   ^('<<' e1=expr e2=expr)
683         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<\< <e2>"
684     |   ^('<' e1=expr e2=expr)
685         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \< <e2>"
686     |   ^('+' e1=expr e2=expr)
687         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> + <e2>"
688     |   ^('-' e1=expr e2=expr)
689         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> - <e2>"
690     |   ^('*' e1=expr e2=expr)
691         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> * <e2>"
692     |   ^('/' e1=expr e2=expr)
693         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> / <e2>"
694     |   ^('%' e1=expr e2=expr)
695         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> % <e2>"
696     |   ^(UNARY_PLUS e1=expr)
697         -> template(e1={$e1.st}) "+<e1>"
698     |   ^(UNARY_MINUS e1=expr)
699         -> template(e1={$e1.st}) "-<e1>"
700     |   ^(PRE_INC e1=expr)
701         -> template(e1={$e1.st}) "++<e1>"
702     |   ^(PRE_DEC e1=expr)
703         -> template(e1={$e1.st}) "--<e1>"
704     |   ^(POST_INC e1=expr)
705         -> template(e1={$e1.st}) "<e1>++"
706     |   ^(POST_DEC e1=expr)
707         -> template(e1={$e1.st}) "<e1>--"
708     |   ^(TILDE e1=expr)
709         -> template(e1={$e1.st}) "~<e1>"
710     |   ^(NOT e1=expr)
711         -> template(e1={$e1.st}) "!<e1>"
712     |   ^(CAST_EXPR ty=type e1=expr)
713         -> template(ty={$ty.st}, e1={$e1.st}) "(<ty>)<e1>"
714     |   primaryExpression
715         -> {$primaryExpression.st}
716     ;
717
718 primaryExpression
719     :   ^(DOT prim=primaryExpression
720             ( IDENT   -> template(id={$IDENT}, prim={$prim.st}) "<prim>.<id>"
721             | THIS    -> template(prim={$prim.st}) "<prim>.this"
722             | SUPER   -> template(prim={$prim.st}) "<prim>.super"
723             )
724         )
725     |   ^(ARROW prim=primaryExpression
726             ( IDENT   -> template(id={$IDENT}, prim={$prim.st}) "<prim>-><id>"
727             | THIS    -> template(prim={$prim.st}) "<prim>->this"
728             | SUPER   -> template(prim={$prim.st}) "<prim>->super"
729             )
730         )
731     |   parenthesizedExpression
732         -> {$parenthesizedExpression.st}
733     |   IDENT
734         -> {%{$start.getText()}}
735     |   ^(METHOD_CALL pe=primaryExpression gtal=genericTypeArgumentList? args=arguments)
736         -> method_call(primary={$pe.st}, generic_types={$gtal.st}, args={$args.st})
737     |   ^(ENTRY_METHOD_CALL pe=primaryExpression gtal=genericTypeArgumentList? args=arguments)
738         -> method_call(primary={$pe.st}, generic_types={$gtal.st}, args={$args.st})
739     |   explicitConstructorCall
740         -> {$explicitConstructorCall.st}
741     |   ^(ARRAY_ELEMENT_ACCESS pe=primaryExpression ex=expression)
742         -> template(pe={$pe.st}, ex={$ex.st}) "<pe>[<ex>]"
743     |   literal
744         -> {$literal.st}
745     |   newExpression
746         -> {$newExpression.st}
747     |   THIS
748         -> {%{$start.getText()}}
749     |   arrayTypeDeclarator
750         -> {$arrayTypeDeclarator.st}
751     |   SUPER
752         -> {%{$start.getText()}}
753     |   GETNUMPES
754         ->  template() "CkNumPes()"
755     |   GETNUMNODES
756         ->  template() "CkNumNodes()"
757     |   GETMYPE
758         ->  template() "CkMyPe()"
759     |   GETMYNODE
760         ->  template() "CkMyNode()"
761     |   GETMYRANK
762         ->  template() "CkMyRank()"
763
764     ;
765     
766 explicitConstructorCall
767     :   ^(THIS_CONSTRUCTOR_CALL genericTypeArgumentList? arguments)
768         -> template(t={$text}) "<t>"
769     |   ^(SUPER_CONSTRUCTOR_CALL primaryExpression? genericTypeArgumentList? arguments)
770         -> template(t={$text}) "<t>"
771     ;
772
773 arrayTypeDeclarator
774     :   ^(ARRAY_DECLARATOR (arrayTypeDeclarator | qualifiedIdentifier | primitiveType))
775         -> template(t={$text}) "<t>"
776     ;
777
778 newExpression
779     :   ^(  STATIC_ARRAY_CREATOR
780             (   primitiveType newArrayConstruction
781             |   genericTypeArgumentList? qualifiedTypeIdent newArrayConstruction
782             )
783         )
784         -> template(t={$text}) "<t>"
785     |   ^(NEW proxyType arguments)
786         -> template(t={$proxyType.st}, a={$arguments.st}) "<t>::ckNew(<a>)"
787     |   ^(NEW nonProxyType arguments)
788         -> template(q={$nonProxyType.st}, a={$arguments.st}) "new <q>(<a>)"
789     ;
790
791 newArrayConstruction
792     :   arrayDeclaratorList arrayInitializer
793         -> array_construction_with_init(
794                 array_decls={$arrayDeclaratorList.st},
795                 initializer={$arrayInitializer.st})
796     |   (ex+=expression)+ adl=arrayDeclaratorList?
797         -> array_construction(exprs={$ex}, array_decls={$adl.st})
798     ;
799
800 arguments
801     :   ^(ARGUMENT_LIST (ex+=expression)*)
802         -> arguments(exprs={$ex})
803     ;
804
805 literal
806 @init {
807 $st = %{$start.getText()};
808 }
809     :   HEX_LITERAL
810     |   OCTAL_LITERAL
811     |   DECIMAL_LITERAL
812     |   FLOATING_POINT_LITERAL
813     |   CHARACTER_LITERAL
814     |   STRING_LITERAL
815     |   TRUE
816     |   FALSE
817     |   NULL
818     ;
819