2a4c428fad881e7269a8ed05a77dc7e7c4c04779
[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 @init {
136     boolean needsMigration = false;
137     List<String> inits = new ArrayList<String>();
138     List<String> pupInits = new ArrayList<String>();
139 }
140     :   ^(TYPE CLASS IDENT (^('extends' su=type))? (^('implements' type+))?
141         {
142             currentClass = (ClassSymbol)$IDENT.def;
143
144             inits = currentClass.generateInits(currentClass.initializers);
145         }
146         (csds+=classScopeDeclaration)*)
147         -> {emitCC()}? classDeclaration_cc(
148                 sym={currentClass},
149                 ident={$IDENT.text}, 
150                 ext={$su.st}, 
151                 csds={$csds},
152                 inits={inits})
153         -> {emitH()}?  classDeclaration_h(
154                 sym={currentClass},
155                 ident={$IDENT.text}, 
156                 ext={$su.st}, 
157                 csds={$csds})
158         ->
159     |   ^('template' (i0+=IDENT*) ^('class' i1=IDENT (^('extends' su=type))? (^('implements' type+))? (csds+=classScopeDeclaration)*))
160         -> {emitH()}? templateDeclaration_h(
161             tident={$i0},
162             ident={$i1.text},
163             ext={$su.st},
164             csds={$csds})
165         -> 
166     |   ^(INTERFACE IDENT (^('extends' type+))? interfaceScopeDeclaration*)
167         -> template(t={$text}) "/*INTERFACE-not implemented*/ <t>"
168     |   ^(ENUM IDENT (^('implements' type+))? classScopeDeclaration*)
169         -> template(t={$text}) "/*ENUM-not implemented*/ <t>"
170     |   ^(TYPE chareType IDENT (^('extends' type))? (^('implements' type+))?
171         {
172             currentClass = (ClassSymbol)$IDENT.def;
173             needsMigration = currentClass.isChareArray && !currentClass.hasMigrationCtor;
174
175             inits = currentClass.generateInits(currentClass.initializers);
176             pupInits = currentClass.generateInits(currentClass.pupInitializers);
177         }
178         (csds+=classScopeDeclaration)*)
179         -> {emitCC()}? chareDeclaration_cc(
180                 sym={currentClass},
181                 ident={$IDENT.text}, 
182                 ext={$su.st}, 
183                 csds={$csds},
184                 pupInits={pupInits},
185                 pupers={currentClass.generatePUPers()},
186                 needsMigration={needsMigration},
187                 inits={inits})
188         -> {emitCI()}? chareDeclaration_ci(
189                 basename={basename()},
190                 sym={currentClass},
191                 chareType={$chareType.st},
192                 arrayDim={null},
193                 ident={$IDENT.text}, 
194                 ext={$su.st}, 
195                 csds={$csds})
196         -> {emitH()}? chareDeclaration_h(
197                 sym={currentClass},
198                 ident={$IDENT.text}, 
199                 ext={$su.st}, 
200                 csds={$csds},
201                 needsPupInit={pupInits.size() > 0},
202                 needsMigration={needsMigration})
203         ->
204     ;
205
206 chareType
207 @init {
208 $st = %{$start.getText()};
209 }
210     :   CHARE
211     |   GROUP
212     |   NODEGROUP
213     |   MAINCHARE
214     |   ^(CHARE_ARRAY ARRAY_DIMENSION)
215         -> template(t={$ARRAY_DIMENSION.text}) "array [<t>]"
216     ;
217
218 enumConstant
219     :   ^(IDENT arguments?)
220         -> template(t={$text}) "/*enumConstant-not implemented*/ <t>"
221     ;
222
223 classScopeDeclaration
224 @init
225 {
226     boolean entry = false;
227     boolean migrationCtor = false;
228 }
229     :   ^(FUNCTION_METHOD_DECL m=modifierList? g=genericTypeParameterList? 
230             ty=type IDENT f=formalParameterList
231             b=block?) {
232             currentMethod = (MethodSymbol)$IDENT.def;
233         }
234         -> {emitCC()}? funcMethodDecl_cc(
235                 classSym={currentClass},
236                 methodSym={currentMethod},
237                 modl={$m.st}, 
238                 gtpl={$g.st}, 
239                 ty={$ty.st},
240                 id={$IDENT.text}, 
241                 fpl={$f.st}, 
242                 block={$b.st})
243         -> {emitH()}? funcMethodDecl_h(
244                 modl={$m.st}, 
245                 gtpl={$g.st}, 
246                 ty={$ty.st},
247                 id={$IDENT.text}, 
248                 fpl={$f.st}, 
249                 block={$b.st})
250         -> {emitCI()}? // do nothing, since it's not an entry method
251         ->
252     |   ^(ENTRY_FUNCTION_DECL m=modifierList? g=genericTypeParameterList? 
253             ty=type IDENT f=formalParameterList a=domainExpression[null]? 
254             b=block?) {
255             currentMethod = (MethodSymbol)$IDENT.def;
256         }
257         -> {emitCC()}? funcMethodDecl_cc(
258                 classSym={currentClass},
259                 methodSym={currentMethod},
260                 modl={$m.st}, 
261                 gtpl={$g.st}, 
262                 ty={$ty.st},
263                 id={$IDENT.text}, 
264                 fpl={$f.st}, 
265                 adl={$a.st},
266                 block={$b.st})
267         -> {emitH()}? funcMethodDecl_h(
268                 modl={$m.st}, 
269                 gtpl={$g.st}, 
270                 ty={$ty.st},
271                 id={$IDENT.text}, 
272                 fpl={$f.st}, 
273                 adl={$a.st},
274                 block={$b.st})
275         -> {emitCI()}? funcMethodDecl_ci(
276                 modl={$m.st}, 
277                 gtpl={$g.st}, 
278                 ty={$ty.st},
279                 id={$IDENT.text}, 
280                 fpl={$f.st}, 
281                 block={$b.st})
282         ->
283     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList[null])
284         -> {emitH()}? class_var_decl(
285             modl={$modifierList.st},
286             type={$simpleType.st},
287             declList={$variableDeclaratorList.st})
288         ->
289     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList[$objectType.st])
290         -> {emitH()}? class_var_decl(
291             modl={$modifierList.st},
292             type={$objectType.st},
293             declList={$variableDeclaratorList.st})
294         ->
295     |   ^(CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList b=block)
296         {
297             currentMethod = (MethodSymbol)$IDENT.def;
298         }
299         -> {emitCC()}? ctorDecl_cc(
300                 modl={$m.st},
301                 gtpl={$g.st}, 
302                 id={$IDENT.text}, 
303                 fpl={$f.st}, 
304                 block={$b.st})
305         -> {emitCI()}? // do nothing, it's not an entry constructor
306         -> {emitH()}? ctorDecl_h(
307                 modl={$m.st},
308                 gtpl={$g.st}, 
309                 id={$IDENT.text}, 
310                 fpl={$f.st}, 
311                 block={$b.st})
312         ->
313     |   ^(ENTRY_CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList b=block)
314         {
315             currentMethod = (MethodSymbol)$IDENT.def;
316             migrationCtor = currentClass.migrationCtor == $ENTRY_CONSTRUCTOR_DECL;
317         }
318         -> {emitCC()}? ctorDecl_cc(
319                 modl={$m.st},
320                 gtpl={$g.st}, 
321                 id={$IDENT.text}, 
322                 fpl={$f.st}, 
323                 block={$b.st})
324         -> {emitCI() && !migrationCtor}? ctorDecl_ci(
325                 modl={$m.st},
326                 gtpl={$g.st}, 
327                 id={$IDENT.text}, 
328                 fpl={$f.st}, 
329                 block={$b.st})
330         -> {emitH()}? ctorDecl_h(
331                 modl={$m.st},
332                 gtpl={$g.st}, 
333                 id={$IDENT.text}, 
334                 fpl={$f.st}, 
335                 block={$b.st})
336         ->
337     ;
338     
339 interfaceScopeDeclaration
340     :   ^(FUNCTION_METHOD_DECL modifierList? genericTypeParameterList? type IDENT formalParameterList)
341         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
342     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList[$simpleType.st])
343         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
344     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList[$objectType.st])
345         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
346     ;
347
348 variableDeclaratorList[StringTemplate obtype]
349     :   ^(VAR_DECLARATOR_LIST (var_decls+=variableDeclarator[obtype])+ )
350         -> var_decl_list(var_decls={$var_decls})
351     ;
352
353 variableDeclarator[StringTemplate obtype]
354     :   ^(VAR_DECLARATOR id=variableDeclaratorId initializer=variableInitializer[obtype]?)
355         -> {emitCC()}? var_decl_cc(id={$id.st}, initializer={$initializer.st})
356         -> {emitH()}?  var_decl_h(id={$id.st}, initializer={$initializer.st})
357         -> {emitCI()}? var_decl_ci(id={$id.st}, initializer={$initializer.st})
358         ->
359     ; 
360     
361 variableDeclaratorId
362     :   ^(IDENT de=domainExpression[null]?)
363         -> var_decl_id(id={$IDENT.text}, domainExp={$de.st})
364     ;
365
366 variableInitializer[StringTemplate obtype]
367     :   arrayInitializer
368         -> {$arrayInitializer.st}
369     |   newExpression[obtype]
370         -> {$newExpression.st}
371     |   expression
372         -> {$expression.st}
373     ;
374
375 rangeItem
376     :   dl=DECIMAL_LITERAL
377         -> template(t={$dl.text}) "<t>"
378     |   IDENT
379         -> template(t={$IDENT.text}) "<t>"
380     ;
381
382 rangeExpression
383     :   ^(RANGE_EXPRESSION (ri+=rangeItem)*)
384         -> template(t={$ri}) "Range(<t; separator=\",\">)"
385     ;
386
387 rangeList returns [int len]
388     :   (r+=rangeExpression)*
389         { $len = $r.size(); }
390         -> template(t={$r}) "<t; separator=\", \">"
391     ;
392
393 domainExpression[List<StringTemplate> otherParams]
394     :   ^(DOMAIN_EXPRESSION rl=rangeList)
395         -> range_constructor(range={$rl.st}, others={$otherParams}, len={$rl.len})
396     ;
397
398 domainExpressionAccess
399     :   ^(DOMAIN_EXPRESSION rl=rangeListAccess)
400         -> template(t={$rangeListAccess.st}) "<t>"
401     ;
402
403 rangeListAccess
404     :   (r+=rangeExpressionAccess)*
405         -> template(t={$r}) "<t; separator=\", \">"
406     ;
407
408 rangeExpressionAccess
409     :   ^(RANGE_EXPRESSION (ri+=rangeItem)*)
410         -> template(t={$ri}) "<t; separator=\",\">"
411     ;
412
413 arrayInitializer
414     :   ^(ARRAY_INITIALIZER variableInitializer[null]*)
415         -> template(t={$text}) "/* arrayInitializer-not implemented */ <t>"
416     ;
417
418 genericTypeParameterList
419     :   ^(GENERIC_TYPE_PARAM_LIST genericTypeParameter+)
420         -> template(t={$text}) "/*GENERIC_TYPE_PARAM_LIST-not implemented*/ <t>"
421     ;
422
423 genericTypeParameter
424     :   ^(IDENT bound?)
425         -> template(t={$text}) "/*genericTypeParameter-not implemented*/ <t>"
426     ;
427         
428 bound
429     :   ^(EXTENDS_BOUND_LIST type+)
430         -> template(t={$text}) "/*EXTENDS_BOUND_LIST-not implemented*/ <t>"
431     ;
432
433 throwsClause
434     :   ^(THROWS_CLAUSE qualifiedIdentifier+)
435         -> template(t={$text}) "/* throwsClause-not implemented */ <t>"
436     ;
437
438 modifierList
439     :   ^(MODIFIER_LIST accessModifierList localModifierList charjModifierList otherModifierList)
440         ->  {emitCC()}? mod_list_cc(accmods = {$accessModifierList.names}, localmods = {$localModifierList.names}, charjmods = {$charjModifierList.names}, othermods = {$otherModifierList.names})
441         ->  {emitH()}? mod_list_h(accmods = {$accessModifierList.names}, localmods = {$localModifierList.names}, charjmods = {$charjModifierList.names}, othermods = {$otherModifierList.names})
442         ->  {emitCI()}? mod_list_ci(accmods = {$accessModifierList.names}, localmods = {$localModifierList.names}, charjmods = {$charjModifierList.names}, othermods = {$otherModifierList.names})
443         ->
444     ;
445
446 modifier
447     :   accessModifier
448     |   localModifier
449     |   charjModifier
450     |   otherModifier
451     ;
452
453 accessModifierList
454 returns [List names]
455     :   ^(ACCESS_MODIFIER_LIST (m+=accessModifier)*)
456         {
457             $names = $m;
458         }
459     ;
460 localModifierList
461 returns [List names]
462     :   ^(LOCAL_MODIFIER_LIST (m+=localModifier)*)
463         {
464             $names = $m;
465         }
466         ->  local_mod_list(mods = {$names})
467     ;
468
469 charjModifierList
470 returns [List names]
471     :   ^(CHARJ_MODIFIER_LIST (m+=charjModifier)*)
472         {
473             $names = $m;
474         }
475     ;
476
477 otherModifierList
478 returns [List names]
479     :   ^(OTHER_MODIFIER_LIST (m+=otherModifier)*)
480         {
481             $names = $m;
482         }
483     ;
484     
485 localModifier
486 @init
487 {
488     $st = %{$start.getText()};
489 }
490     :   FINAL
491     |   STATIC
492     |   VOLATILE
493     ;
494
495 accessModifier
496 @init
497 {
498     $st = %{$start.getText()};
499 }
500     :   PUBLIC
501     |   PROTECTED
502     |   PRIVATE
503         {
504             $st = %{"private"};
505         }
506     ;
507
508 charjModifier
509     :   ENTRY -> {%{$ENTRY.text}}
510     |   TRACED
511     ;
512
513 otherModifier
514 @init
515 {
516     $st = %{$start.getText()};
517 }
518     :   ABSTRACT
519     |   NATIVE
520     ;
521     
522 type
523     :   simpleType
524         -> {$simpleType.st}
525     |   objectType 
526         -> {$objectType.st}
527     |   VOID
528         {
529             $st = %{"void"};
530         }
531     ;
532
533 simpleType
534     :   ^(SIMPLE_TYPE primitiveType domainExpression[null]?)
535         -> simple_type(typeID={$primitiveType.st}, arrDeclList={$domainExpression.st})
536     ;
537
538 objectType //[boolean forNewExpression]
539     : proxyType -> {$proxyType.st;}
540     | nonProxyType -> {$nonProxyType.st}
541     ;
542
543 nonProxyType
544     :   ^(OBJECT_TYPE qualifiedTypeIdent domainExpression[null]?)
545         -> obj_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$domainExpression.st})
546     |   ^(POINTER_TYPE qualifiedTypeIdent domainExpression[null]?)
547         -> pointer_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$domainExpression.st})
548     |   ^(REFERENCE_TYPE qualifiedTypeIdent domainExpression[null]?)
549         -> reference_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$domainExpression.st})
550     ;
551
552 proxyType
553     :   ^(PROXY_TYPE qualifiedTypeIdent domainExpression[null]?)
554         -> proxy_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$domainExpression.st})
555     ;
556
557 qualifiedTypeIdent returns [ClassSymbol type]
558     :   ^(QUALIFIED_TYPE_IDENT (t+=typeIdent)+)
559         {$type = (ClassSymbol)$QUALIFIED_TYPE_IDENT.def;}
560         -> template(types={$t}) "<types; separator=\"::\">"
561     ;
562
563 typeIdent
564     :   ^(IDENT templateInstantiation?)
565         -> typeIdent(typeID={$IDENT.text}, generics={$templateInstantiation.st})
566     ;
567
568 primitiveType
569 @init {
570 $st = %{$start.getText()};
571 }
572     :   BOOLEAN
573         -> template() "bool"
574     |   CHAR
575     |   BYTE
576         -> template() "char"
577     |   SHORT
578     |   INT
579     |   LONG
580     |   FLOAT
581     |   DOUBLE
582     ;
583
584 templateArg
585     :   genericTypeArgument
586         -> {$genericTypeArgument.st}
587     |   literal
588         -> {$literal.st}
589     ;
590
591 templateArgList
592     :   params+=templateArg+
593         -> template(params={$params}) "<params; separator=\", \">"
594     ;
595
596 templateInstantiation
597     :   ^(TEMPLATE_INST templateArgList)
598         -> template(args={$templateArgList.st}) "\<<args>\>"
599     |   ^(TEMPLATE_INST ts=templateInstantiation)
600         -> template(inst={$ts.st}) "\<<inst>\>"
601     ;
602
603 genericTypeArgumentList
604     :   ^(GENERIC_TYPE_ARG_LIST (gta+=genericTypeArgument)+)
605         -> template(gtal={$gta}) "\<<gtal; separator=\", \">\>"
606     ;
607
608 genericTypeArgument
609     :   type
610         -> {$type.st}
611     |   '?'
612         -> template(t={$text}) "/* genericTypeArgument: wildcard bound types not implemented */ <t>"
613     ;
614
615 formalParameterList
616     :   ^(FORMAL_PARAM_LIST (fpsd+=formalParameterStandardDecl)* fpvd=formalParameterVarargDecl?)
617         -> formal_param_list(sdecl={$fpsd}, vdecl={$fpvd.st})
618     ;
619     
620 formalParameterStandardDecl
621     :   ^(FORMAL_PARAM_STD_DECL lms=localModifierList? t=type vdid=variableDeclaratorId)
622         -> formal_param_decl(modList={$lms.st}, type={$t.st}, declID={$vdid.st})
623     ;
624     
625 formalParameterVarargDecl
626     :   ^(FORMAL_PARAM_VARARG_DECL localModifierList? type variableDeclaratorId)
627         -> template(t={$text}) "/*formal parameter varargs not implemented*/ <t>"
628     ;
629     
630 qualifiedIdentifier
631     :   IDENT
632         -> template(t={$text}) "<t>"
633     |   ^(DOT qualifiedIdentifier IDENT)
634         -> template(t={$text}) "<t>"
635     ;
636     
637 block
638 @init { boolean emptyBlock = true; }
639     :   ^(BLOCK (b+=blockStatement)*)
640         { emptyBlock = ($b == null || $b.size() == 0); }
641         -> {emitCC() && emptyBlock}? template(bsl={$b}) "{ }"
642         -> {emitCC()}? block_cc(bsl={$b})
643         ->
644     ;
645     
646 blockStatement
647     :   localVariableDeclaration
648         -> {$localVariableDeclaration.st}
649     |   statement
650         -> {$statement.st}
651     ;
652
653
654 localVariableDeclaration
655     :   ^(PRIMITIVE_VAR_DECLARATION localModifierList? simpleType vdl=variableDeclaratorList[null])
656         -> local_var_decl(
657             modList={$localModifierList.st},
658             type={$simpleType.st},
659             declList={$vdl.st})
660     |   ^(OBJECT_VAR_DECLARATION localModifierList? objectType vdl=variableDeclaratorList[$objectType.st])
661         -> local_var_decl(
662             modList={$localModifierList.st},
663             type={$objectType.st},
664             declList={$vdl.st})
665     ;
666
667
668 statement
669     :   nonBlockStatement
670         -> {$nonBlockStatement.st}
671     |   block
672         -> {$block.st}
673     ;
674
675 nonBlockStatement
676     :   ^(ASSERT cond=expression msg=expression?)
677         -> assert(cond={$cond.st}, msg={$msg.st})
678     |   ^(IF parenthesizedExpression then=block else_=block?)
679         -> if(cond={$parenthesizedExpression.st}, then={$then.st}, else_={$else_.st})
680     |   ^(FOR forInit? FOR_EXPR cond=expression? FOR_UPDATE (update+=expression)* b=block)
681         -> for(initializer={$forInit.st}, cond={$cond.st}, update={$update}, body={$block.st})
682     |   ^(FOR_EACH localModifierList? type IDENT expression block) 
683         -> template(t={$text}) "/* foreach not implemented */ <t>"
684     |   ^(WHILE pe=parenthesizedExpression b=block)
685         -> while(cond={$pe.st}, body={$b.st})
686     |   ^(DO b=block pe=parenthesizedExpression)
687         -> dowhile(cond={$pe.st}, block={$b.st})
688     |   ^(SWITCH pe=parenthesizedExpression (scls+=switchCaseLabel)*)
689         -> switch(expr={$pe.st}, labels={$scls})
690     |   ^(RETURN e=expression?)
691         -> return(val={$e.st})
692     |   ^(THROW expression)
693         -> template(t={$text}) "/* throw not implemented */ <t>"
694     |   ^(BREAK IDENT?)
695         -> template() "break;" // TODO: support labeling
696     |   ^(CONTINUE IDENT?)
697         -> template() "continue;" // TODO: support labeling
698     |   ^(LABELED_STATEMENT i=IDENT s=statement)
699         -> label(text={$i.text}, stmt={$s.st})
700     |   expression
701         -> template(expr={$expression.st}) "<expr>;"
702     |   ^('delete' expression)
703         -> template(t={$expression.st}) "delete <t>;"
704     |   ^('embed' STRING_LITERAL EMBED_BLOCK)
705         ->  embed_cc(str={$STRING_LITERAL.text}, blk={$EMBED_BLOCK.text})
706     |   ';' // Empty statement.
707         -> {%{$start.getText()}}
708     |   ^(PRINT (exprs += expression)*)
709         ->  print(exprs = {$exprs})
710     |   ^(PRINTLN (exprs += expression)*)
711         ->  println(exprs = {$exprs})
712     |   ^(EXIT expression?)
713         ->  exit(expr = {$expression.st})
714     |   EXITALL
715         ->  exitall()
716     ;
717         
718 switchCaseLabel
719     :   ^(CASE expression (b+=blockStatement)*)
720         -> case(expr={$expression.st}, block={$b})
721     |   ^(DEFAULT (b+=blockStatement)*)
722         -> template(block={$b}) "default: <block>"
723     ;
724     
725 forInit
726     :   localVariableDeclaration
727         -> template(lvd={$localVariableDeclaration.st}) "<lvd>"
728     |   (ex+=expression)+
729         -> template(ex={$ex}) "<ex; separator=\", \">"
730     ;
731
732 // EXPRESSIONS
733
734 parenthesizedExpression
735     :   ^(PAREN_EXPR exp=expression)
736         -> template(expr={$exp.st}) "(<expr>)"
737     ;
738
739 expressionArrayAccess
740     :   ^(EXPR expr)
741         -> {$expr.st}
742     |    domainExpressionAccess
743         -> {$domainExpressionAccess.st}
744     ;
745     
746 expression
747     :   ^(EXPR expr)
748         -> {$expr.st}
749     |   domainExpression[null]
750         -> {$domainExpression.st}
751     ;
752
753 expr
754     :   ^(ASSIGNMENT e1=expr e2=expr)
755         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> = <e2>"
756     |   ^('+=' e1=expr e2=expr)
757         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> += <e2>"
758     |   ^('-=' e1=expr e2=expr)
759         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> -= <e2>"
760     |   ^('*=' e1=expr e2=expr)
761         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> *= <e2>"
762     |   ^('/=' e1=expr e2=expr)
763         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> /= <e2>"
764     |   ^('&=' e1=expr e2=expr)
765         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> &= <e2>"
766     |   ^('|=' e1=expr e2=expr)
767         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> |= <e2>"
768     |   ^('^=' e1=expr e2=expr)
769         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> ^= <e2>"
770     |   ^('%=' e1=expr e2=expr)
771         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> %= <e2>"
772     |   ^('>>>=' e1=expr e2=expr)
773         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>\>= <e2>"
774     |   ^('>>=' e1=expr e2=expr)
775         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>= <e2>"
776     |   ^('<<=' e1=expr e2=expr)
777         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<\<= <e2>"
778     |   ^('?' e1=expr e2=expr e3=expr)
779         -> template(e1={$e1.st}, e2={$e2.st}, e3={$e3.st}) "<e1> ? <e2> : <e3>"
780     |   ^('||' e1=expr e2=expr)
781         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> || <e2>"
782     |   ^('&&' e1=expr e2=expr)
783         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> && <e2>"
784     |   ^(BITWISE_OR e1=expr e2=expr)
785         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> | <e2>"
786     |   ^('^' e1=expr e2=expr)
787         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> ^ <e2>"
788     |   ^('&' e1=expr e2=expr)
789         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> & <e2>"
790     |   ^(EQUALS e1=expr e2=expr)
791         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> == <e2>"
792     |   ^('!=' e1=expr e2=expr)
793         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> != <e2>"
794     |   ^('instanceof' expr type)
795         -> template(t={$text}) "/* instanceof not implemented */ <t>"
796     |   ^('<=' e1=expr e2=expr)
797         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<= <e2>"
798     |   ^('>=' e1=expr e2=expr)
799         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>= <e2>"
800     |   ^('>>>' e1=expr e2=expr)
801         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>\> <e2>"
802     |   ^('>>' e1=expr e2=expr)
803         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\> <e2>"
804     |   ^('>' e1=expr e2=expr)
805         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \> <e2>"
806     |   ^('<<' e1=expr e2=expr)
807         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<\< <e2>"
808     |   ^('<' e1=expr e2=expr)
809         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \< <e2>"
810     |   ^('+' e1=expr e2=expr)
811         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> + <e2>"
812     |   ^('-' e1=expr e2=expr)
813         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> - <e2>"
814     |   ^('*' e1=expr e2=expr)
815         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> * <e2>"
816     |   ^('/' e1=expr e2=expr)
817         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> / <e2>"
818     |   ^('%' e1=expr e2=expr)
819         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> % <e2>"
820     |   ^(UNARY_PLUS e1=expr)
821         -> template(e1={$e1.st}) "+<e1>"
822     |   ^(UNARY_MINUS e1=expr)
823         -> template(e1={$e1.st}) "-<e1>"
824     |   ^(PRE_INC e1=expr)
825         -> template(e1={$e1.st}) "++<e1>"
826     |   ^(PRE_DEC e1=expr)
827         -> template(e1={$e1.st}) "--<e1>"
828     |   ^(POST_INC e1=expr)
829         -> template(e1={$e1.st}) "<e1>++"
830     |   ^(POST_DEC e1=expr)
831         -> template(e1={$e1.st}) "<e1>--"
832     |   ^(TILDE e1=expr)
833         -> template(e1={$e1.st}) "~<e1>"
834     |   ^(NOT e1=expr)
835         -> template(e1={$e1.st}) "!<e1>"
836     |   ^(CAST_EXPR ty=type e1=expr)
837         -> template(ty={$ty.st}, e1={$e1.st}) "(<ty>)<e1>"
838     |   primaryExpression
839         -> {$primaryExpression.st}
840     |   ^(POINTER_DEREFERENCE e1 = expr)
841         ->  template(e = {$e1.st}) "*(<e>)"
842     ;
843
844 primaryExpression
845 @init { int dims = 1; }
846     :   ^(DOT prim=primaryExpression
847             ( IDENT   -> template(id={$IDENT.text}, prim={$prim.st}) "<prim>.<id>"
848             | THIS    -> template(prim={$prim.st}) "<prim>.this"
849             | SUPER   -> template(prim={$prim.st}) "<prim>.super"
850             )
851         )
852     |   ^(ARROW prim=primaryExpression
853             ( IDENT   -> template(id={$IDENT.text}, prim={$prim.st}) "<prim>-><id>"
854             | THIS    -> template(prim={$prim.st}) "<prim>->this"
855             | SUPER   -> template(prim={$prim.st}) "<prim>->super"
856             )
857         )
858     |   parenthesizedExpression
859         -> {$parenthesizedExpression.st}
860     |   IDENT
861         -> {%{$IDENT.text}}
862     |   CHELPER
863         -> {%{"constructorHelper"}}
864     |   ^(METHOD_CALL pe=primaryExpression gtal=genericTypeArgumentList? args=arguments)
865         -> method_call(primary={$pe.st}, generic_types={$gtal.st}, args={$args.st})
866     |   ^(ENTRY_METHOD_CALL pe=primaryExpression gtal=genericTypeArgumentList? args=arguments)
867         -> method_call(primary={$pe.st}, generic_types={$gtal.st}, args={$args.st})
868     |   explicitConstructorCall
869         -> {$explicitConstructorCall.st}
870     |   ^(ARRAY_ELEMENT_ACCESS pe=primaryExpression ex=expressionArrayAccess) {
871             if ($pe.start.symbolType != null && $pe.start.symbolType instanceof PointerType) {
872                 PointerType p = (PointerType)($pe.start.symbolType);
873                 if (p.baseType instanceof ClassSymbol) {
874                     ClassSymbol cs = (ClassSymbol)(p.baseType);
875                     if (cs.templateArgs != null && cs.templateArgs.size() > 1 &&
876                         cs.templateArgs.get(1) instanceof LiteralType) {
877                         LiteralType l = (LiteralType)(cs.templateArgs.get(1));
878                         dims = Integer.valueOf(l.literal);
879                     }
880                 }
881             }
882         }
883         -> {$pe.start.symbolType != null && $pe.start.symbolType instanceof PointerType && dims == 1}?
884                template(pe={$pe.st}, ex={$ex.st}) "(*(<pe>))[<ex>]"
885         -> {$pe.start.symbolType != null && $pe.start.symbolType instanceof PointerType && dims == 2}?
886                template(pe={$pe.st}, ex={$ex.st}) "(*(<pe>)).access(<ex>)"
887         -> template(pe={$pe.st}, ex={$ex.st}) "(<pe>)[<ex>]"
888     |   literal
889         -> {$literal.st}
890     |   newExpression[null]
891         -> {$newExpression.st}
892     |   THIS
893         -> {%{$start.getText()}}
894     |   arrayTypeDeclarator
895         -> {$arrayTypeDeclarator.st}
896     |   SUPER
897         -> {%{$start.getText()}}
898     |   GETNUMPES
899         ->  template() "CkNumPes()"
900     |   GETNUMNODES
901         ->  template() "CkNumNodes()"
902     |   GETMYPE
903         ->  template() "CkMyPe()"
904     |   GETMYNODE
905         ->  template() "CkMyNode()"
906     |   GETMYRANK
907         ->  template() "CkMyRank()"
908     |   domainExpression[null]
909         ->  {$domainExpression.st}
910     ;
911     
912 explicitConstructorCall
913     :   ^(THIS_CONSTRUCTOR_CALL genericTypeArgumentList? arguments)
914         -> template(t={$text}) "<t>"
915     |   ^(SUPER_CONSTRUCTOR_CALL primaryExpression? genericTypeArgumentList? arguments)
916         -> template(t={$text}) "<t>"
917     ;
918
919 arrayTypeDeclarator
920     :   ^(ARRAY_DECLARATOR (arrayTypeDeclarator | qualifiedIdentifier | primitiveType))
921         -> template(t={$text}) "<t>"
922     ;
923
924 newExpression[StringTemplate obtype]
925     :   ^(NEW_EXPRESSION arguments? domainExpression[$arguments.args])
926         -> template(domain={$domainExpression.st},type={$obtype}) "new <type>(<domain>)"
927     |   ^(NEW proxyType arguments)
928         -> template(t={$proxyType.st}, a={$arguments.st}) "<t>::ckNew(<a>)"
929     |   ^(NEW nonProxyType arguments)
930         -> template(q={$nonProxyType.st}, a={$arguments.st}) "new <q>(<a>)"
931     ;
932
933 arguments returns [List<StringTemplate> args]
934 @init {
935     $args = new ArrayList<StringTemplate>();
936 }
937     :   ^(ARGUMENT_LIST (e=expression { $args.add($e.st); } )*)        
938         ->  arguments(exprs={$args})
939     ;
940
941 literal
942 @init {
943 $st = %{$start.getText()};
944 }
945     :   HEX_LITERAL
946     |   OCTAL_LITERAL
947     |   DECIMAL_LITERAL
948     |   FLOATING_POINT_LITERAL
949     |   CHARACTER_LITERAL
950     |   STRING_LITERAL
951     |   TRUE
952     |   FALSE
953     |   NULL
954     ;
955