add206306f72c2459e9eb5533e8e93da63bd1dd2
[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     boolean sdagMethod = false;
229 }
230     :   ^(FUNCTION_METHOD_DECL m=modifierList? g=genericTypeParameterList? 
231             ty=type IDENT f=formalParameterList
232             { currentMethod = (MethodSymbol)$IDENT.def; }
233             b=block?)
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         -> {emitCI()}?  funcMethodDecl_ci(
255                 modl={$m.st}, 
256                 gtpl={$g.st}, 
257                 ty={$ty.st},
258                 id={$IDENT.text}, 
259                 fpl={$f.st}, 
260                 block={null})
261         ->
262     |   ^(ENTRY_FUNCTION_DECL m=modifierList? g=genericTypeParameterList? 
263             ty=type IDENT f=formalParameterList a=domainExpression[null]? 
264             {
265                 currentMethod = (MethodSymbol)$IDENT.def;
266                 sdagMethod = currentMethod.hasSDAG;
267             }
268             b=block) 
269         -> {emitCC()}? funcMethodDecl_cc(
270                 classSym={currentClass},
271                 methodSym={currentMethod},
272                 modl={$m.st}, 
273                 gtpl={$g.st}, 
274                 ty={$ty.st},
275                 id={$IDENT.text}, 
276                 fpl={$f.st}, 
277                 adl={$a.st},
278                 block={$b.st})
279         -> {emitH()}? funcMethodDecl_h(
280                 modl={$m.st}, 
281                 gtpl={$g.st}, 
282                 ty={$ty.st},
283                 id={$IDENT.text}, 
284                 fpl={$f.st}, 
285                 adl={$a.st},
286                 block={$b.st})
287         -> {emitCI()}? funcMethodDecl_ci(
288                 modl={$m.st}, 
289                 gtpl={$g.st}, 
290                 ty={$ty.st},
291                 id={$IDENT.text}, 
292                 fpl={$f.st}, 
293                 block={$b.st})
294         ->
295     |   ^(SDAG_FUNCTION_DECL m=modifierList? g=genericTypeParameterList? 
296             ty=type IDENT f=formalParameterList a=domainExpression[null]? 
297             {
298             currentMethod = (MethodSymbol)$IDENT.def;
299             sdagMethod = currentMethod.hasSDAG;
300             }
301             ^(BLOCK (sdg+=sdagBasicBlock)*))
302             //sdgb=nakedSdagBlock?) 
303         -> {emitCI()}? funcMethodDecl_sdag_ci(
304                 classSym={currentClass},
305                 methodSym={currentMethod},
306                 modl={$m.st}, 
307                 gtpl={$g.st}, 
308                 ty={$ty.st},
309                 id={$IDENT.text}, 
310                 fpl={$f.st}, 
311                 adl={$a.st},
312                 block={$sdg})
313         ->
314     |   ^(DIVCON_METHOD_DECL modifierList? type IDENT formalParameterList divconBlock)
315     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList[null])
316         -> {emitH()}? class_var_decl(
317             modl={$modifierList.st},
318             type={$simpleType.st},
319             declList={$variableDeclaratorList.st})
320         ->
321     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList[$objectType.st])
322         -> {emitH()}? class_var_decl(
323             modl={$modifierList.st},
324             type={$objectType.st},
325             declList={$variableDeclaratorList.st})
326         ->
327     |   ^(CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList
328             {
329                 currentMethod = (MethodSymbol)$IDENT.def;
330             }
331             b=block)
332         -> {emitCC()}? ctorDecl_cc(
333                 modl={$m.st},
334                 gtpl={$g.st}, 
335                 id={$IDENT.text}, 
336                 fpl={$f.st}, 
337                 block={$b.st})
338         -> {emitCI()}? // do nothing, it's not an entry constructor
339         -> {emitH()}? ctorDecl_h(
340                 modl={$m.st},
341                 gtpl={$g.st}, 
342                 id={$IDENT.text}, 
343                 fpl={$f.st}, 
344                 block={$b.st})
345         ->
346     |   ^(ENTRY_CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList
347             {
348                 currentMethod = (MethodSymbol)$IDENT.def;
349                 migrationCtor = currentClass.migrationCtor == $ENTRY_CONSTRUCTOR_DECL;
350             }
351             b=block)
352         -> {emitCC()}? ctorDecl_cc(
353                 modl={$m.st},
354                 gtpl={$g.st}, 
355                 id={$IDENT.text}, 
356                 fpl={$f.st}, 
357                 block={$b.st})
358         -> {emitCI() && !migrationCtor}? ctorDecl_ci(
359                 modl={$m.st},
360                 gtpl={$g.st}, 
361                 id={$IDENT.text}, 
362                 fpl={$f.st}, 
363                 block={$b.st})
364         -> {emitH()}? ctorDecl_h(
365                 modl={$m.st},
366                 gtpl={$g.st}, 
367                 id={$IDENT.text}, 
368                 fpl={$f.st}, 
369                 block={$b.st})
370         ->
371     ;
372     
373 interfaceScopeDeclaration
374     :   ^(FUNCTION_METHOD_DECL modifierList? genericTypeParameterList? type IDENT formalParameterList)
375         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
376     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList[$simpleType.st])
377         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
378     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList[$objectType.st])
379         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
380     ;
381
382 variableDeclaratorList[StringTemplate obtype]
383     :   ^(VAR_DECLARATOR_LIST (var_decls+=variableDeclarator[obtype])+ )
384         -> var_decl_list(var_decls={$var_decls})
385     ;
386
387 variableDeclarator[StringTemplate obtype]
388     :   ^(VAR_DECLARATOR id=variableDeclaratorId initializer=variableInitializer[obtype]?)
389         -> {emitCC()}? var_decl_cc(id={$id.st}, initializer={$initializer.st})
390         -> {emitH()}?  var_decl_h(id={$id.st}, initializer={$initializer.st})
391         -> {emitCI()}? var_decl_ci(id={$id.st}, initializer={$initializer.st})
392         ->
393     ; 
394     
395 variableDeclaratorId
396     :   ^(IDENT de=domainExpression[null]?)
397         -> var_decl_id(id={$IDENT.text}, domainExp={$de.st})
398     ;
399
400 variableInitializer[StringTemplate obtype]
401     :   arrayInitializer
402         -> {$arrayInitializer.st}
403     |   newExpression[obtype]
404         -> {$newExpression.st}
405     |   expression
406         -> {$expression.st}
407     ;
408
409 rangeItem
410     :   dl=DECIMAL_LITERAL
411         -> template(t={$dl.text}) "<t>"
412     |   IDENT
413         -> template(t={$IDENT.text}) "<t>"
414     ;
415
416 rangeExpression
417     :   ^(RANGE_EXPRESSION (ri+=rangeItem)*)
418         -> template(t={$ri}) "Range(<t; separator=\",\">)"
419     ;
420
421 rangeList returns [int len]
422     :   (r+=rangeExpression)*
423         { $len = $r.size(); }
424         -> template(t={$r}) "<t; separator=\", \">"
425     ;
426
427 domainExpression[List<StringTemplate> otherParams]
428     :   ^(DOMAIN_EXPRESSION rl=rangeList)
429         -> range_constructor(range={$rl.st}, others={$otherParams}, len={$rl.len})
430     ;
431
432 domainExpressionAccess
433     :   ^(DOMAIN_EXPRESSION rl=rangeListAccess)
434         -> template(t={$rangeListAccess.st}) "<t>"
435     ;
436
437 rangeListAccess
438     :   (r+=rangeExpressionAccess)*
439         -> template(t={$r}) "<t; separator=\", \">"
440     ;
441
442 rangeExpressionAccess
443     :   ^(RANGE_EXPRESSION (ri+=rangeItem)*)
444         -> template(t={$ri}) "<t; separator=\",\">"
445     ;
446
447 arrayInitializer
448     :   ^(ARRAY_INITIALIZER variableInitializer[null]*)
449         -> template(t={$text}) "/* arrayInitializer-not implemented */ <t>"
450     ;
451
452 genericTypeParameterList
453     :   ^(GENERIC_TYPE_PARAM_LIST genericTypeParameter+)
454         -> template(t={$text}) "/*GENERIC_TYPE_PARAM_LIST-not implemented*/ <t>"
455     ;
456
457 genericTypeParameter
458     :   ^(IDENT bound?)
459         -> template(t={$text}) "/*genericTypeParameter-not implemented*/ <t>"
460     ;
461         
462 bound
463     :   ^(EXTENDS_BOUND_LIST type+)
464         -> template(t={$text}) "/*EXTENDS_BOUND_LIST-not implemented*/ <t>"
465     ;
466
467 throwsClause
468     :   ^(THROWS_CLAUSE qualifiedIdentifier+)
469         -> template(t={$text}) "/* throwsClause-not implemented */ <t>"
470     ;
471
472 modifierList
473     :   ^(MODIFIER_LIST accessModifierList localModifierList charjModifierList otherModifierList)
474         ->  {emitCC()}? mod_list_cc(accmods = {$accessModifierList.names}, localmods = {$localModifierList.names}, charjmods = {$charjModifierList.names}, othermods = {$otherModifierList.names})
475         ->  {emitH()}? mod_list_h(accmods = {$accessModifierList.names}, localmods = {$localModifierList.names}, charjmods = {$charjModifierList.names}, othermods = {$otherModifierList.names})
476         ->  {emitCI()}? mod_list_ci(accmods = {$accessModifierList.names}, localmods = {$localModifierList.names}, charjmods = {$charjModifierList.names}, othermods = {$otherModifierList.names})
477         ->
478     ;
479
480 modifier
481     :   accessModifier
482     |   localModifier
483     |   charjModifier
484     |   otherModifier
485     ;
486
487 accessModifierList
488 returns [List names]
489     :   ^(ACCESS_MODIFIER_LIST (m+=accessModifier)*)
490         {
491             $names = $m;
492         }
493     ;
494 localModifierList
495 returns [List names]
496     :   ^(LOCAL_MODIFIER_LIST (m+=localModifier)*)
497         {
498             $names = $m;
499         }
500         ->  local_mod_list(mods = {$names})
501     ;
502
503 charjModifierList
504 returns [List names]
505     :   ^(CHARJ_MODIFIER_LIST (m+=charjModifier)*)
506         {
507             $names = $m;
508         }
509     ;
510
511 otherModifierList
512 returns [List names]
513     :   ^(OTHER_MODIFIER_LIST (m+=otherModifier)*)
514         {
515             $names = $m;
516         }
517     ;
518     
519 localModifier
520 @init
521 {
522     $st = %{$start.getText()};
523 }
524     :   FINAL
525     |   STATIC
526     |   VOLATILE
527     ;
528
529 accessModifier
530 @init
531 {
532     $st = %{$start.getText()};
533 }
534     :   PUBLIC
535     |   PROTECTED
536     |   PRIVATE
537         {
538             $st = %{"private"};
539         }
540     ;
541
542 charjModifier
543     :   ENTRY -> {%{$ENTRY.text}}
544     |   SDAGENTRY -> template() "entry"
545     |   TRACED
546     ;
547
548 otherModifier
549 @init
550 {
551     $st = %{$start.getText()};
552 }
553     :   ABSTRACT
554     |   NATIVE
555     ;
556     
557 type
558     :   simpleType
559         -> {$simpleType.st}
560     |   objectType 
561         -> {$objectType.st}
562     |   VOID
563         {
564             $st = %{"void"};
565         }
566     ;
567
568 simpleType
569     :   ^(SIMPLE_TYPE primitiveType domainExpression[null]?)
570         -> simple_type(typeID={$primitiveType.st}, arrDeclList={$domainExpression.st})
571     ;
572
573 objectType //[boolean forNewExpression]
574     : proxyType -> {$proxyType.st;}
575     | nonProxyType -> {$nonProxyType.st}
576     ;
577
578 nonProxyType
579     :   ^(OBJECT_TYPE qualifiedTypeIdent domainExpression[null]?)
580         -> obj_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$domainExpression.st})
581     |   ^(POINTER_TYPE qualifiedTypeIdent domainExpression[null]?)
582         -> pointer_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$domainExpression.st})
583     |   ^(REFERENCE_TYPE qualifiedTypeIdent domainExpression[null]?)
584         -> reference_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$domainExpression.st})
585     ;
586
587 proxyType
588     :   ^(PROXY_TYPE qualifiedTypeIdent domainExpression[null]?)
589         -> proxy_type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$domainExpression.st})
590         |       ^(ARRAY_SECTION_TYPE qualifiedTypeIdent domainExpression[null]?) // TODO array sections
591                 -> template() "not implemented yet"
592     ;
593
594 qualifiedTypeIdent returns [ClassSymbol type]
595     :   ^(QUALIFIED_TYPE_IDENT (t+=typeIdent)+)
596         {$type = (ClassSymbol)$QUALIFIED_TYPE_IDENT.def;}
597         -> template(types={$t}) "<types; separator=\"::\">"
598     ;
599
600 typeIdent
601     :   ^(IDENT templateInstantiation?)
602         -> typeIdent(typeID={$IDENT.text}, generics={$templateInstantiation.st})
603     ;
604
605 primitiveType
606 @init {
607 $st = %{$start.getText()};
608 }
609     :   BOOLEAN
610         -> template() "bool"
611     |   CHAR
612     |   BYTE
613         -> template() "char"
614     |   SHORT
615     |   INT
616     |   LONG
617     |   FLOAT
618     |   DOUBLE
619     ;
620
621 templateArg
622     :   genericTypeArgument
623         -> {$genericTypeArgument.st}
624     |   literal
625         -> {$literal.st}
626     ;
627
628 templateArgList
629     :   params+=templateArg+
630         -> template(params={$params}) "<params; separator=\", \">"
631     ;
632
633 templateInstantiation
634     :   ^(TEMPLATE_INST templateArgList)
635         -> template(args={$templateArgList.st}) "\<<args>\>"
636     |   ^(TEMPLATE_INST ts=templateInstantiation)
637         -> template(inst={$ts.st}) "\<<inst>\>"
638     ;
639
640 genericTypeArgumentList
641     :   ^(GENERIC_TYPE_ARG_LIST (gta+=genericTypeArgument)+)
642         -> template(gtal={$gta}) "\<<gtal; separator=\", \">\>"
643     ;
644
645 genericTypeArgument
646     :   type
647         -> {$type.st}
648     |   '?'
649         -> template(t={$text}) "/* genericTypeArgument: wildcard bound types not implemented */ <t>"
650     ;
651
652 formalParameterList
653     :   ^(FORMAL_PARAM_LIST (fpsd+=formalParameterStandardDecl)* fpvd=formalParameterVarargDecl?)
654         -> formal_param_list(sdecl={$fpsd}, vdecl={$fpvd.st})
655     ;
656     
657 formalParameterStandardDecl
658     :   ^(FORMAL_PARAM_STD_DECL lms=localModifierList? t=type vdid=variableDeclaratorId)
659         -> formal_param_decl(modList={$lms.st}, type={$t.st}, declID={$vdid.st})
660     ;
661     
662 formalParameterVarargDecl
663     :   ^(FORMAL_PARAM_VARARG_DECL localModifierList? type variableDeclaratorId)
664         -> template(t={$text}) "/*formal parameter varargs not implemented*/ <t>"
665     ;
666     
667 qualifiedIdentifier
668     :   IDENT
669         -> template(t={$text}) "<t>"
670     |   ^(DOT qualifiedIdentifier IDENT)
671         -> template(t={$text}) "<t>"
672     ;
673     
674 block
675 @init { boolean emptyBlock = true; }
676     :   ^(BLOCK (b+=blockStatement)*)
677         { emptyBlock = ($b == null || $b.size() == 0); }
678         -> {((emitCC() && (currentMethod == null || !currentMethod.hasSDAG)) ||
679             (emitCI() && (currentMethod != null && currentMethod.hasSDAG))) && emptyBlock}? template(bsl={$b}) "{ }"
680         -> {emitCC() && (currentMethod == null || !currentMethod.hasSDAG)}? block_cc(bsl={$b})
681         -> {emitCI() && (currentMethod != null && currentMethod.hasSDAG)}? block_cc(bsl={$b})
682         ->
683     ;
684
685
686 nakedSdagBlock
687     :   ^(BLOCK (sdg+=sdagBasicBlock)*)
688         -> template(sdg={$sdg}) "<sdg>"
689     ;
690
691
692 sdagBlock
693     :   ^(BLOCK (sdg+=sdagBasicBlock)*)
694         -> block_cc(bsl={$sdg})
695     ;
696
697 sdagBasicBlock
698     :   sdagStatement
699         -> {$sdagStatement.st}
700     |   (s+=statement)+
701         -> block_atomic(s={$s})
702     ;
703     
704 blockStatement
705     :   localVariableDeclaration
706         -> {$localVariableDeclaration.st}
707     |   statement
708         -> {$statement.st}
709     ;
710
711
712 localVariableDeclaration
713     :   ^(PRIMITIVE_VAR_DECLARATION localModifierList? simpleType vdl=variableDeclaratorList[null])
714         -> local_var_decl(
715             modList={$localModifierList.st},
716             type={$simpleType.st},
717             declList={$vdl.st})
718     |   ^(OBJECT_VAR_DECLARATION localModifierList? objectType vdl=variableDeclaratorList[$objectType.st])
719         -> local_var_decl(
720             modList={$localModifierList.st},
721             type={$objectType.st},
722             declList={$vdl.st})
723     ;
724
725
726 statement
727     :   nonBlockStatement
728         -> {$nonBlockStatement.st}
729     |   block
730         -> {$block.st}
731     ;
732
733 divconBlock
734     :   ^(DIVCON_BLOCK divconExpr)
735     ;
736
737 divconAssignment
738     :   ^(LET_ASSIGNMENT IDENT expression)
739     ;
740
741 divconAssignmentList
742     :   divconAssignment+
743     ;
744
745 divconExpr
746     :   ^(IF parenthesizedExpression divconExpr divconExpr?)
747     |   ^(LET divconAssignmentList IN divconExpr)
748     |   expression
749     ;
750
751 sdagStatement
752     :   ^(OVERLAP sdagBlock)
753         -> template(b={$sdagBlock.st}) "overlap <b>"
754     |   ^(WHEN (wa+=whenArgument)* nakedSdagBlock)
755         -> template(w={wa}, b={$nakedSdagBlock.st}) "when <w> <b>"
756     |   ^(SDAG_IF pe=parenthesizedExpression
757             ifblock=sdagBlock elseblock=sdagBlock?)
758         -> if(cond={$pe.st}, then={$ifblock.st}, else_={$elseblock.st})
759     |   ^(SDAG_FOR forInit? FOR_EXPR cond=expression?
760             FOR_UPDATE (update+=expression)* b=sdagBlock)
761         -> for(initializer={$forInit.st}, cond={$cond.st},
762                 update={$update}, body={$b.st})
763     |   ^(SDAG_WHILE pe=parenthesizedExpression b=sdagBlock)
764         -> while(cond={$pe.st}, body={$b.st})
765     |   ^(SDAG_DO b=sdagBlock pe=parenthesizedExpression)
766         -> dowhile(cond={$pe.st}, block={$b.st})
767     ;
768
769 whenArgument
770     :   IDENT expression? formalParameterList
771         -> template(i={$IDENT}, e={$expression.st}, f={$formalParameterList.st}) "<i> <if(e)>[<e>] <endif><f>"
772     ;
773
774 nonBlockStatement
775     :   ^(ASSERT cond=expression msg=expression?)
776         -> assert(cond={$cond.st}, msg={$msg.st})
777     |   ^(IF parenthesizedExpression then=block else_=block?)
778         -> if(cond={$parenthesizedExpression.st}, then={$then.st}, else_={$else_.st})
779     |   ^(FOR forInit? FOR_EXPR cond=expression? FOR_UPDATE (update+=expression)* b=block)
780         -> for(initializer={$forInit.st}, cond={$cond.st}, update={$update}, body={$block.st})
781     |   ^(FOR_EACH localModifierList? type IDENT expression block) 
782         -> template(t={$text}) "/* foreach not implemented */ <t>"
783     |   ^(WHILE pe=parenthesizedExpression b=block)
784         -> while(cond={$pe.st}, body={$b.st})
785     |   ^(DO b=block pe=parenthesizedExpression)
786         -> dowhile(cond={$pe.st}, block={$b.st})
787     |   ^(SWITCH pe=parenthesizedExpression (scls+=switchCaseLabel)*)
788         -> switch(expr={$pe.st}, labels={$scls})
789     |   ^(RETURN e=expression?)
790         -> return(val={$e.st})
791     |   ^(THROW expression)
792         -> template(t={$text}) "/* throw not implemented */ <t>"
793     |   ^(BREAK IDENT?)
794         -> template() "break;" // TODO: support labeling
795     |   ^(CONTINUE IDENT?)
796         -> template() "continue;" // TODO: support labeling
797     |   ^(LABELED_STATEMENT i=IDENT s=statement)
798         -> label(text={$i.text}, stmt={$s.st})
799     |   expression
800         -> template(expr={$expression.st}) "<expr>;"
801     |   ^('delete' expression)
802         -> template(t={$expression.st}) "delete <t>;"
803     |   ^('embed' STRING_LITERAL EMBED_BLOCK)
804         ->  embed_cc(str={$STRING_LITERAL.text}, blk={$EMBED_BLOCK.text})
805     |   ';' // Empty statement.
806         -> {%{$start.getText()}}
807     |   ^(PRINT (exprs += expression)*)
808         ->  print(exprs = {$exprs})
809     |   ^(PRINTLN (exprs += expression)*)
810         ->  println(exprs = {$exprs})
811     |   ^(EXIT expression?)
812         ->  exit(expr = {$expression.st})
813     |   EXITALL
814         ->  exitall()
815     ;
816         
817 switchCaseLabel
818     :   ^(CASE expression (b+=blockStatement)*)
819         -> case(expr={$expression.st}, block={$b})
820     |   ^(DEFAULT (b+=blockStatement)*)
821         -> template(block={$b}) "default: <block>"
822     ;
823     
824 forInit
825     :   localVariableDeclaration
826         -> template(lvd={$localVariableDeclaration.st}) "<lvd>"
827     |   (ex+=expression)+
828         -> template(ex={$ex}) "<ex; separator=\", \">"
829     ;
830
831 // EXPRESSIONS
832
833 parenthesizedExpression
834     :   ^(PAREN_EXPR exp=expression)
835         -> template(expr={$exp.st}) "(<expr>)"
836     ;
837
838 expressionArrayAccess
839     :   ^(EXPR expr)
840         -> {$expr.st}
841     |    domainExpressionAccess
842         -> {$domainExpressionAccess.st}
843     ;
844     
845 expression
846     :   ^(EXPR expr)
847         -> {$expr.st}
848     |   domainExpression[null]
849         -> {$domainExpression.st}
850     ;
851
852 expr
853     :   ^(ASSIGNMENT e1=expr e2=expr)
854         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> = <e2>"
855     |   ^('+=' e1=expr e2=expr)
856         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> += <e2>"
857     |   ^('-=' e1=expr e2=expr)
858         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> -= <e2>"
859     |   ^('*=' e1=expr e2=expr)
860         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> *= <e2>"
861     |   ^('/=' e1=expr e2=expr)
862         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> /= <e2>"
863     |   ^('&=' e1=expr e2=expr)
864         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> &= <e2>"
865     |   ^('|=' e1=expr e2=expr)
866         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> |= <e2>"
867     |   ^('^=' e1=expr e2=expr)
868         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> ^= <e2>"
869     |   ^('%=' e1=expr e2=expr)
870         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> %= <e2>"
871     |   ^('>>>=' e1=expr e2=expr)
872         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>\>= <e2>"
873     |   ^('>>=' e1=expr e2=expr)
874         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>= <e2>"
875     |   ^('<<=' e1=expr e2=expr)
876         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<\<= <e2>"
877     |   ^('?' e1=expr e2=expr e3=expr)
878         -> template(e1={$e1.st}, e2={$e2.st}, e3={$e3.st}) "<e1> ? <e2> : <e3>"
879     |   ^('||' e1=expr e2=expr)
880         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> || <e2>"
881     |   ^('&&' e1=expr e2=expr)
882         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> && <e2>"
883     |   ^(BITWISE_OR e1=expr e2=expr)
884         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> | <e2>"
885     |   ^('^' e1=expr e2=expr)
886         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> ^ <e2>"
887     |   ^('&' e1=expr e2=expr)
888         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> & <e2>"
889     |   ^(EQUALS e1=expr e2=expr)
890         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> == <e2>"
891     |   ^('!=' e1=expr e2=expr)
892         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> != <e2>"
893     |   ^('instanceof' expr type)
894         -> template(t={$text}) "/* instanceof not implemented */ <t>"
895     |   ^('<=' e1=expr e2=expr)
896         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<= <e2>"
897     |   ^('>=' e1=expr e2=expr)
898         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>= <e2>"
899     |   ^('>>>' e1=expr e2=expr)
900         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>\> <e2>"
901     |   ^('>>' e1=expr e2=expr)
902         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\> <e2>"
903     |   ^('>' e1=expr e2=expr)
904         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \> <e2>"
905     |   ^('<<' e1=expr e2=expr)
906         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<\< <e2>"
907     |   ^('<' e1=expr e2=expr)
908         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \< <e2>"
909     |   ^('+' e1=expr e2=expr)
910         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> + <e2>"
911     |   ^('-' e1=expr e2=expr)
912         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> - <e2>"
913     |   ^('*' e1=expr e2=expr)
914         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> * <e2>"
915     |   ^('/' e1=expr e2=expr)
916         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> / <e2>"
917     |   ^('%' e1=expr e2=expr)
918         -> template(e1={$e1.st}, e2={$e2.st}) "<e1> % <e2>"
919     |   ^(UNARY_PLUS e1=expr)
920         -> template(e1={$e1.st}) "+<e1>"
921     |   ^(UNARY_MINUS e1=expr)
922         -> template(e1={$e1.st}) "-<e1>"
923     |   ^(PRE_INC e1=expr)
924         -> template(e1={$e1.st}) "++<e1>"
925     |   ^(PRE_DEC e1=expr)
926         -> template(e1={$e1.st}) "--<e1>"
927     |   ^(POST_INC e1=expr)
928         -> template(e1={$e1.st}) "<e1>++"
929     |   ^(POST_DEC e1=expr)
930         -> template(e1={$e1.st}) "<e1>--"
931     |   ^(TILDE e1=expr)
932         -> template(e1={$e1.st}) "~<e1>"
933     |   ^(NOT e1=expr)
934         -> template(e1={$e1.st}) "!<e1>"
935     |   ^(CAST_EXPR ty=type e1=expr)
936         -> template(ty={$ty.st}, e1={$e1.st}) "(<ty>)<e1>"
937     |   primaryExpression
938         -> {$primaryExpression.st}
939     |   ^(POINTER_DEREFERENCE e1 = expr)
940         ->  template(e = {$e1.st}) "*(<e>)"
941     ;
942
943 primaryExpression
944 @init { int dims = 1; }
945     :   ^(DOT prim=primaryExpression
946             ( IDENT   -> template(id={$IDENT.text}, prim={$prim.st}) "<prim>.<id>"
947             | THIS    -> template(prim={$prim.st}) "<prim>.this"
948             | SUPER   -> template(prim={$prim.st}) "<prim>.super"
949             )
950         )
951     |   ^(ARROW prim=primaryExpression
952             ( IDENT   -> template(id={$IDENT.text}, prim={$prim.st}) "<prim>-><id>"
953             | THIS    -> template(prim={$prim.st}) "<prim>->this"
954             | SUPER   -> template(prim={$prim.st}) "<prim>->super"
955             )
956         )
957     |   parenthesizedExpression
958         -> {$parenthesizedExpression.st}
959     |   IDENT
960         -> {%{$IDENT.text}}
961     |   CHELPER
962         -> {%{"constructorHelper"}}
963     |   ^(METHOD_CALL pe=primaryExpression gtal=genericTypeArgumentList? args=arguments)
964         -> method_call(primary={$pe.st}, generic_types={$gtal.st}, args={$args.st})
965     |   ^(ENTRY_METHOD_CALL pe=primaryExpression gtal=genericTypeArgumentList? args=arguments)
966         -> method_call(primary={$pe.st}, generic_types={$gtal.st}, args={$args.st})
967     |   explicitConstructorCall
968         -> {$explicitConstructorCall.st}
969     |   ^(ARRAY_ELEMENT_ACCESS pe=primaryExpression ex=expressionArrayAccess) {
970             if ($pe.start.symbolType != null && $pe.start.symbolType instanceof PointerType) {
971                 PointerType p = (PointerType)($pe.start.symbolType);
972                 if (p.baseType instanceof ClassSymbol) {
973                     ClassSymbol cs = (ClassSymbol)(p.baseType);
974                     if (cs.templateArgs != null && cs.templateArgs.size() > 1 &&
975                         cs.templateArgs.get(1) instanceof LiteralType) {
976                         LiteralType l = (LiteralType)(cs.templateArgs.get(1));
977                         dims = Integer.valueOf(l.literal);
978                     }
979                 }
980             }
981         }
982         -> {$pe.start.symbolType != null && $pe.start.symbolType instanceof PointerType && dims == 1}?
983                template(pe={$pe.st}, ex={$ex.st}) "(*(<pe>))[<ex>]"
984         -> {$pe.start.symbolType != null && $pe.start.symbolType instanceof PointerType && dims == 2}?
985                template(pe={$pe.st}, ex={$ex.st}) "(*(<pe>)).access(<ex>)"
986         -> template(pe={$pe.st}, ex={$ex.st}) "(<pe>)[<ex>]"
987     |   literal
988         -> {$literal.st}
989     |   newExpression[null]
990         -> {$newExpression.st}
991     |   THIS
992         -> {%{$start.getText()}}
993     |   arrayTypeDeclarator
994         -> {$arrayTypeDeclarator.st}
995     |   SUPER
996         -> {%{$start.getText()}}
997     |   GETNUMPES
998         ->  template() "CkNumPes()"
999     |   GETNUMNODES
1000         ->  template() "CkNumNodes()"
1001     |   GETMYPE
1002         ->  template() "CkMyPe()"
1003     |   GETMYNODE
1004         ->  template() "CkMyNode()"
1005     |   GETMYRANK
1006         ->  template() "CkMyRank()"
1007         |       THISINDEX
1008                 ->      template() "thisIndex"
1009         |       THISPROXY
1010                 ->      template() "thisProxy"
1011     |   domainExpression[null]
1012         ->  {$domainExpression.st}
1013     ;
1014     
1015 explicitConstructorCall
1016     :   ^(THIS_CONSTRUCTOR_CALL genericTypeArgumentList? arguments)
1017         -> template(t={$text}) "<t>"
1018     |   ^(SUPER_CONSTRUCTOR_CALL primaryExpression? genericTypeArgumentList? arguments)
1019         -> template(t={$text}) "<t>"
1020     ;
1021
1022 arrayTypeDeclarator
1023     :   ^(ARRAY_DECLARATOR (arrayTypeDeclarator | qualifiedIdentifier | primitiveType))
1024         -> template(t={$text}) "<t>"
1025     ;
1026
1027 newExpression[StringTemplate obtype]
1028     :   ^(NEW_EXPRESSION arguments? domainExpression[$arguments.args])
1029         -> template(domain={$domainExpression.st},type={$obtype}) "new <type>(<domain>)"
1030     |   ^(NEW proxyType arguments)
1031         -> template(t={$proxyType.st}, a={$arguments.st}) "<t>::ckNew(<a>)"
1032     |   ^(NEW nonProxyType arguments)
1033         -> template(q={$nonProxyType.st}, a={$arguments.st}) "new <q>(<a>)"
1034     ;
1035
1036 arguments returns [List<StringTemplate> args]
1037 @init {
1038     $args = new ArrayList<StringTemplate>();
1039 }
1040     :   ^(ARGUMENT_LIST (e=expression { $args.add($e.st); } )*)        
1041         ->  arguments(exprs={$args})
1042     ;
1043
1044 literal
1045 @init {
1046 $st = %{$start.getText()};
1047 }
1048     :   HEX_LITERAL
1049     |   OCTAL_LITERAL
1050     |   DECIMAL_LITERAL
1051     |   FLOATING_POINT_LITERAL
1052     |   CHARACTER_LITERAL
1053     |   STRING_LITERAL
1054     |   TRUE
1055     |   FALSE
1056     |   NULL
1057     ;
1058