overhaul of statement codegen
[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
37     /**
38      *  Override ANTLR's token mismatch behavior so we throw exceptions early.
39      */
40     protected void mismatch(IntStream input, int ttype, BitSet follow)
41         throws RecognitionException {
42         throw new MismatchedTokenException(ttype, input);
43     }
44
45     /**
46      *  Override ANTLR's set mismatch behavior so we throw exceptions early.
47      */
48     public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow)
49         throws RecognitionException {
50         throw e;
51     }
52
53     /**
54      *  Test a list of CharjAST nodes to see if any of them has the given token
55      *  type.
56      */
57     public boolean listContainsToken(List<CharjAST> list, int tokenType) {
58         if (list == null) return false;
59         for (CharjAST node : list) {
60             if (node.token.getType() == tokenType) {
61                 return true;
62             }
63         }
64         return false;
65     }
66 }
67
68
69 // Replace default ANTLR generated catch clauses with this action, allowing early failure.
70 @rulecatch {
71     catch (RecognitionException re) {
72         reportError(re);
73         throw re;
74     }
75 }
76
77
78 // Starting point for parsing a Charj file.
79 charjSource[SymbolTable symtab, OutputMode m]
80 @init {
81     this.symtab_ = symtab;
82     this.translator_ = symtab.translator;
83     this.mode_ = m;
84     String closingBraces = "";
85 }
86     :   ^(CHARJ_SOURCE (p=packageDeclaration)? 
87         (i+=importDeclaration)* 
88         (t=typeDeclaration))
89         //(t+=typeDeclaration)*)
90         {
91             // construct string of }'s to close namespace 
92             if ($p.st != null) {
93                 String temp_p = $p.st.toString();
94                 for (int idx=0; idx<temp_p.length(); ++idx) {
95                     if (temp_p.charAt(idx) == '{') {
96                         closingBraces += "} ";
97                     }
98                 }
99             }
100         }
101         -> {emitCC()}? charjSource_cc(
102             pd={$p.st}, ids={$i}, tds={$t.st}, cb={closingBraces}, debug={debug()})
103         -> {emitCI()}? charjSource_ci(pd={$p.st}, ids={$i}, tds={$t.st}, debug={debug()})
104         -> {emitH()}? charjSource_h(
105             pd={$p.st}, ids={$i}, tds={$t.st}, cb={closingBraces}, debug={debug()})
106         ->
107     ;
108
109 packageDeclaration
110 @init { 
111     List<String> names = null; 
112 }
113     :   ^(PACKAGE qualifiedIdentifier)  {
114             names =  java.util.Arrays.asList(
115                     $qualifiedIdentifier.text.split("[.]"));
116         }
117         -> {(emitCC() || emitH())}? packageDeclaration_cc_h(
118             ids={names})
119         ->
120     ;
121     
122 importDeclaration
123 @init {
124     String importID = null;
125 }
126     :   ^(IMPORT STATIC? qualifiedIdentifier DOTSTAR?)
127         {
128             importID = $qualifiedIdentifier.text;
129             if ($DOTSTAR != null) {
130             }
131         }
132         {$DOTSTAR == null}? // TODO: add support for importing x.*
133         -> {(emitCC() || emitH())}? importDeclaration_cc_h(
134             inc_id={importID.replace(".","/")},
135             use_id={importID.replace(".","::")})
136         ->
137     ;
138     
139 typeDeclaration
140     :   ^(CLASS m=modifierList IDENT g=genericTypeParameterList? 
141                 e=classExtendsClause? i=implementsClause? c=classTopLevelScope) 
142         -> {emitCC()}? classDeclaration_cc(
143                 mod={$m.st}, 
144                 ident={$IDENT.text}, 
145                 gen={$g.st}, 
146                 ext={$e.st}, 
147                 impl={$i.st},
148                 ctls={$c.st})
149         -> {emitCI()}? classDeclaration_ci(
150                 mod={$m.st}, 
151                 ident={$IDENT.text}, 
152                 gen={$g.st}, 
153                 ext={$e.st}, 
154                 impl={$i.st},
155                 ctls={$c.st})
156         -> {emitH()}? classDeclaration_h(
157                 mod={$m.st}, 
158                 ident={$IDENT.text}, 
159                 gen={$g.st}, 
160                 ext={$e.st}, 
161                 impl={$i.st},
162                 ctls={$c.st})
163         ->
164     |   ^(INTERFACE modifierList IDENT genericTypeParameterList? 
165                 interfaceExtendsClause? interfaceTopLevelScope)
166         -> template(t={$text}) "/*INTERFACE-not implemented*/ <t>"
167     |   ^(ENUM modifierList IDENT implementsClause? enumTopLevelScope)
168         -> template(t={$text}) "/*ENUM-not implemented*/ <t>"
169     ;
170
171
172 classExtendsClause
173     :   ^(EXTENDS_CLAUSE t=type) 
174         -> {emitCC() || emitH()}? classExtends_cc_h(type={$t.st})
175         -> {emitCI()}? classExtends_ci(type={$t.st})
176         ->
177     ;   
178
179 interfaceExtendsClause 
180     :   ^(EXTENDS_CLAUSE (typeList+=type)+) 
181         -> interfaceExtends(ts={$typeList})
182     ;   
183     
184 implementsClause
185     :   ^(IMPLEMENTS_CLAUSE type+)
186         -> template(t={$text}) "/*IMPLEMENTS_CLAUSE-not implemented*/ <t>"
187     ;
188         
189 genericTypeParameterList
190     :   ^(GENERIC_TYPE_PARAM_LIST genericTypeParameter+)
191         -> template(t={$text}) "/*GENERIC_TYPE_PARAM_LIST-not implemented*/ <t>"
192     ;
193
194 genericTypeParameter
195     :   ^(IDENT bound?)
196         -> template(t={$text}) "/*genericTypeParameter-not implemented*/ <t>"
197     ;
198         
199 bound
200     :   ^(EXTENDS_BOUND_LIST type+)
201         -> template(t={$text}) "/*EXTENDS_BOUND_LIST-not implemented*/ <t>"
202     ;
203
204 enumTopLevelScope
205     :   ^(ENUM_TOP_LEVEL_SCOPE enumConstant+ classTopLevelScope?)
206         -> template(t={$text}) "/*enumTopLevelScope-not implemented*/ <t>"
207     ;
208     
209 enumConstant
210     :   ^(IDENT arguments? classTopLevelScope?)
211         -> template(t={$text}) "/*enumConstant-not implemented*/ <t>"
212     ;
213     
214     
215 classTopLevelScope
216     :   ^(CLASS_TOP_LEVEL_SCOPE (csd+=classScopeDeclarations)*) 
217         -> classTopLevelScope(classScopeDeclarations={$csd})
218     ;
219     
220 classScopeDeclarations
221 @init { boolean entry = false; }
222     :   ^(CLASS_INSTANCE_INITIALIZER block)
223         -> {$block.st}
224     |   ^(CLASS_STATIC_INITIALIZER block)
225         -> {$block.st}
226     |   ^(FUNCTION_METHOD_DECL m=modifierList g=genericTypeParameterList? 
227             ty=type IDENT f=formalParameterList a=arrayDeclaratorList? 
228             tc=throwsClause? b=block?)
229         { 
230             // determine whether this is an entry method
231             entry = listContainsToken($m.start.getChildren(), ENTRY);
232         }
233         -> {emitCC()}? funcMethodDecl_cc(
234                 modl={$m.st}, 
235                 gtpl={$g.st}, 
236                 ty={$ty.text},
237                 id={$IDENT.text}, 
238                 fpl={$f.st}, 
239                 adl={$a.st},
240                 tc={$tc.st}, 
241                 block={$b.st})
242         -> {emitH()}? funcMethodDecl_h(
243                 modl={$m.st}, 
244                 gtpl={$g.st}, 
245                 ty={$ty.text},
246                 id={$IDENT.text}, 
247                 fpl={$f.st}, 
248                 adl={$a.st},
249                 tc={$tc.st}, 
250                 block={$b.st})
251         -> {(emitCI() && entry)}? funcMethodDecl_ci(
252                 modl={$m.st}, 
253                 gtpl={$g.st}, 
254                 ty={$ty.text},
255                 id={$IDENT.text}, 
256                 fpl={$f.st}, 
257                 adl={$a.st},
258                 tc={$tc.st}, 
259                 block={$b.st})
260         ->
261     |   ^(VOID_METHOD_DECL m=modifierList g=genericTypeParameterList? IDENT 
262             f=formalParameterList t=throwsClause? b=block?)
263         { 
264             // determine whether this is an entry method
265             entry = listContainsToken($m.start.getChildren(), ENTRY);
266         }
267         -> {emitCC()}? voidMethodDecl_cc(
268                 modl={$m.st}, 
269                 gtpl={$g.st}, 
270                 id={$IDENT.text}, 
271                 fpl={$f.st}, 
272                 tc={$t.st}, 
273                 block={$b.st})
274         -> {emitCI() && entry}? voidMethodDecl_ci(
275                 modl={$m.st}, 
276                 gtpl={$g.st}, 
277                 id={$IDENT.text}, 
278                 fpl={$f.st}, 
279                 tc={$t.st}, 
280                 block={$b.st})
281         -> {emitH()}? voidMethodDecl_h(
282                 modl={$m.st}, 
283                 gtpl={$g.st}, 
284                 id={$IDENT.text}, 
285                 fpl={$f.st}, 
286                 tc={$t.st}, 
287                 block={$b.st})
288         ->
289     |   ^(PRIMITIVE_VAR_DECLARATION modifierList simpleType variableDeclaratorList)
290         -> {emitCC() || emitH()}? primitive_var_decl(
291             modList={$modifierList.st},
292             type={$simpleType.st},
293             declList={$variableDeclaratorList.st})
294         ->
295     |   ^(OBJECT_VAR_DECLARATION modifierList objectType variableDeclaratorList)
296         -> {emitCC() || emitH()}? object_var_decl(
297             modList={$modifierList.st},
298             type={$objectType.st},
299             declList={$variableDeclaratorList.st})
300         ->
301     |   ^(CONSTRUCTOR_DECL m=modifierList g=genericTypeParameterList? IDENT f=formalParameterList 
302             t=throwsClause? b=block)
303         { 
304             // determine whether this is an entry method
305             entry = listContainsToken($m.start.getChildren(), ENTRY);
306         }
307         -> {emitCC()}? ctorDecl_cc(
308                 modl={$m.st}, 
309                 gtpl={$g.st}, 
310                 id={$IDENT.text}, 
311                 fpl={$f.st}, 
312                 tc={$t.st}, 
313                 block={$b.st})
314         -> {emitCI() && entry}? ctorDecl_ci(
315                 modl={$m.st}, 
316                 gtpl={$g.st}, 
317                 id={$IDENT.text}, 
318                 fpl={$f.st}, 
319                 tc={$t.st}, 
320                 block={$b.st})
321         -> {emitH()}? ctorDecl_h(
322                 modl={$m.st}, 
323                 gtpl={$g.st}, 
324                 id={$IDENT.text}, 
325                 fpl={$f.st}, 
326                 tc={$t.st}, 
327                 block={$b.st})
328         ->
329     |   typeDeclaration
330         -> {$typeDeclaration.st}
331     ;
332     
333 interfaceTopLevelScope
334     :   ^(INTERFACE_TOP_LEVEL_SCOPE interfaceScopeDeclarations*)
335         -> template(t={$text}) "/*interfaceTopLevelScope-not implemented */ <t>"
336     ;
337     
338 interfaceScopeDeclarations
339     :   ^(FUNCTION_METHOD_DECL modifierList genericTypeParameterList? type IDENT formalParameterList arrayDeclaratorList? throwsClause?)
340         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
341     |   ^(VOID_METHOD_DECL modifierList genericTypeParameterList? IDENT formalParameterList throwsClause?)
342         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
343         // Interface constant declarations have been switched to variable
344         // declarations by Charj.g; the parser has already checked that
345         // there's an obligatory initializer.
346     |   ^(PRIMITIVE_VAR_DECLARATION modifierList simpleType variableDeclaratorList)
347         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
348     |   ^(OBJECT_VAR_DECLARATION modifierList objectType variableDeclaratorList)
349         -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
350     |   typeDeclaration
351         -> {$typeDeclaration.st}
352     ;
353
354 variableDeclaratorList
355     :   ^(VAR_DECLARATOR_LIST (var_decls+=variableDeclarator)+)
356         -> var_decl_list(var_decls={$var_decls})
357     ;
358
359 variableDeclarator
360     :   ^(VAR_DECLARATOR id=variableDeclaratorId initializer=variableInitializer?)
361         -> var_decl(id={$id.st}, initializer={$initializer.st})
362     ;
363     
364 variableDeclaratorId
365     :   ^(IDENT adl=arrayDeclaratorList?)
366         -> var_decl_id(id={$IDENT.text}, arrayDeclList={$adl.st})
367     ;
368
369 variableInitializer
370     :   arrayInitializer
371         -> {$arrayInitializer.st}
372     |   expression
373         -> {$expression.st}
374     ;
375
376 arrayDeclarator
377     :   LBRACK RBRACK
378         -> template(t={$text}) "<t>"
379     ;
380
381 arrayDeclaratorList
382     :   ^(ARRAY_DECLARATOR_LIST ARRAY_DECLARATOR*)  
383         -> template(t={$text}) "<t>"
384     ;
385     
386 arrayInitializer
387     :   ^(ARRAY_INITIALIZER variableInitializer*)
388         -> template(t={$text}) "/* arrayInitializer-not implemented */ <t>"
389     ;
390
391 throwsClause
392     :   ^(THROWS_CLAUSE qualifiedIdentifier+)
393         -> template(t={$text}) "/* throwsClause-not implemented */ <t>"
394     ;
395
396 modifierList
397     :   ^(MODIFIER_LIST (m+=modifier)*)
398         -> template(mod={$m}) "<mod; separator=\" \">"
399     ;
400
401 modifier
402 @init {
403 $st = %{$start.getText()};
404 }
405     :   PUBLIC
406     |   PROTECTED
407     |   PRIVATE
408     |   ENTRY
409     |   STATIC
410     |   ABSTRACT
411     |   NATIVE
412     |   SYNCHRONIZED
413     |   TRANSIENT
414     |   VOLATILE
415     |   localModifier
416         -> {$localModifier.st}
417     ;
418
419 localModifierList
420     :   ^(LOCAL_MODIFIER_LIST (m+=localModifier)*)
421         -> template(mod={$m}) "<mod; separator=\" \">"
422     ;
423
424 localModifier
425     :   FINAL
426         -> {%{$start.getText()}}
427     ;
428
429     
430 type
431     :   simpleType
432         -> {$simpleType.st}
433     |   objectType 
434         -> {$objectType.st}
435     ;
436
437 simpleType
438     :   ^(TYPE primitiveType arrayDeclaratorList?)
439         -> type(typeID={$primitiveType.st}, arrDeclList={$arrayDeclaratorList.st})
440     ;
441
442 objectType
443     :   ^(TYPE qualifiedTypeIdent arrayDeclaratorList?)
444         -> type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$arrayDeclaratorList.st})
445     ;
446
447 qualifiedTypeIdent
448     :   ^(QUALIFIED_TYPE_IDENT (t+=typeIdent)+) 
449         -> template(types={$t}) "<types; separator=\".\">"
450     ;
451
452 typeIdent
453     :   ^(IDENT genericTypeArgumentList?)
454         -> typeIdent(typeID={$IDENT.text}, generics={$genericTypeArgumentList.st})
455     ;
456
457 primitiveType
458 @init {
459 $st = %{$start.getText()};
460 }
461     :   BOOLEAN
462     |   CHAR
463     |   BYTE
464     |   SHORT
465     |   INT
466     |   LONG
467     |   FLOAT
468     |   DOUBLE
469     ;
470
471 genericTypeArgumentList
472     :   ^(GENERIC_TYPE_ARG_LIST (gta+=genericTypeArgument)+)
473         -> template(gtal={$gta}) "\<<gtal; separator=\", \">\>"
474     ;
475     
476 genericTypeArgument
477     :   type
478         -> {$type.st}
479     |   ^(QUESTION genericWildcardBoundType?)
480         -> template(t={$text}) "/* genericTypeArgument: wildcard bound types not implemented */ <t>"
481     ;
482
483 genericWildcardBoundType                                                                                                                      
484     :   ^(EXTENDS type)
485         -> template(t={$text}) "/* genericWildcardBoundType not implemented */ <t>"
486     |   ^(SUPER type)
487         -> template(t={$text}) "/* genericWildcardBoundType not implemented */ <t>"
488     ;
489
490 formalParameterList
491     :   ^(FORMAL_PARAM_LIST (fpsd+=formalParameterStandardDecl)* fpvd=formalParameterVarargDecl?)
492         -> formal_param_list(sdecl={$fpsd}, vdecl={$fpvd.st})
493     ;
494     
495 formalParameterStandardDecl
496     :   ^(FORMAL_PARAM_STD_DECL lms=localModifierList t=type vdid=variableDeclaratorId)
497         -> formal_param_decl(modList={$lms.st}, type={$t.st}, declID={$vdid.st})
498     ;
499     
500 formalParameterVarargDecl
501     :   ^(FORMAL_PARAM_VARARG_DECL localModifierList type variableDeclaratorId)
502         -> template(t={$text}) "/*formal parameter varargs not implemented*/ <t>"
503     ;
504     
505 qualifiedIdentifier
506     :   IDENT
507         -> template(t={$text}) "<t>"
508     |   ^(DOT qualifiedIdentifier IDENT)
509         -> template(t={$text}) "<t>"
510     ;
511     
512 block
513 @init { boolean emptyBlock = true; }
514     :   ^(BLOCK_SCOPE (b+=blockStatement)*)
515         { emptyBlock = ($b == null || $b.size() == 0); }
516         -> {emitCC() && emptyBlock}? template(bsl={$b}) "{ }"
517         -> {emitCC()}? block_cc(bsl={$b})
518         ->
519     ;
520     
521 blockStatement
522     :   localVariableDeclaration
523         -> {$localVariableDeclaration.st}
524     |   typeDeclaration
525         -> {$typeDeclaration.st}
526     |   statement
527         -> {$statement.st}
528     ;
529
530
531 localVariableDeclaration
532     :   ^(PRIMITIVE_VAR_DECLARATION localModifierList simpleType variableDeclaratorList)
533         -> primitive_var_decl(
534             modList={null},
535             type={$simpleType.st},
536             declList={$variableDeclaratorList.st})
537     |   ^(OBJECT_VAR_DECLARATION localModifierList objectType variableDeclaratorList)
538         -> object_var_decl(
539             modList={null},
540             type={$objectType.st},
541             declList={$variableDeclaratorList.st})
542     ;
543
544
545 statement
546     :   block
547         -> {$block.st}
548     |   ^(ASSERT cond=expression msg=expression?)
549         -> assert(cond={$cond.st}, msg={$msg.st})
550     |   ^(IF parenthesizedExpression then=statement else_=statement?)
551         -> if(cond={$parenthesizedExpression.st}, then={$then.st}, else_={$else_.st})
552     |   ^(FOR forInit forCondition forUpdater s=statement)
553         -> for(initializer={$forInit.st}, cond={$forCondition.st}, update={$forUpdater.st}, body={$s.st})
554     |   ^(FOR_EACH localModifierList type IDENT expression statement) 
555         -> template(t={$text}) "/* foreach not implemented */ <t>"
556     |   ^(WHILE pe=parenthesizedExpression s=statement)
557         -> while(cond={$pe.st}, body={$s.st})
558     |   ^(DO s=statement pe=parenthesizedExpression)
559         -> dowhile(cond={$pe.st}, block={$s.st})
560     |   ^(TRY block catches? block?)  // The second optional block is the finally block.
561         -> template(t={$text}) "/* try/catch not implemented */ <t>"
562     |   ^(SWITCH pe=parenthesizedExpression sbls=switchBlockLabels)
563         -> switch(expr={$pe.st}, labels={$sbls.st})
564     |   ^(SYNCHRONIZED parenthesizedExpression block)
565         -> template(t={$text}) "/* synchronized not implemented */ <t>"
566     |   ^(RETURN e=expression?)
567         -> return(val={$e.st})
568     |   ^(THROW expression)
569         -> template(t={$text}) "/* throw not implemented */ <t>"
570     |   ^(BREAK IDENT?)
571         -> template() "break;" // TODO: support labeling
572     |   ^(CONTINUE IDENT?)
573         -> template() "continue" // TODO: support labeling
574     |   ^(LABELED_STATEMENT IDENT statement)
575         -> template(t={$text}) "<t>"
576     |   expression
577         -> {$expression.st}
578     |   ^(EMBED STRING_LITERAL EMBED_BLOCK)
579         ->  embed_cc(str={$STRING_LITERAL.text}, blk={$EMBED_BLOCK.text})
580     |   SEMI // Empty statement.
581         -> {%{$start.getText()}}
582     ;
583         
584 catches
585     :   ^(CATCH_CLAUSE_LIST catchClause+)
586         -> template(t={$text}) "/* catch not implemented */ <t>"
587     ;
588     
589 catchClause
590     :   ^(CATCH formalParameterStandardDecl block)
591         -> template(t={$text}) "/* catchClause not implemented */ <t>"
592     ;
593
594 switchBlockLabels
595     :   ^(SWITCH_BLOCK_LABEL_LIST switchCaseLabel*)
596         -> template(t={$text}) "<t>"
597     ;
598         
599 switchCaseLabel
600     :   ^(CASE expression blockStatement*)
601         -> template(t={$text}) "<t>"
602     |   ^(DEFAULT blockStatement*)
603         -> template(t={$text}) "<t>"
604     ;
605     
606 forInit
607     :   ^(FOR_INIT (localVariableDeclaration | expression*)?)
608         -> template(t={$text}) "<t>"
609     ;
610     
611 forCondition
612     :   ^(FOR_CONDITION expression?)
613         -> template(t={$text}) "<t>"
614     ;
615     
616 forUpdater
617     :   ^(FOR_UPDATE expression*)
618         -> template(t={$text}) "<t>"
619     ;
620     
621 // EXPRESSIONS
622
623 parenthesizedExpression
624     :   ^(PARENTESIZED_EXPR expression)
625         -> template(t={$text}) "<t>"
626     ;
627     
628 expression
629     :   ^(EXPR expr)
630         -> {$expr.st}
631     ;
632
633 expr
634     :   ^(ASSIGN expr expr)
635         -> template(t={$text}) "<t>"
636     |   ^(PLUS_ASSIGN expr expr)
637         -> template(t={$text}) "<t>"
638     |   ^(MINUS_ASSIGN expr expr)
639         -> template(t={$text}) "<t>"
640     |   ^(STAR_ASSIGN expr expr)
641         -> template(t={$text}) "<t>"
642     |   ^(DIV_ASSIGN expr expr)
643         -> template(t={$text}) "<t>"
644     |   ^(AND_ASSIGN expr expr)
645         -> template(t={$text}) "<t>"
646     |   ^(OR_ASSIGN expr expr)
647         -> template(t={$text}) "<t>"
648     |   ^(XOR_ASSIGN expr expr)
649         -> template(t={$text}) "<t>"
650     |   ^(MOD_ASSIGN expr expr)
651         -> template(t={$text}) "<t>"
652     |   ^(BIT_SHIFT_RIGHT_ASSIGN expr expr)
653         -> template(t={$text}) "<t>"
654     |   ^(SHIFT_RIGHT_ASSIGN expr expr)
655         -> template(t={$text}) "<t>"
656     |   ^(SHIFT_LEFT_ASSIGN expr expr)
657         -> template(t={$text}) "<t>"
658     |   ^(QUESTION expr expr expr)
659         -> template(t={$text}) "<t>"
660     |   ^(LOGICAL_OR expr expr)
661         -> template(t={$text}) "<t>"
662     |   ^(LOGICAL_AND expr expr)
663         -> template(t={$text}) "<t>"
664     |   ^(OR expr expr)
665         -> template(t={$text}) "<t>"
666     |   ^(XOR expr expr)
667         -> template(t={$text}) "<t>"
668     |   ^(AND expr expr)
669         -> template(t={$text}) "<t>"
670     |   ^(EQUAL expr expr)
671         -> template(t={$text}) "<t>"
672     |   ^(NOT_EQUAL expr expr)
673         -> template(t={$text}) "<t>"
674     |   ^(INSTANCEOF expr type)
675         -> template(t={$text}) "<t>"
676     |   ^(LESS_OR_EQUAL expr expr)
677         -> template(t={$text}) "<t>"
678     |   ^(GREATER_OR_EQUAL expr expr)
679         -> template(t={$text}) "<t>"
680     |   ^(BIT_SHIFT_RIGHT expr expr)
681         -> template(t={$text}) "<t>"
682     |   ^(SHIFT_RIGHT expr expr)
683         -> template(t={$text}) "<t>"
684     |   ^(GREATER_THAN expr expr)
685         -> template(t={$text}) "<t>"
686     |   ^(SHIFT_LEFT expr expr)
687         -> template(t={$text}) "<t>"
688     |   ^(LESS_THAN expr expr)
689         -> template(t={$text}) "<t>"
690     |   ^(PLUS expr expr)
691         -> template(t={$text}) "<t>"
692     |   ^(MINUS expr expr)
693         -> template(t={$text}) "<t>"
694     |   ^(STAR expr expr)
695         -> template(t={$text}) "<t>"
696     |   ^(DIV expr expr)
697         -> template(t={$text}) "<t>"
698     |   ^(MOD expr expr)
699         -> template(t={$text}) "<t>"
700     |   ^(UNARY_PLUS expr)
701         -> template(t={$text}) "<t>"
702     |   ^(UNARY_MINUS expr)
703         -> template(t={$text}) "<t>"
704     |   ^(PRE_INC expr)
705         -> template(t={$text}) "<t>"
706     |   ^(PRE_DEC expr)
707         -> template(t={$text}) "<t>"
708     |   ^(POST_INC expr)
709         -> template(t={$text}) "<t>"
710     |   ^(POST_DEC expr)
711         -> template(t={$text}) "<t>"
712     |   ^(NOT expr)
713         -> template(t={$text}) "<t>"
714     |   ^(LOGICAL_NOT expr)
715         -> template(t={$text}) "<t>"
716     |   ^(CAST_EXPR type expr)
717         -> template(t={$text}) "<t>"
718     |   primaryExpression
719         -> {$primaryExpression.st}
720     ;
721     
722 primaryExpression
723     :   ^(  DOT
724             (   primaryExpression
725                 (   IDENT
726                 |   THIS
727                 |   SUPER
728                 |   innerNewExpression
729                 |   CLASS
730                 )
731             |   primitiveType CLASS
732             |   VOID CLASS
733             )
734         )
735         -> template(t={$text}) "<t>"
736     |   parenthesizedExpression
737         -> {$parenthesizedExpression.st}
738     |   IDENT
739         -> {%{$start.getText()}}
740     |   ^(METHOD_CALL primaryExpression genericTypeArgumentList? arguments)
741         -> template(t={$text}) "<t>"
742     |   explicitConstructorCall
743         -> {$explicitConstructorCall.st}
744     |   ^(ARRAY_ELEMENT_ACCESS primaryExpression expression)
745         -> template(t={$text}) "<t>"
746     |   literal
747         -> {$literal.st}
748     |   newExpression
749         -> {$newExpression.st}
750     |   THIS
751         -> {%{$start.getText()}}
752     |   arrayTypeDeclarator
753         -> {$arrayTypeDeclarator.st}
754     |   SUPER
755         -> {%{$start.getText()}}
756     ;
757     
758 explicitConstructorCall
759     :   ^(THIS_CONSTRUCTOR_CALL genericTypeArgumentList? arguments)
760         -> template(t={$text}) "<t>"
761     |   ^(SUPER_CONSTRUCTOR_CALL primaryExpression? genericTypeArgumentList? arguments)
762         -> template(t={$text}) "<t>"
763     ;
764
765 arrayTypeDeclarator
766     :   ^(ARRAY_DECLARATOR (arrayTypeDeclarator | qualifiedIdentifier | primitiveType))
767         -> template(t={$text}) "<t>"
768     ;
769
770 newExpression
771     :   ^(  STATIC_ARRAY_CREATOR
772             (   primitiveType newArrayConstruction
773             |   genericTypeArgumentList? qualifiedTypeIdent newArrayConstruction
774             )
775         )
776         -> template(t={$text}) "<t>"
777     |   ^(CLASS_CONSTRUCTOR_CALL genericTypeArgumentList? qualifiedTypeIdent arguments classTopLevelScope?)
778         -> template(t={$text}) "<t>"
779     ;
780
781 innerNewExpression // something like 'InnerType innerType = outer.new InnerType();'
782     :   ^(CLASS_CONSTRUCTOR_CALL genericTypeArgumentList? IDENT arguments classTopLevelScope?)
783         -> template(t={$text}) "<t>"
784     ;
785     
786 newArrayConstruction
787     :   arrayDeclaratorList arrayInitializer
788         -> template(t={$text}) "<t>"
789     |   expression+ arrayDeclaratorList?
790         -> template(t={$text}) "<t>"
791     ;
792
793 arguments
794     :   ^(ARGUMENT_LIST expression*)
795         -> template(t={$text}) "<t>"
796     ;
797
798 literal
799 @init {
800 $st = %{$start.getText()};
801 }
802     :   HEX_LITERAL
803     |   OCTAL_LITERAL
804     |   DECIMAL_LITERAL
805     |   FLOATING_POINT_LITERAL
806     |   CHARACTER_LITERAL
807     |   STRING_LITERAL
808     |   TRUE
809     |   FALSE
810     |   NULL
811     ;
812