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