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