new, way better build system, tests, and template output
[charm.git] / src / langs / charj / src / charj / translator / Charj.g
1 /**
2  * ANTLR (v3) grammar for the Charj Language
3  *
4  * The other .g files are tree parsers that can read and modify an AST 
5  * using the output of this grammar.
6  */
7
8
9 grammar Charj;
10
11 options {
12     backtrack = true; 
13     memoize = true;
14     output = AST;
15     ASTLabelType = CommonTree;
16 }
17
18 tokens {
19
20     // operators and other special chars
21     
22     AND                     = '&'               ;
23     AND_ASSIGN              = '&='              ;
24     ASSIGN                  = '='               ;
25     AT                      = '@'               ;
26     BIT_SHIFT_RIGHT         = '>>>'             ;
27     BIT_SHIFT_RIGHT_ASSIGN  = '>>>='            ;
28     COLON                   = ':'               ;
29     COMMA                   = ','               ;
30     DEC                     = '--'              ;
31     DIV                     = '/'               ;
32     DIV_ASSIGN              = '/='              ;
33     DOT                     = '.'               ;
34     DOTSTAR                 = '.*'              ;
35     ELLIPSIS                = '...'             ;
36     EQUAL                   = '=='              ;
37     GREATER_OR_EQUAL        = '>='              ;
38     GREATER_THAN            = '>'               ;
39     INC                     = '++'              ;
40     LBRACK                  = '['               ;
41     LCURLY                  = '{'               ;
42     LESS_OR_EQUAL           = '<='              ;
43     LESS_THAN               = '<'               ;
44     LOGICAL_AND             = '&&'              ;
45     LOGICAL_NOT             = '!'               ;
46     LOGICAL_OR              = '||'              ;
47     LPAREN                  = '('               ;
48     MINUS                   = '-'               ;
49     MINUS_ASSIGN            = '-='              ;
50     MOD                     = '%'               ;
51     MOD_ASSIGN              = '%='              ;
52     NOT                     = '~'               ;
53     NOT_EQUAL               = '!='              ;
54     OR                      = '|'               ;
55     OR_ASSIGN               = '|='              ;
56     PLUS                    = '+'               ;
57     PLUS_ASSIGN             = '+='              ;
58     QUESTION                = '?'               ;
59     RBRACK                  = ']'               ;
60     RCURLY                  = '}'               ;
61     RPAREN                  = ')'               ;
62     SEMI                    = ';'               ;
63     SHIFT_LEFT              = '<<'              ;
64     SHIFT_LEFT_ASSIGN       = '<<='             ;
65     SHIFT_RIGHT             = '>>'              ;
66     SHIFT_RIGHT_ASSIGN      = '>>='             ;
67     STAR                    = '*'               ;
68     STAR_ASSIGN             = '*='              ;
69     XOR                     = '^'               ;
70     XOR_ASSIGN              = '^='              ;
71
72     // keywords
73     
74     ABSTRACT                = 'abstract'        ;
75     ASSERT                  = 'assert'          ;
76     BOOLEAN                 = 'boolean'         ;
77     BREAK                   = 'break'           ;
78     BYTE                    = 'byte'            ;
79     CASE                    = 'case'            ;
80     CATCH                   = 'catch'           ;
81     CHAR                    = 'char'            ;
82     CLASS                   = 'class'           ;
83     CONTINUE                = 'continue'        ;
84     DEFAULT                 = 'default'         ;
85     DO                      = 'do'              ;
86     DOUBLE                  = 'double'          ;
87     ELSE                    = 'else'            ;
88     ENUM                    = 'enum'            ;
89     EXTENDS                 = 'extends'         ;
90     FALSE                   = 'false'           ;
91     FINAL                   = 'final'           ;
92     FINALLY                 = 'finally'         ;
93     FLOAT                   = 'float'           ;
94     FOR                     = 'for'             ;
95     IF                      = 'if'              ;
96     IMPLEMENTS              = 'implements'      ;
97     INSTANCEOF              = 'instanceof'      ;
98     INTERFACE               = 'interface'       ;
99     IMPORT                  = 'import'          ;
100     INT                     = 'int'             ;
101     LONG                    = 'long'            ;
102     NATIVE                  = 'native'          ;
103     NEW                     = 'new'             ;
104     NULL                    = 'null'            ;
105     PACKAGE                 = 'package'         ;
106     PRIVATE                 = 'private'         ;
107     PROTECTED               = 'protected'       ;
108     PUBLIC                  = 'public'          ;
109     RETURN                  = 'return'          ;
110     SHORT                   = 'short'           ;
111     STATIC                  = 'static'          ;
112     SUPER                   = 'super'           ;
113     SWITCH                  = 'switch'          ;
114     SYNCHRONIZED            = 'synchronized'    ;
115     THIS                    = 'this'            ;
116     THROW                   = 'throw'           ;
117     THROWS                  = 'throws'          ;
118     TRANSIENT               = 'transient'       ;
119     TRUE                    = 'true'            ;
120     TRY                     = 'try'             ;
121     VOID                    = 'void'            ;
122     VOLATILE                = 'volatile'        ;
123     WHILE                   = 'while'           ;
124     
125     // tokens for imaginary nodes
126     
127     ARGUMENT_LIST;
128     ARRAY_DECLARATOR;
129     ARRAY_DECLARATOR_LIST;
130     ARRAY_ELEMENT_ACCESS;
131     ARRAY_INITIALIZER;
132     BLOCK_SCOPE;
133     CAST_EXPR;
134     CATCH_CLAUSE_LIST;
135     CLASS_CONSTRUCTOR_CALL;
136     CLASS_INSTANCE_INITIALIZER;
137     CLASS_STATIC_INITIALIZER;
138     CLASS_TOP_LEVEL_SCOPE;
139     CONSTRUCTOR_DECL;
140     ENUM_TOP_LEVEL_SCOPE;
141     EXPR;
142     EXTENDS_BOUND_LIST;
143     EXTENDS_CLAUSE;
144     FOR_CONDITION;
145     FOR_EACH;
146     FOR_INIT;
147     FOR_UPDATE;
148     FORMAL_PARAM_LIST;
149     FORMAL_PARAM_STD_DECL;
150     FORMAL_PARAM_VARARG_DECL;
151     FUNCTION_METHOD_DECL;
152     GENERIC_TYPE_ARG_LIST;
153     GENERIC_TYPE_PARAM_LIST;
154     INTERFACE_TOP_LEVEL_SCOPE;
155     IMPLEMENTS_CLAUSE;
156     LABELED_STATEMENT;
157     LOCAL_MODIFIER_LIST;
158     CHARJ_SOURCE;
159     METHOD_CALL;
160     MODIFIER_LIST;
161     PARENTESIZED_EXPR;
162     POST_DEC;
163     POST_INC;
164     PRE_DEC;
165     PRE_INC;
166     QUALIFIED_TYPE_IDENT;
167     STATIC_ARRAY_CREATOR;
168     SUPER_CONSTRUCTOR_CALL;
169     SWITCH_BLOCK_LABEL_LIST;
170     THIS_CONSTRUCTOR_CALL;
171     THROWS_CLAUSE;
172     TYPE;
173     UNARY_MINUS;
174     UNARY_PLUS;
175     VAR_DECLARATION;
176     VAR_DECLARATOR;
177     VAR_DECLARATOR_LIST;
178     VOID_METHOD_DECL;
179 }
180
181 @header {
182 package charj.translator;
183 }
184
185 @members {
186     
187     private boolean mMessageCollectionEnabled = false;
188     private boolean mHasErrors = false;
189     private List<String> mMessages;
190
191     /**
192      *  Switches error message collection on or of.
193      *
194      *  The standard destination for parser error messages is <code>System.err</code>.
195      *  However, if <code>true</code> gets passed to this method this default
196      *  behaviour will be switched off and all error messages will be collected
197      *  instead of written to anywhere.
198      *
199      *  The default value is <code>false</code>.
200      *
201      *  @param pNewState  <code>true</code> if error messages should be collected.
202      */
203     public void enableErrorMessageCollection(boolean pNewState) {
204         mMessageCollectionEnabled = pNewState;
205         if (mMessages == null && mMessageCollectionEnabled) {
206             mMessages = new ArrayList<String>();
207         }
208     }
209     
210     /**
211      *  Collects an error message or passes the error message to <code>
212      *  super.emitErrorMessage(...)</code>.
213      *
214      *  The actual behaviour depends on whether collecting error messages
215      *  has been enabled or not.
216      *
217      *  @param pMessage  The error message.
218      */
219      @Override
220     public void emitErrorMessage(String pMessage) {
221         if (mMessageCollectionEnabled) {
222             mMessages.add(pMessage);
223         } else {
224             super.emitErrorMessage(pMessage);
225         }
226     }
227     
228     /**
229      *  Returns collected error messages.
230      *
231      *  @return  A list holding collected error messages or <code>null</code> if
232      *           collecting error messages hasn't been enabled. Of course, this
233      *           list may be empty if no error message has been emited.
234      */
235     public List<String> getMessages() {
236         return mMessages;
237     }
238     
239     /**
240      *  Tells if parsing a Charj source has caused any error messages.
241      *
242      *  @return  <code>true</code> if parsing a Charj source has caused at least
243      *           one error message.
244      */
245     public boolean hasErrors() {
246         return mHasErrors;
247     }
248 }
249
250 @lexer::header {
251 package charj.translator; 
252 }
253
254 @lexer::members {
255 /** 
256  *  Determines if whitespaces and comments should be preserved or thrown away.
257  *
258  *  If <code>true</code> whitespaces and comments will be preserved within the
259  *  hidden channel, otherwise the appropriate tokens will be skiped. This is
260  *  a 'little bit' expensive.
261  */
262 public boolean preserveWhitespacesAndComments = true;
263 }
264
265 // Starting point for parsing a Charj file.
266 charjSource
267     :   compilationUnit
268         ->  ^(CHARJ_SOURCE compilationUnit)
269     ;
270
271 compilationUnit
272     :   packageDeclaration? 
273         importDeclaration* 
274         typeDecls*
275     ;
276
277 typeDecls
278     :   typeDeclaration
279     |   SEMI!
280     ;
281
282 packageDeclaration
283     :   PACKAGE^ qualifiedIdentifier SEMI!  
284     ;
285     
286 importDeclaration
287     :   IMPORT^ STATIC? qualifiedIdentifier DOTSTAR? SEMI!
288     ;
289     
290 typeDeclaration
291     :   modifierList!
292         (   classTypeDeclaration[$modifierList.tree]
293         |   interfaceTypeDeclaration[$modifierList.tree]
294         |   enumTypeDeclaration[$modifierList.tree]
295         )
296     ;
297     
298 classTypeDeclaration[CommonTree modifiers]
299     :   CLASS IDENT genericTypeParameterList? classExtendsClause? implementsClause? classBody
300         ->  ^(CLASS {$modifiers} IDENT genericTypeParameterList? classExtendsClause? implementsClause? classBody)
301     ;
302     
303 classExtendsClause
304     :   EXTENDS type
305         ->  ^(EXTENDS_CLAUSE[$EXTENDS, "EXTENDS_CLAUSE"] type)
306     ;   
307     
308 interfaceExtendsClause
309     :   EXTENDS typeList
310         ->  ^(EXTENDS_CLAUSE[$EXTENDS, "EXTENDS_CLAUSE"] typeList)
311     ;   
312     
313 implementsClause
314     :   IMPLEMENTS typeList
315         ->  ^(IMPLEMENTS_CLAUSE[$IMPLEMENTS, "IMPLEMENTS_CLAUSE"] typeList)
316     ;
317         
318 genericTypeParameterList
319     :   LESS_THAN genericTypeParameter (COMMA genericTypeParameter)* genericTypeListClosing
320         ->  ^(GENERIC_TYPE_PARAM_LIST[$LESS_THAN, "GENERIC_TYPE_PARAM_LIST"] genericTypeParameter+)
321     ;
322
323 genericTypeListClosing  // This 'trick' is fairly dirty - if there's some time a better solution should 
324                         // be found to resolve the problem with nested generic type parameter lists 
325                         // (i.e. <T1 extends AnyType<T2>> for generic type parameters or <T1<T2>> for 
326                         // generic type arguments etc). 
327     :   GREATER_THAN
328     |   SHIFT_RIGHT
329     |   BIT_SHIFT_RIGHT
330     |   // nothing
331     ;
332
333 genericTypeParameter
334     :   IDENT bound?
335         ->  ^(IDENT bound?)
336     ;
337         
338 bound
339     :   EXTENDS type (AND type)*
340         ->  ^(EXTENDS_BOUND_LIST[$EXTENDS, "EXTENDS_BOUND_LIST"] type+)
341     ;
342
343 enumTypeDeclaration[CommonTree modifiers]
344     :   ENUM IDENT implementsClause? enumBody
345         ->  ^(ENUM {$modifiers} IDENT implementsClause? enumBody)
346     ;
347     
348 enumBody
349     :   LCURLY enumScopeDeclarations RCURLY
350         ->  ^(ENUM_TOP_LEVEL_SCOPE[$LCURLY, "ENUM_TOP_LEVEL_SCOPE"] enumScopeDeclarations)
351     ;
352
353 enumScopeDeclarations
354     :   enumConstants (COMMA!)? enumClassScopeDeclarations?
355     ;
356
357 enumClassScopeDeclarations
358     :   SEMI classScopeDeclarations*
359         ->  ^(CLASS_TOP_LEVEL_SCOPE[$SEMI, "CLASS_TOP_LEVEL_SCOPE"] classScopeDeclarations*)
360     ;
361
362 enumConstants
363     :   enumConstant (COMMA! enumConstant)*
364     ;
365     
366 enumConstant
367     :   IDENT^ arguments? classBody?
368     ;
369     
370 interfaceTypeDeclaration[CommonTree modifiers]
371     :   INTERFACE IDENT genericTypeParameterList? interfaceExtendsClause? interfaceBody
372         ->  ^(INTERFACE {$modifiers} IDENT genericTypeParameterList? interfaceExtendsClause? interfaceBody)
373     ;
374     
375 typeList
376     :   type (COMMA! type)*
377     ;
378     
379 classBody
380     :   LCURLY classScopeDeclarations* RCURLY
381         ->  ^(CLASS_TOP_LEVEL_SCOPE[$LCURLY, "CLASS_TOP_LEVEL_SCOPE"] classScopeDeclarations*)
382     ;
383     
384 interfaceBody
385     :   LCURLY interfaceScopeDeclarations* RCURLY
386         ->  ^(INTERFACE_TOP_LEVEL_SCOPE[$LCURLY, "CLASS_TOP_LEVEL_SCOPE"] interfaceScopeDeclarations*)
387     ;
388
389 classScopeDeclarations
390     :   block           ->  ^(CLASS_INSTANCE_INITIALIZER block)
391     |   STATIC block    ->  ^(CLASS_STATIC_INITIALIZER[$STATIC, "CLASS_STATIC_INITIALIZER"] block)
392     |   modifierList
393         (   genericTypeParameterList?
394             (   type IDENT formalParameterList arrayDeclaratorList? throwsClause? (block | SEMI)
395                 ->  ^(FUNCTION_METHOD_DECL modifierList genericTypeParameterList? type IDENT formalParameterList arrayDeclaratorList? throwsClause? block?)
396             |   VOID IDENT formalParameterList throwsClause? (block | SEMI)
397                 ->  ^(VOID_METHOD_DECL modifierList genericTypeParameterList? IDENT formalParameterList throwsClause? block?)
398             |   ident=IDENT formalParameterList throwsClause? block
399                 ->  ^(CONSTRUCTOR_DECL[$ident, "CONSTRUCTOR_DECL"] modifierList genericTypeParameterList? formalParameterList throwsClause? block)
400             )
401         |   type classFieldDeclaratorList SEMI
402             ->  ^(VAR_DECLARATION modifierList type classFieldDeclaratorList)
403         )
404     |   typeDeclaration
405     |   SEMI!
406     ;
407             
408 interfaceScopeDeclarations
409     :   modifierList
410         (   genericTypeParameterList?
411             (   type IDENT formalParameterList arrayDeclaratorList? throwsClause? SEMI
412                 ->  ^(FUNCTION_METHOD_DECL modifierList genericTypeParameterList? type IDENT formalParameterList arrayDeclaratorList? throwsClause?)
413             |   VOID IDENT formalParameterList throwsClause? SEMI
414                 ->  ^(VOID_METHOD_DECL modifierList genericTypeParameterList? IDENT formalParameterList throwsClause?)
415             )
416         |   type interfaceFieldDeclaratorList SEMI
417             ->  ^(VAR_DECLARATION modifierList type interfaceFieldDeclaratorList)
418         )
419     |   typeDeclaration
420     |   SEMI!
421     ;
422
423 classFieldDeclaratorList
424     :   classFieldDeclarator (COMMA classFieldDeclarator)*
425         ->  ^(VAR_DECLARATOR_LIST classFieldDeclarator+)
426     ;
427
428 classFieldDeclarator
429     :   variableDeclaratorId (ASSIGN variableInitializer)?
430         ->  ^(VAR_DECLARATOR variableDeclaratorId variableInitializer?)
431     ;
432     
433 interfaceFieldDeclaratorList
434     :   interfaceFieldDeclarator (COMMA interfaceFieldDeclarator)*
435         ->  ^(VAR_DECLARATOR_LIST interfaceFieldDeclarator+)
436     ;
437
438 interfaceFieldDeclarator
439     :   variableDeclaratorId ASSIGN variableInitializer
440         ->  ^(VAR_DECLARATOR variableDeclaratorId variableInitializer)
441     ;
442     
443 variableDeclaratorId
444     :   IDENT^ arrayDeclaratorList?
445     ;
446
447 variableInitializer
448     :   arrayInitializer
449     |   expression
450     ;
451
452 arrayDeclarator
453     :   LBRACK RBRACK
454         ->  ^(ARRAY_DECLARATOR)
455     ;
456
457 arrayDeclaratorList
458     :   arrayDeclarator+
459         ->  ^(ARRAY_DECLARATOR_LIST arrayDeclarator+)   
460     ;
461     
462 arrayInitializer
463     :   LCURLY (variableInitializer (COMMA variableInitializer)* COMMA?)? RCURLY
464         ->  ^(ARRAY_INITIALIZER[$LCURLY, "ARRAY_INITIALIZER"] variableInitializer*)
465     ;
466
467 throwsClause
468     :   THROWS qualifiedIdentList
469         ->  ^(THROWS_CLAUSE[$THROWS, "THROWS_CLAUSE"] qualifiedIdentList)
470     ;
471
472 modifierList
473     :   modifier*   
474         ->  ^(MODIFIER_LIST modifier*)
475     ;
476
477 modifier
478     :   PUBLIC
479     |   PROTECTED
480     |   PRIVATE
481     |   STATIC
482     |   ABSTRACT
483     |   NATIVE
484     |   SYNCHRONIZED
485     |   TRANSIENT
486     |   VOLATILE
487     |   localModifier
488     ;
489
490 localModifierList
491     :   localModifier*
492         -> ^(LOCAL_MODIFIER_LIST localModifier*)
493     ;
494     
495 localModifier
496     :   FINAL
497     ;
498
499 type
500     :   simpleType
501     |   objectType
502     ;
503
504 simpleType // including static arrays of simple type elements
505     :   primitiveType arrayDeclaratorList?
506         ->  ^(TYPE primitiveType arrayDeclaratorList?)  
507     ;
508     
509 objectType // including static arrays of object type reference elements
510     :   qualifiedTypeIdent arrayDeclaratorList?
511         ->  ^(TYPE qualifiedTypeIdent arrayDeclaratorList?)
512     ;
513
514 objectTypeSimplified
515     :   qualifiedTypeIdentSimplified arrayDeclaratorList?
516         ->  ^(TYPE qualifiedTypeIdentSimplified arrayDeclaratorList?)
517     ;
518
519 qualifiedTypeIdent
520     :   typeIdent (DOT typeIdent)*
521         ->  ^(QUALIFIED_TYPE_IDENT typeIdent+) 
522     ;
523
524 qualifiedTypeIdentSimplified
525     :   typeIdentSimplified (DOT typeIdentSimplified)*
526         ->  ^(QUALIFIED_TYPE_IDENT typeIdentSimplified+) 
527     ;
528
529 typeIdent
530     :   IDENT^ genericTypeArgumentList?
531     ;
532
533 typeIdentSimplified
534     :   IDENT^ genericTypeArgumentListSimplified?
535     ;
536
537 primitiveType
538     :   BOOLEAN
539     |   CHAR
540     |   BYTE
541     |   SHORT
542     |   INT
543     |   LONG
544     |   FLOAT
545     |   DOUBLE
546     ;
547
548 genericTypeArgumentList
549     :   LESS_THAN genericTypeArgument (COMMA genericTypeArgument)* genericTypeListClosing
550         ->  ^(GENERIC_TYPE_ARG_LIST[$LESS_THAN, "GENERIC_TYPE_ARG_LIST"] genericTypeArgument+)
551     ;
552
553 genericTypeArgument
554     :   type
555     |   QUESTION genericWildcardBoundType?
556         ->  ^(QUESTION genericWildcardBoundType?)
557     ;
558     
559 genericWildcardBoundType
560     :   (EXTENDS | SUPER)^ type
561     ;
562
563 genericTypeArgumentListSimplified
564     :   LESS_THAN genericTypeArgumentSimplified (COMMA genericTypeArgumentSimplified)* genericTypeListClosing
565         ->  ^(GENERIC_TYPE_ARG_LIST[$LESS_THAN, "GENERIC_TYPE_ARG_LIST"] genericTypeArgumentSimplified+)
566     ;
567     
568 genericTypeArgumentSimplified
569     :   type
570     |   QUESTION
571     ;
572     
573 qualifiedIdentList
574     :   qualifiedIdentifier (COMMA! qualifiedIdentifier)*
575     ;
576     
577 formalParameterList
578     :   LPAREN 
579         (   // Contains at least one standard argument declaration and optionally a variable argument declaration.
580             formalParameterStandardDecl (COMMA formalParameterStandardDecl)* (COMMA formalParameterVarArgDecl)? 
581             ->  ^(FORMAL_PARAM_LIST[$LPAREN, "FORMAL_PARAM_LIST"] formalParameterStandardDecl+ formalParameterVarArgDecl?) 
582             // Contains a variable argument declaration only.
583         |   formalParameterVarArgDecl
584             ->  ^(FORMAL_PARAM_LIST[$LPAREN, "FORMAL_PARAM_LIST"] formalParameterVarArgDecl) 
585             // Contains nothing.
586         |   ->  ^(FORMAL_PARAM_LIST[$LPAREN, "FORMAL_PARAM_LIST"]) 
587         )
588         RPAREN
589     ;
590     
591 formalParameterStandardDecl
592     :   localModifierList type variableDeclaratorId
593         ->  ^(FORMAL_PARAM_STD_DECL localModifierList type variableDeclaratorId)
594     ;
595     
596 formalParameterVarArgDecl
597     :   localModifierList type ELLIPSIS variableDeclaratorId
598         ->  ^(FORMAL_PARAM_VARARG_DECL localModifierList type variableDeclaratorId)
599     ;
600     
601 qualifiedIdentifier
602     :   (   IDENT               ->  IDENT
603         )
604         (   DOT ident=IDENT     ->  ^(DOT $qualifiedIdentifier $ident)
605         )*
606     ;
607     
608 block
609     :   LCURLY blockStatement* RCURLY
610         ->  ^(BLOCK_SCOPE[$LCURLY, "BLOCK_SCOPE"] blockStatement*)
611     ;
612
613 blockStatement
614     :   localVariableDeclaration SEMI!
615     |   typeDeclaration
616     |   statement
617     ;
618     
619 localVariableDeclaration
620     :   localModifierList type classFieldDeclaratorList
621         ->  ^(VAR_DECLARATION localModifierList type classFieldDeclaratorList)
622     ;
623     
624         
625 statement
626     :   block
627     |   ASSERT expr1=expression 
628         (   COLON expr2=expression SEMI                                     ->  ^(ASSERT $expr1 $expr2)
629         |   SEMI                                                            ->  ^(ASSERT $expr1)
630         )
631     |   IF parenthesizedExpression ifStat=statement 
632         (   ELSE elseStat=statement                                         ->  ^(IF parenthesizedExpression $ifStat $elseStat)
633         |                                                                   ->  ^(IF parenthesizedExpression $ifStat)
634         )   
635     |   FOR LPAREN 
636         (   forInit SEMI forCondition SEMI forUpdater RPAREN statement      ->  ^(FOR forInit forCondition forUpdater statement) 
637         |   localModifierList type IDENT COLON expression RPAREN statement
638                                                                             ->  ^(FOR_EACH[$FOR, "FOR_EACH"] localModifierList type IDENT expression statement)
639         ) 
640     |   WHILE parenthesizedExpression statement                             ->  ^(WHILE parenthesizedExpression statement)
641     |   DO statement WHILE parenthesizedExpression SEMI                     ->  ^(DO statement parenthesizedExpression)
642     |   TRY block (catches finallyClause? | finallyClause)                  ->  ^(TRY block catches? finallyClause?)
643     |   SWITCH parenthesizedExpression LCURLY switchBlockLabels RCURLY      ->  ^(SWITCH parenthesizedExpression switchBlockLabels)
644     |   SYNCHRONIZED parenthesizedExpression block                          ->  ^(SYNCHRONIZED parenthesizedExpression block)
645     |   RETURN expression? SEMI                                             ->  ^(RETURN expression?)
646     |   THROW expression SEMI                                               ->  ^(THROW expression)
647     |   BREAK IDENT? SEMI                                                   ->  ^(BREAK IDENT?)
648     |   CONTINUE IDENT? SEMI                                                ->  ^(CONTINUE IDENT?)
649     |   IDENT COLON statement                                               ->  ^(LABELED_STATEMENT IDENT statement)
650     |   expression SEMI!
651     |   SEMI // Preserve empty statements.
652     ;           
653         
654 catches
655     :   catchClause+
656         ->  ^(CATCH_CLAUSE_LIST catchClause+)
657     ;
658     
659 catchClause
660     :   CATCH^ LPAREN! formalParameterStandardDecl RPAREN! block
661     ;
662
663 finallyClause
664     :   FINALLY block
665         ->  block
666     ;
667
668 switchBlockLabels
669     :   switchCaseLabels switchDefaultLabel? switchCaseLabels
670         ->  ^(SWITCH_BLOCK_LABEL_LIST switchCaseLabels switchDefaultLabel? switchCaseLabels)
671     ;
672     
673 switchCaseLabels
674     :   switchCaseLabel*
675     ;
676         
677 switchCaseLabel
678     :   CASE^ expression COLON! blockStatement*
679     ;
680     
681 switchDefaultLabel
682     :   DEFAULT^ COLON! blockStatement*
683     ;
684     
685 forInit
686     :   localVariableDeclaration    ->  ^(FOR_INIT localVariableDeclaration)
687     |   expressionList              ->  ^(FOR_INIT expressionList)
688     |                               ->  ^(FOR_INIT)
689     ;
690     
691 forCondition
692     :   expression?
693         ->  ^(FOR_CONDITION expression?)
694     ;
695     
696 forUpdater
697     :   expressionList?
698         ->  ^(FOR_UPDATE expressionList?)
699     ;
700
701 // EXPRESSIONS
702
703 parenthesizedExpression
704     :   LPAREN expression RPAREN
705         ->  ^(PARENTESIZED_EXPR[$LPAREN, "PARENTESIZED_EXPR"] expression)
706     ;
707     
708 expressionList
709     :   expression (COMMA! expression)*
710     ;
711
712 expression
713     :   assignmentExpression
714         ->  ^(EXPR assignmentExpression)
715     ;
716
717 assignmentExpression
718     :   conditionalExpression 
719         (   (   ASSIGN^
720             |   PLUS_ASSIGN^
721             |   MINUS_ASSIGN^
722             |   STAR_ASSIGN^
723             |   DIV_ASSIGN^
724             |   AND_ASSIGN^
725             |   OR_ASSIGN^
726             |   XOR_ASSIGN^
727             |   MOD_ASSIGN^
728             |   SHIFT_LEFT_ASSIGN^
729             |   SHIFT_RIGHT_ASSIGN^
730             |   BIT_SHIFT_RIGHT_ASSIGN^
731         ) 
732         assignmentExpression)?
733     ;
734     
735 conditionalExpression
736     :   logicalOrExpression (QUESTION^ assignmentExpression COLON! conditionalExpression)?
737     ;
738
739 logicalOrExpression
740     :   logicalAndExpression (LOGICAL_OR^ logicalAndExpression)*
741     ;
742
743 logicalAndExpression
744     :   inclusiveOrExpression (LOGICAL_AND^ inclusiveOrExpression)*
745     ;
746
747 inclusiveOrExpression
748     :   exclusiveOrExpression (OR^ exclusiveOrExpression)*
749     ;
750
751 exclusiveOrExpression
752     :   andExpression (XOR^ andExpression)*
753     ;
754
755 andExpression
756     :   equalityExpression (AND^ equalityExpression)*
757     ;
758
759 equalityExpression
760     :   instanceOfExpression 
761         (   (   EQUAL^
762             |   NOT_EQUAL^
763             ) 
764             instanceOfExpression
765         )*
766     ;
767
768 instanceOfExpression
769     :   relationalExpression (INSTANCEOF^ type)?
770     ;
771
772 relationalExpression
773     :   shiftExpression 
774         (   (   LESS_OR_EQUAL^
775             |   GREATER_OR_EQUAL^
776             |   LESS_THAN^
777             |   GREATER_THAN^
778             )
779             shiftExpression
780         )*
781     ;
782     
783 shiftExpression
784     :   additiveExpression
785         (   (   BIT_SHIFT_RIGHT^
786             |   SHIFT_RIGHT^
787             |   SHIFT_LEFT^
788             )
789             additiveExpression
790         )*
791     ;
792
793 additiveExpression
794     :   multiplicativeExpression
795         (   (   PLUS^
796             |   MINUS^
797             )
798             multiplicativeExpression
799         )*
800     ;
801
802 multiplicativeExpression
803     :   unaryExpression 
804         (   (   STAR^
805             |   DIV^
806             |   MOD^
807             )
808             unaryExpression
809         )*
810     ;
811     
812 unaryExpression
813     :   PLUS unaryExpression        ->  ^(UNARY_PLUS[$PLUS, "UNARY_PLUS"] unaryExpression)
814     |   MINUS unaryExpression       ->  ^(UNARY_MINUS[$MINUS, "UNARY_MINUS"] unaryExpression)
815     |   INC postfixedExpression     ->  ^(PRE_INC[$INC, "PRE_INC"] postfixedExpression)
816     |   DEC postfixedExpression     ->  ^(PRE_DEC[$DEC, "PRE_DEC"] postfixedExpression)
817     |   unaryExpressionNotPlusMinus
818     ;
819
820 unaryExpressionNotPlusMinus
821     :   NOT unaryExpression                             ->  ^(NOT unaryExpression)
822     |   LOGICAL_NOT unaryExpression                     ->  ^(LOGICAL_NOT unaryExpression)
823     |   LPAREN type RPAREN unaryExpression              ->  ^(CAST_EXPR[$LPAREN, "CAST_EXPR"] type unaryExpression)
824     |   postfixedExpression
825     ;
826     
827 postfixedExpression
828         // At first resolve the primary expression ...
829     :   (   primaryExpression                       ->  primaryExpression
830         )
831         // ... and than the optional things that may follow a primary expression 0 or more times.
832         (   outerDot=DOT                            
833             (   (   genericTypeArgumentListSimplified?  // Note: generic type arguments are only valid for method calls, i.e. if there
834                                                         //       is an argument list.
835                     IDENT                           ->  ^(DOT $postfixedExpression IDENT)
836                 ) 
837                 (   arguments                       ->  ^(METHOD_CALL $postfixedExpression genericTypeArgumentListSimplified? arguments)
838                 )?
839             |   THIS                                ->  ^(DOT $postfixedExpression THIS)
840             |   Super=SUPER arguments                   ->  ^(SUPER_CONSTRUCTOR_CALL[$Super, "SUPER_CONSTRUCTOR_CALL"] $postfixedExpression arguments)
841             |   (   SUPER innerDot=DOT IDENT        ->  ^($innerDot ^($outerDot $postfixedExpression SUPER) IDENT)
842                 )
843                 (   arguments                       ->  ^(METHOD_CALL $postfixedExpression arguments)
844                 )?
845             |   innerNewExpression                  ->  ^(DOT $postfixedExpression innerNewExpression)
846             )
847         |   LBRACK expression RBRACK                ->  ^(ARRAY_ELEMENT_ACCESS $postfixedExpression expression)
848         )*
849         // At the end there may follow a post increment/decrement.
850         (   INC -> ^(POST_INC[$INC, "POST_INC"] $postfixedExpression)
851         |   DEC -> ^(POST_DEC[$DEC, "POST_DEC"] $postfixedExpression)
852         )?
853     ;    
854     
855 primaryExpression
856     :   parenthesizedExpression
857     |   literal
858     |   newExpression
859     |   qualifiedIdentExpression
860     |   genericTypeArgumentListSimplified 
861         (   SUPER
862             (   arguments                               ->  ^(SUPER_CONSTRUCTOR_CALL[$SUPER, "SUPER_CONSTRUCTOR_CALL"] genericTypeArgumentListSimplified arguments)
863             |   DOT IDENT arguments                     ->  ^(METHOD_CALL ^(DOT SUPER IDENT) genericTypeArgumentListSimplified arguments)
864             )
865         |   IDENT arguments                             ->  ^(METHOD_CALL IDENT genericTypeArgumentListSimplified arguments)
866         |   THIS arguments                              ->  ^(THIS_CONSTRUCTOR_CALL[$THIS, "THIS_CONSTRUCTOR_CALL"] genericTypeArgumentListSimplified arguments)
867         )
868     |   (   THIS                                        ->  THIS
869         )
870         (   arguments                                   ->  ^(THIS_CONSTRUCTOR_CALL[$THIS, "THIS_CONSTRUCTOR_CALL"] arguments)
871         )?
872     |   SUPER arguments                                 ->  ^(SUPER_CONSTRUCTOR_CALL[$SUPER, "SUPER_CONSTRUCTOR_CALL"] arguments)
873     |   (   SUPER DOT IDENT
874         )
875         (   arguments                                   ->  ^(METHOD_CALL ^(DOT SUPER IDENT) arguments)
876         |                                               ->  ^(DOT SUPER IDENT)
877         )
878     |   (   primitiveType                               ->  primitiveType
879         )
880         (   arrayDeclarator                             ->  ^(arrayDeclarator $primaryExpression)   
881         )* 
882         DOT CLASS                                       ->  ^(DOT $primaryExpression CLASS)
883     |   VOID DOT CLASS                                  ->  ^(DOT VOID CLASS)
884     ;
885     
886 qualifiedIdentExpression
887         // The qualified identifier itself is the starting point for this rule.
888     :   (   qualifiedIdentifier                             ->  qualifiedIdentifier
889         )
890         // And now comes the stuff that may follow the qualified identifier.
891         (   (   arrayDeclarator                         ->  ^(arrayDeclarator $qualifiedIdentExpression)
892             )+ 
893             (   DOT CLASS                               ->  ^(DOT $qualifiedIdentExpression CLASS)
894             )
895         |   arguments                                   ->  ^(METHOD_CALL qualifiedIdentifier arguments)
896         |   outerDot=DOT
897             (   CLASS                                   ->  ^(DOT qualifiedIdentifier CLASS)
898             |   genericTypeArgumentListSimplified 
899                 (   Super=SUPER arguments               ->  ^(SUPER_CONSTRUCTOR_CALL[$Super, "SUPER_CONSTRUCTOR_CALL"] qualifiedIdentifier genericTypeArgumentListSimplified arguments)
900                 |   SUPER innerDot=DOT IDENT arguments  ->  ^(METHOD_CALL ^($innerDot ^($outerDot qualifiedIdentifier SUPER) IDENT) genericTypeArgumentListSimplified arguments)
901                 |   IDENT arguments                     ->  ^(METHOD_CALL ^(DOT qualifiedIdentifier IDENT) genericTypeArgumentListSimplified arguments)
902                 )
903             |   THIS                                    ->  ^(DOT qualifiedIdentifier THIS)
904             |   Super=SUPER arguments                   ->  ^(SUPER_CONSTRUCTOR_CALL[$Super, "SUPER_CONSTRUCTOR_CALL"] qualifiedIdentifier arguments)
905             |   innerNewExpression                      ->  ^(DOT qualifiedIdentifier innerNewExpression)
906             )
907         )?
908     ;
909
910 newExpression
911     :   NEW  
912         (   primitiveType newArrayConstruction      // new static array of primitive type elements
913             ->  ^(STATIC_ARRAY_CREATOR[$NEW, "STATIC_ARRAY_CREATOR"] primitiveType newArrayConstruction)
914         |   genericTypeArgumentListSimplified? qualifiedTypeIdentSimplified
915             (   newArrayConstruction                // new static array of object type reference elements
916                 ->  ^(STATIC_ARRAY_CREATOR[$NEW, "STATIC_ARRAY_CREATOR"] genericTypeArgumentListSimplified? qualifiedTypeIdentSimplified newArrayConstruction)
917             |   arguments classBody?                // new object type via constructor invocation
918                 ->  ^(CLASS_CONSTRUCTOR_CALL[$NEW, "STATIC_ARRAY_CREATOR"] genericTypeArgumentListSimplified? qualifiedTypeIdentSimplified arguments classBody?)
919             )
920         )
921     ;
922     
923 innerNewExpression // something like 'InnerType innerType = outer.new InnerType();'
924     :   NEW genericTypeArgumentListSimplified? IDENT arguments classBody?
925         ->  ^(CLASS_CONSTRUCTOR_CALL[$NEW, "STATIC_ARRAY_CREATOR"] genericTypeArgumentListSimplified? IDENT arguments classBody?)
926     ;
927
928 newArrayConstruction
929     :   arrayDeclaratorList arrayInitializer
930     |   LBRACK! expression RBRACK! (LBRACK! expression RBRACK!)* arrayDeclaratorList?
931     ;
932
933 arguments
934     :   LPAREN expressionList? RPAREN
935         ->  ^(ARGUMENT_LIST[$LPAREN, "ARGUMENT_LIST"] expressionList?)
936     ;
937
938 literal 
939     :   HEX_LITERAL
940     |   OCTAL_LITERAL
941     |   DECIMAL_LITERAL
942     |   FLOATING_POINT_LITERAL
943     |   CHARACTER_LITERAL
944     |   STRING_LITERAL
945     |   TRUE
946     |   FALSE
947     |   NULL
948     ;
949
950 // LEXER
951
952 HEX_LITERAL : '0' ('x'|'X') HEX_DIGIT+ INTEGER_TYPE_SUFFIX? ;
953
954 DECIMAL_LITERAL : ('0' | '1'..'9' '0'..'9'*) INTEGER_TYPE_SUFFIX? ;
955
956 OCTAL_LITERAL : '0' ('0'..'7')+ INTEGER_TYPE_SUFFIX? ;
957
958 fragment
959 HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
960
961 fragment
962 INTEGER_TYPE_SUFFIX : ('l'|'L') ;
963
964 FLOATING_POINT_LITERAL
965     :   ('0'..'9')+ 
966         (
967             DOT ('0'..'9')* EXPONENT? FLOAT_TYPE_SUFFIX?
968         |   EXPONENT FLOAT_TYPE_SUFFIX?
969         |   FLOAT_TYPE_SUFFIX
970         )
971     |   DOT ('0'..'9')+ EXPONENT? FLOAT_TYPE_SUFFIX?
972     ;
973
974 fragment
975 EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
976
977 fragment
978 FLOAT_TYPE_SUFFIX : ('f'|'F'|'d'|'D') ;
979
980 CHARACTER_LITERAL
981     :   '\'' ( ESCAPE_SEQUENCE | ~('\''|'\\') ) '\''
982     ;
983
984 STRING_LITERAL
985     :  '"' ( ESCAPE_SEQUENCE | ~('\\'|'"') )* '"'
986     ;
987
988 fragment
989 ESCAPE_SEQUENCE
990     :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
991     |   UNICODE_ESCAPE
992     |   OCTAL_ESCAPE
993     ;
994
995 fragment
996 OCTAL_ESCAPE
997     :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
998     |   '\\' ('0'..'7') ('0'..'7')
999     |   '\\' ('0'..'7')
1000     ;
1001
1002 fragment
1003 UNICODE_ESCAPE
1004     :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
1005     ;
1006
1007 IDENT
1008     :   CHARJ_ID_START (CHARJ_ID_PART)*
1009     ;
1010
1011 fragment
1012 CHARJ_ID_START
1013     :  '\u0024'
1014     |  '\u0041'..'\u005a'
1015     |  '\u005f'
1016     |  '\u0061'..'\u007a'
1017     |  '\u00c0'..'\u00d6'
1018     |  '\u00d8'..'\u00f6'
1019     |  '\u00f8'..'\u00ff'
1020     |  '\u0100'..'\u1fff'
1021     |  '\u3040'..'\u318f'
1022     |  '\u3300'..'\u337f'
1023     |  '\u3400'..'\u3d2d'
1024     |  '\u4e00'..'\u9fff'
1025     |  '\uf900'..'\ufaff'
1026     ;
1027
1028 fragment
1029 CHARJ_ID_PART
1030     :  CHARJ_ID_START
1031     |  '\u0030'..'\u0039'
1032     ;
1033
1034 WS  :  (' '|'\r'|'\t'|'\u000C'|'\n') 
1035     {   
1036         if (!preserveWhitespacesAndComments) {
1037             skip();
1038         } else {
1039             $channel = HIDDEN;
1040         }
1041     }
1042     ;
1043
1044 COMMENT
1045     :   '/*' ( options {greedy=false;} : . )* '*/'
1046     {   
1047         if (!preserveWhitespacesAndComments) {
1048             skip();
1049         } else {
1050             $channel = HIDDEN;
1051         }
1052     }
1053     ;
1054
1055 LINE_COMMENT
1056     : '//' ~('\n'|'\r')* '\r'? '\n'
1057     {   
1058         if (!preserveWhitespacesAndComments) {
1059             skip();
1060         } else {
1061             $channel = HIDDEN;
1062         }
1063     }
1064     ;