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