[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Java2 grammar



Hi,
we changed the java to grammar a bit, so now you will be able to
parse the whole JDK and the grammar is now able to deal with the
creation of inner classes from outside the containing class.

Hope it's usefull to someone.

Cheers Thomas

==========================================================================
Thomas Leonhardt           email  leonhardt@informatik.tu-darmstadt.de
TU Darmstadt               WWW    http://www.pi.informatik.tu-darmstadt.de
FG Praktische Informatik   phone  +49 / (0)6151 / 16 - 5313
D-64283 Darmstadt          fax    +49 / (0)6151 / 16 - 5472
Germany
==========================================================================


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * This file is part of J11.                                       *
 * See the file "J11-LICENSE" for Copyright information and the    *
 * terms and conditions for copying, distribution and              *
 * modification of J11.                                            *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/*******************************************************************
 * Etienne Gagnon: I have built this grammar based to the          *
 * information on pages 19-23 of the "Inner Classes Specification  *
 * document.                                                       *
 * Sun has not released yet an official grammar for Java 1.1 and I *
 * suspect that the definition of Java identifiers has changed and *
 * is different from the Java 1.02 version. This intuition comes   *
 * from noticing the deprecation of Character.isJavaLetter() and   *
 * isJavaLetterOrDigit() methods.                                  *
 * In this grammar, I have not changed the lexer. So I scan        *
 * Java 1.02 identifiers. This is the only documented definition   *
 * of identifiers that I have. If somebody has better information, *
 * please let me know.                                             *
 *******************************************************************/

/*
 * Project CKTEST
 * Changes to the original grammar are marked with a [CHANGED] tag.
 *
 */

Package tud.inf.pi.sablecc.java2;

/*******************************************************************
 * Helpers                                                         *
 *******************************************************************/
Helpers

    unicode_input_character = [0..0xffff];
    ht  = 0x0009;
    lf  = 0x000a;
    ff  = 0x000c;
    cr  = 0x000d;
    sp  = ' ';

    line_terminator = lf | cr | cr lf;
    input_character = [unicode_input_character - [cr + lf]];

    not_star =    [input_character - '*'] | line_terminator;
    not_star_not_slash = [input_character - ['*' + '/']] | line_terminator;

    unicode_letter =
        [0x0041..0x005a] | [0x0061..0x007a] | [0x00aa..0x00aa] |
[0x00b5..0x00b5] |
        [0x00ba..0x00ba] | [0x00c0..0x00d6] | [0x00d8..0x00f6] |
[0x00f8..0x01f5] |
        [0x01fa..0x0217] | [0x0250..0x02a8] | [0x02b0..0x02b8] |
[0x02bb..0x02c1] |
        [0x02d0..0x02d1] | [0x02e0..0x02e4] | [0x037a..0x037a] |
[0x0386..0x0386] |
        [0x0388..0x038a] | [0x038c..0x038c] | [0x038e..0x03a1] |
[0x03a3..0x03ce] |
        [0x03d0..0x03d6] | [0x03da..0x03da] | [0x03dc..0x03dc] |
[0x03de..0x03de] |
        [0x03e0..0x03e0] | [0x03e2..0x03f3] | [0x0401..0x040c] |
[0x040e..0x044f] |
        [0x0451..0x045c] | [0x045e..0x0481] | [0x0490..0x04c4] |
[0x04c7..0x04c8] |
        [0x04cb..0x04cc] | [0x04d0..0x04eb] | [0x04ee..0x04f5] |
[0x04f8..0x04f9] |
        [0x0531..0x0556] | [0x0559..0x0559] | [0x0561..0x0587] |
[0x05d0..0x05ea] |
        [0x05f0..0x05f2] | [0x0621..0x063a] | [0x0640..0x064a] |
[0x0671..0x06b7] |
        [0x06ba..0x06be] | [0x06c0..0x06ce] | [0x06d0..0x06d3] |
[0x06d5..0x06d5] |
        [0x06e5..0x06e6] | [0x0905..0x0939] | [0x093d..0x093d] |
[0x0958..0x0961] |
        [0x0985..0x098c] | [0x098f..0x0990] | [0x0993..0x09a8] |
[0x09aa..0x09b0] |
        [0x09b2..0x09b2] | [0x09b6..0x09b9] | [0x09dc..0x09dd] |
[0x09df..0x09e1] |
        [0x09f0..0x09f1] | [0x0a05..0x0a0a] | [0x0a0f..0x0a10] |
[0x0a13..0x0a28] |
        [0x0a2a..0x0a30] | [0x0a32..0x0a33] | [0x0a35..0x0a36] |
[0x0a38..0x0a39] |
        [0x0a59..0x0a5c] | [0x0a5e..0x0a5e] | [0x0a72..0x0a74] |
[0x0a85..0x0a8b] |
        [0x0a8d..0x0a8d] | [0x0a8f..0x0a91] | [0x0a93..0x0aa8] |
[0x0aaa..0x0ab0] |
        [0x0ab2..0x0ab3] | [0x0ab5..0x0ab9] | [0x0abd..0x0abd] |
[0x0ae0..0x0ae0] |
        [0x0b05..0x0b0c] | [0x0b0f..0x0b10] | [0x0b13..0x0b28] |
[0x0b2a..0x0b30] |
        [0x0b32..0x0b33] | [0x0b36..0x0b39] | [0x0b3d..0x0b3d] |
[0x0b5c..0x0b5d] |
        [0x0b5f..0x0b61] | [0x0b85..0x0b8a] | [0x0b8e..0x0b90] |
[0x0b92..0x0b95] |
        [0x0b99..0x0b9a] | [0x0b9c..0x0b9c] | [0x0b9e..0x0b9f] |
[0x0ba3..0x0ba4] |
        [0x0ba8..0x0baa] | [0x0bae..0x0bb5] | [0x0bb7..0x0bb9] |
[0x0c05..0x0c0c] |
        [0x0c0e..0x0c10] | [0x0c12..0x0c28] | [0x0c2a..0x0c33] |
[0x0c35..0x0c39] |
        [0x0c60..0x0c61] | [0x0c85..0x0c8c] | [0x0c8e..0x0c90] |
[0x0c92..0x0ca8] |
        [0x0caa..0x0cb3] | [0x0cb5..0x0cb9] | [0x0cde..0x0cde] |
[0x0ce0..0x0ce1] |
        [0x0d05..0x0d0c] | [0x0d0e..0x0d10] | [0x0d12..0x0d28] |
[0x0d2a..0x0d39] |
        [0x0d60..0x0d61] | [0x0e01..0x0e2e] | [0x0e30..0x0e30] |
[0x0e32..0x0e33] |
        [0x0e40..0x0e46] | [0x0e81..0x0e82] | [0x0e84..0x0e84] |
[0x0e87..0x0e88] |
        [0x0e8a..0x0e8a] | [0x0e8d..0x0e8d] | [0x0e94..0x0e97] |
[0x0e99..0x0e9f] |
        [0x0ea1..0x0ea3] | [0x0ea5..0x0ea5] | [0x0ea7..0x0ea7] |
[0x0eaa..0x0eab] |
        [0x0ead..0x0eae] | [0x0eb0..0x0eb0] | [0x0eb2..0x0eb3] |
[0x0ebd..0x0ebd] |
        [0x0ec0..0x0ec4] | [0x0ec6..0x0ec6] | [0x0edc..0x0edd] |
[0x0f40..0x0f47] |
        [0x0f49..0x0f69] | [0x10a0..0x10c5] | [0x10d0..0x10f6] |
[0x1100..0x1159] |
        [0x115f..0x11a2] | [0x11a8..0x11f9] | [0x1e00..0x1e9b] |
[0x1ea0..0x1ef9] |
        [0x1f00..0x1f15] | [0x1f18..0x1f1d] | [0x1f20..0x1f45] |
[0x1f48..0x1f4d] |
        [0x1f50..0x1f57] | [0x1f59..0x1f59] | [0x1f5b..0x1f5b] |
[0x1f5d..0x1f5d] |
        [0x1f5f..0x1f7d] | [0x1f80..0x1fb4] | [0x1fb6..0x1fbc] |
[0x1fbe..0x1fbe] |
        [0x1fc2..0x1fc4] | [0x1fc6..0x1fcc] | [0x1fd0..0x1fd3] |
[0x1fd6..0x1fdb] |
        [0x1fe0..0x1fec] | [0x1ff2..0x1ff4] | [0x1ff6..0x1ffc] |
[0x207f..0x207f] |
        [0x2102..0x2102] | [0x2107..0x2107] | [0x210a..0x2113] |
[0x2115..0x2115] |
        [0x2118..0x211d] | [0x2124..0x2124] | [0x2126..0x2126] |
[0x2128..0x2128] |
        [0x212a..0x2131] | [0x2133..0x2138] | [0x3005..0x3005] |
[0x3031..0x3035] |
        [0x3041..0x3094] | [0x309b..0x309e] | [0x30a1..0x30fa] |
[0x30fc..0x30fe] |
        [0x3105..0x312c] | [0x3131..0x318e] | [0x4e00..0x9fa5] |
[0xac00..0xd7a3] |
        [0xf900..0xfa2d] | [0xfb00..0xfb06] | [0xfb13..0xfb17] |
[0xfb1f..0xfb28] |
        [0xfb2a..0xfb36] | [0xfb38..0xfb3c] | [0xfb3e..0xfb3e] |
[0xfb40..0xfb41] |
        [0xfb43..0xfb44] | [0xfb46..0xfbb1] | [0xfbd3..0xfd3d] |
[0xfd50..0xfd8f] |
        [0xfd92..0xfdc7] | [0xfdf0..0xfdfb] | [0xfe70..0xfe72] |
[0xfe74..0xfe74] |
        [0xfe76..0xfefc] | [0xff21..0xff3a] | [0xff41..0xff5a] |
[0xff66..0xffbe] |
        [0xffc2..0xffc7] | [0xffca..0xffcf] | [0xffd2..0xffd7] |
[0xffda..0xffdc];

    unicode_digit =
        [0x0030..0x0039] | [0x0660..0x0669] | [0x06f0..0x06f9] |
[0x0966..0x096f] |
        [0x09e6..0x09ef] | [0x0a66..0x0a6f] | [0x0ae6..0x0aef] |
[0x0b66..0x0b6f] |
        [0x0be7..0x0bef] | [0x0c66..0x0c6f] | [0x0ce6..0x0cef] |
[0x0d66..0x0d6f] |
        [0x0e50..0x0e59] | [0x0ed0..0x0ed9] | [0x0f20..0x0f29] |
[0xff10..0xff19];

    java_letter = unicode_letter | '$' | '_';
    java_letter_or_digit = unicode_letter | unicode_digit | '$' | '_';

    non_zero_digit = ['1'..'9'];
    digit = ['0'..'9'];
    hex_digit = ['0'..'9'] | ['a'..'f'] | ['A'..'F'];
    octal_digit = ['0'..'7'];
    zero_to_three = ['0'..'3'];

    decimal_numeral = '0' | non_zero_digit digit*;
    hex_numeral = '0' ('x' | 'X') hex_digit+;
    octal_numeral = '0' octal_digit+;

    integer_type_suffix = 'l' | 'L';

    exponent_part = ('e' | 'E') ('+' | '-')? digit+;

    float_type_suffix = 'f' | 'F' | 'd' | 'D';

    single_character = [input_character - [''' + '\']];
    octal_escape = '\' (octal_digit octal_digit? | zero_to_three octal_digit
octal_digit);
    escape_sequence = '\b' | '\t' | '\n' | '\f' | '\r' | '\"' | '\' ''' |
'\\' | octal_escape;
    string_character = [input_character - ['"' + '\']] | escape_sequence;

/*******************************************************************
 * Tokens                                                          *
 *******************************************************************/
Tokens

    white_space = (sp | ht | ff | line_terminator)*;

    traditional_comment = '/*' not_star+ '*'+ (not_star_not_slash not_star*
'*'+)* '/';
    documentation_comment =    '/**' '*'* (not_star_not_slash not_star*
'*'+)* '/';


/***************************************************************************
*************
     * Here, we take into account the possibilily that the line terminator
might be missing *
     * at the end of the last line of a file. This is imprecise in the Java
Language        *
     * Specification, because it is not clear if a line terminator should be
added to the   *
     * last line, or not. "javac", the reference compiler, accepts and
end-of-line-comment, *
     * even if the line terminator is missing from the last line.
*

****************************************************************************
************/
    end_of_line_comment = '//' input_character* line_terminator?;

    abstract = 'abstract';
    boolean = 'boolean';
    break = 'break';
    byte = 'byte';
    case = 'case';
    catch = 'catch';
    char = 'char';
    class = 'class';
    const = 'const';
    continue = 'continue';
    default = 'default';
    do = 'do';
    double = 'double';
    else = 'else';
    extends = 'extends';
    final = 'final';
    finally = 'finally';
    float = 'float';
    for = 'for';
    goto = 'goto';
    if = 'if';
    implements = 'implements';
    import = 'import';
    instanceof = 'instanceof';
    int = 'int';
    interface = 'interface';
    long = 'long';
    native = 'native';
    new = 'new';
    package = 'package';
    private = 'private';
    protected = 'protected';
    public = 'public';
    return = 'return';
    short = 'short';
    static = 'static';
    strictfp = 'strictfp';     /* [CHANGED] Rolf: New keyword in java2 */
    super = 'super';
    switch = 'switch';
    synchronized = 'synchronized';
    this = 'this';
    throw = 'throw';
    throws = 'throws';
    transient = 'transient';
    try = 'try';
    void = 'void';
    volatile = 'volatile';
    while = 'while';

    true = 'true';
    false = 'false';
    null = 'null';

    l_parenthese = '(';
    r_parenthese = ')';
    l_brace = '{';
    r_brace = '}';
    l_bracket = '[';
    r_bracket = ']';
    semicolon = ';';
    comma = ',';
    dot = '.';

    assign = '=';
    lt = '<';
    gt = '>';
    complement = '!';
    bit_complement = '~';
    question = '?';
    colon = ':';

    eq = '==';
    lteq = '<=';
    gteq ='>=';
    neq = '!=';
    and = '&&';
    or = '||';
    plus_plus = '++';
    minus_minus = '--';

    plus = '+';
    minus = '-';
    star = '*';
    div = '/';
    bit_and = '&';
    bit_or = '|';
    bit_xor = '^';
    mod = '%';
    shift_left = '<<';
    signed_shift_right = '>>';
    unsigned_shift_right = '>>>';

    plus_assign = '+=';
    minus_assign = '-=';
    star_assign = '*=';
    div_assign = '/=';
    bit_and_assign = '&=';
    bit_or_assign = '|=';
    bit_xor_assign = '^=';
    mod_assign = '%=';
    shift_left_assign = '<<=';
    signed_shift_right_assign = '>>=';
    unsigned_shift_right_assign = '>>>=';

    decimal_integer_literal = decimal_numeral integer_type_suffix?;
    hex_integer_literal = hex_numeral integer_type_suffix?;
    octal_integer_literal = octal_numeral integer_type_suffix?;

    floating_point_literal =
        digit+ '.' digit* exponent_part? float_type_suffix? |
        '.' digit+ exponent_part? float_type_suffix? |
        digit+ exponent_part float_type_suffix? |
        digit+ exponent_part? float_type_suffix;

    character_literal = ''' (single_character | escape_sequence) ''';
    string_literal = '"' string_character* '"';

    identifier = java_letter java_letter_or_digit*;

/*******************************************************************
 * Ignored Tokens                                                  *
 *******************************************************************/
Ignored Tokens

  white_space,
  traditional_comment,
  documentation_comment,
  end_of_line_comment;


/*******************************************************************
 * Productions                                                     *
 *******************************************************************/
Productions

/********************************************************************
19.2 Grammar from §2.3: The Syntactic Grammar §2.3
********************************************************************/

goal =
    compilation_unit;

/********************************************************************
19.3 Grammar from §3: Lexical Structure §3
********************************************************************/

literal =
    {integer_literal}
        integer_literal |

    {floating_point_literal}
        floating_point_literal |

    {boolean_literal}
        boolean_literal |

    {character_literal}
        character_literal |

    {string_literal}
        string_literal |

    {null_literal}
        null_literal;

/********************************************************************
19.4 Grammar from §4: Types, Values, and Variables §4
********************************************************************/

type =
    {primitive_type}
        primitive_type |

    {reference_type}
        reference_type;

primitive_type =
    {numeric_type}
        numeric_type |

    {boolean}
        boolean;

numeric_type =
    {integral_type}
        integral_type |

    {floating_point_type}
        floating_point_type;

integral_type =
    {byte}
        byte |

    {short}
        short |

    {int}
        int |

    {long}
        long |

    {char}
        char;

floating_point_type =
    {float}
        float |

    {double}
        double;

reference_type =
    {class_or_interface_type}
        class_or_interface_type |

    {array_type}
        array_type;

class_or_interface_type =
    name;

class_type =
    class_or_interface_type;

interface_type =
    class_or_interface_type;

array_type =
    {primitive_type}
        primitive_type dims |

    {name}
        name dims;

/********************************************************************
19.5 Grammar from §6: Names §6
********************************************************************/

name =
    {simple_name}
        simple_name |

    {qualified_name}
        qualified_name;

simple_name =
    identifier;

qualified_name =
    name dot identifier;

/********************************************************************
19.6 Grammar from §7: Packages §7
********************************************************************/

compilation_unit =
    package_declaration? import_declaration* type_declaration*;

package_declaration =
    package name semicolon;

import_declaration =
    {single_type_import_declaration}
        single_type_import_declaration |

    {type_import_on_demand_declaration}
        type_import_on_demand_declaration;

single_type_import_declaration =
    import name semicolon;

type_import_on_demand_declaration =
    import name dot star semicolon;

type_declaration =
    {class_declaration}
        class_declaration |

    {interface_declaration}
        interface_declaration |

    {semicolon}
        semicolon;

/********************************************************************
19.7 Productions Used Only in the LALR(1) Grammar
********************************************************************/

modifier =
    {public}
        public |

    {protected}
        protected |

    {private}
        private |

    {static}
        static |

    {abstract}
        abstract |

    {final}
        final |

    {native}
        native |

    {synchronized}
        synchronized |

    {transient}
        transient |

    {volatile}
        volatile |

    {strictfp}       /* [CHANGED] Rolf */
        strictfp;

/********************************************************************
19.8.1 Grammar from §8.1: Class Declaration §8.1
********************************************************************/

class_declaration =
    modifier* [t_class]:class identifier P.super? interfaces? class_body;

super =
    extends class_type;

interfaces =
    implements interface_type_list;

interface_type_list =
    {interface_type}
        interface_type |

    {interface_type_list}
        interface_type_list comma interface_type;

class_body =
    l_brace class_body_declaration* r_brace;

class_body_declaration =
    {class_member_declaration}
        class_member_declaration |

    {static_initializer}
        static_initializer |

    {constructor_declaration}
        constructor_declaration |

    {block}
        block;

class_member_declaration =
    {field_declaration}
        field_declaration |

    {method_declaration}
        method_declaration |

    {class_declaration}
        class_declaration |

    {interface_declaration}
        interface_declaration |

    {semicolon}       /* [CHANGED] Rolf: A semicolon may appear here (See
JDK sources) */
        semicolon;

/********************************************************************
19.8.2 Grammar from §8.3: Field Declarations §8.3
********************************************************************/

field_declaration =
    modifier* type variable_declarators semicolon;

variable_declarators =
    {variable_declarator}
        variable_declarator |

    {variable_declarators}
        variable_declarators comma variable_declarator;

variable_declarator =
    {variable_declarator_id}
        variable_declarator_id |

    {assign}
        variable_declarator_id assign variable_initializer;

variable_declarator_id =
    {identifier}
        identifier |

    {variable_declarator_id}
        variable_declarator_id l_bracket r_bracket;

variable_initializer =
    {expression}
        expression |

    {array_initializer}
        array_initializer;

/********************************************************************
19.8.3 Grammar from §8.4: Method Declarations §8.4
********************************************************************/

method_declaration =
    method_header method_body;

method_header =
    {type}
        modifier* type method_declarator P.throws? |

    {void}
        modifier* void method_declarator P.throws?;

method_declarator =
    {identifier}
        identifier l_parenthese formal_parameter_list? r_parenthese |

    {method_declarator}
        method_declarator l_bracket r_bracket;

formal_parameter_list =
    {formal_parameter}
        formal_parameter |

    {formal_parameter_list}
        formal_parameter_list comma formal_parameter;

formal_parameter =
    modifier* type variable_declarator_id;

throws =
    T.throws class_type_list;

class_type_list =
    {class_type}
        class_type |

    {class_type_list}
        class_type_list comma class_type;

method_body =
    {block}
        block |

    {semicolon}
        semicolon;

/********************************************************************
19.8.4 Grammar from §8.5: Static Initializers §8.5
********************************************************************/

static_initializer =
    static block;

/********************************************************************
19.8.5 Grammar from §8.6: Constructor Declarations §8.6
********************************************************************/

constructor_declaration =
    modifier* constructor_declarator P.throws? constructor_body;

constructor_declarator =
    simple_name l_parenthese formal_parameter_list? r_parenthese;

constructor_body =
    l_brace explicit_constructor_invocation? block_statement* r_brace;

explicit_constructor_invocation =
    {this}
        this l_parenthese argument_list? r_parenthese semicolon |

    {super}
        T.super l_parenthese argument_list? r_parenthese semicolon |

    {qualified}
        primary dot T.super l_parenthese argument_list? r_parenthese
semicolon;

/********************************************************************
19.9.1 Grammar from §9.1: Interface Declarations §9.1
********************************************************************/

interface_declaration =
    modifier* interface identifier extends_interfaces? interface_body;

extends_interfaces =
    {extends}
        extends interface_type |

    {extends_interfaces}
        extends_interfaces comma interface_type;

interface_body =
    l_brace interface_member_declaration* r_brace;

interface_member_declaration =
    {constant_declaration}
        constant_declaration |

    {abstract_method_declaration}
        abstract_method_declaration |

    {class_declaration}
        class_declaration |

    {interface_declaration}
        interface_declaration |

    {semicolon}       /* [CHANGED] Rolf: A semicolon may appear here (See
JDK sources) */
        semicolon;

constant_declaration =
    field_declaration;

abstract_method_declaration =
    method_header semicolon;

/********************************************************************
19.10 Grammar from §10: Arrays §10
********************************************************************/

array_initializer =
    l_brace variable_initializers? comma? r_brace;

variable_initializers =
    {variable_initializer}
        variable_initializer |

    {variable_initializers}
        variable_initializers comma variable_initializer;

/********************************************************************
19.11 Grammar from §14: Blocks and Statements §14
********************************************************************/

block =
    l_brace block_statement* r_brace;

block_statement =
    {local_variable_declaration_statement}
        local_variable_declaration_statement |

    {statement}
        statement |

    {class_declaration}
        class_declaration;

local_variable_declaration_statement =
    local_variable_declaration semicolon;

local_variable_declaration =
    modifier* type variable_declarators;

statement =
    {statement_without_trailing_substatement}
        statement_without_trailing_substatement |

    {labeled_statement}
        labeled_statement |

    {if_then_statement}
        if_then_statement |

    {if_then_else_statement}
        if_then_else_statement |

    {while_statement}
        while_statement |

    {for_statement}
        for_statement;

statement_no_short_if =
    {statement_without_trailing_substatement}
        statement_without_trailing_substatement |

    {labeled_statement_no_short_if}
        labeled_statement_no_short_if |

    {if_then_else_statement_no_short_if}
        if_then_else_statement_no_short_if |

    {while_statement_no_short_if}
        while_statement_no_short_if |

    {for_statement_no_short_if}
        for_statement_no_short_if;

statement_without_trailing_substatement =
    {block}
        block |

    {empty_statement}
        empty_statement |

    {expression_statement}
        expression_statement |

    {switch_statement}
        switch_statement |

    {do_statement}
        do_statement |

    {break_statement}
        break_statement |

    {continue_statement}
        continue_statement |

    {return_statement}
        return_statement |

    {synchronized_statement}
        synchronized_statement |

    {throw_statement}
        throw_statement |

    {try_statement}
        try_statement;

empty_statement =
    semicolon;

labeled_statement =
    identifier colon statement;

labeled_statement_no_short_if =
    identifier colon statement_no_short_if;

expression_statement =
    statement_expression semicolon;

statement_expression =
    {assignment}
        assignment |

    {pre_increment_expression}
        pre_increment_expression |

    {pre_decrement_expression}
        pre_decrement_expression |

    {post_increment_expression}
        post_increment_expression |

    {post_decrement_expression}
        post_decrement_expression |

    {method_invocation}
        method_invocation |

    {class_instance_creation_expression}
        class_instance_creation_expression;

if_then_statement =
    if l_parenthese expression r_parenthese statement;

if_then_else_statement =
    if l_parenthese expression r_parenthese statement_no_short_if else
statement;

if_then_else_statement_no_short_if =
    if l_parenthese expression r_parenthese
[statement_no_short_if1]:statement_no_short_if else
[statement_no_short_if2]:statement_no_short_if;

switch_statement =
    switch l_parenthese expression r_parenthese switch_block;

switch_block =
    l_brace switch_block_statement_group* switch_label* r_brace;

switch_block_statement_group =
    switch_label+ block_statement+;

switch_label =
    {case}
        case constant_expression colon |

    {default}
        default colon;

while_statement =
    while l_parenthese expression r_parenthese statement;

while_statement_no_short_if =
    while l_parenthese expression r_parenthese statement_no_short_if;

do_statement =
    do statement while l_parenthese expression r_parenthese semicolon;

for_statement =
    for l_parenthese for_init? [semicolon1]:semicolon expression?
[semicolon2]:semicolon for_update? r_parenthese statement;

for_statement_no_short_if =
    for l_parenthese for_init? [semicolon1]:semicolon expression?
[semicolon2]:semicolon for_update? r_parenthese statement_no_short_if;

for_init =
    {statement_expression_list}
        statement_expression_list |

    {local_variable_declaration}
        local_variable_declaration;

for_update =
    statement_expression_list;

statement_expression_list =
    {statement_expression}
        statement_expression |

    {statement_expression_list}
        statement_expression_list comma statement_expression;

break_statement =
    break identifier? semicolon;

continue_statement =
    continue identifier? semicolon;

return_statement =
    return expression? semicolon;

throw_statement =
    throw expression semicolon;

synchronized_statement =
    synchronized l_parenthese expression r_parenthese block;

try_statement =
    {try}
        try block catch_clause+ |

    {finally}
        try block catch_clause* P.finally;

catch_clause =
    catch l_parenthese formal_parameter r_parenthese block;

finally =
    T.finally block;

/********************************************************************
19.12 Grammar from §15: Expressions §15
********************************************************************/

primary =
    {primary_no_new_array}
        primary_no_new_array |

    {array_creation_expression}
        array_creation_expression;

primary_no_new_array =
    {literal}
        literal |

    {this}
        this |

    {l_parenthese}
        l_parenthese expression r_parenthese |

    {class_instance_creation_expression}
        class_instance_creation_expression |

    {field_access}
        field_access |

    {method_invocation}
        method_invocation |

    {array_access}
        array_access |

    {qualified_this}
        name dot this |

    {primitive_type}
        primitive_type dims? dot [t_class]:class |

    {named_type}
        name dims? dot [t_class]:class |

    {void}
        void dot [t_class]:class;

class_instance_creation_expression =
    {simple}
        new name l_parenthese argument_list? r_parenthese class_body? |

    {qualified}
        primary dot new identifier l_parenthese argument_list? r_parenthese
class_body? |

		/* [CHANGED] Leo: Added the following production to enable creation of
inner classes */

    {innerclass}
        name dot new identifier l_parenthese argument_list? r_parenthese
class_body?;


argument_list =
    {expression}
        expression |

    {argument_list}
        argument_list comma expression;

array_creation_expression =
    {primitive_type}
        new primitive_type dim_expr+ dims? |

    {class_or_interface_type}
        new class_or_interface_type dim_expr+ dims? |

    {init_primitive}
        new primitive_type dims array_initializer |

    {init_class_interface}
        new class_or_interface_type dims array_initializer;

dim_expr =
    l_bracket expression r_bracket;

dims =
    {l_bracket}
        l_bracket r_bracket |

    {dims}
        dims l_bracket r_bracket;

field_access =
    {primary}
        primary dot identifier |

    {super}
        T.super dot identifier;

method_invocation =
    {name}
        name l_parenthese argument_list? r_parenthese |

    {primary}
        primary dot identifier l_parenthese argument_list? r_parenthese |

    {super}
        T.super dot identifier l_parenthese argument_list? r_parenthese;

array_access =
    {name}
        name l_bracket expression r_bracket |

    {primary_no_new_array}
        primary_no_new_array l_bracket expression r_bracket;

postfix_expression =
    {primary}
        primary |

    {name}
        name |

    {post_increment_expression}
        post_increment_expression |

    {post_decrement_expression}
        post_decrement_expression;

post_increment_expression =
    postfix_expression plus_plus;

post_decrement_expression =
    postfix_expression minus_minus;

unary_expression =
    {pre_increment_expression}
        pre_increment_expression |

    {pre_decrement_expression}
        pre_decrement_expression |

    {plus}
        plus unary_expression |

    {minus}
        minus unary_expression |

    {unary_expression_not_plus_minus}
        unary_expression_not_plus_minus;

pre_increment_expression =
    plus_plus unary_expression;

pre_decrement_expression =
    minus_minus unary_expression;

unary_expression_not_plus_minus =
    {postfix_expression}
        postfix_expression |

    {bit_complement}
        bit_complement unary_expression |

    {complement}
        complement unary_expression |

    {cast_expression}
        cast_expression;

cast_expression =
    {primitive_type}
        l_parenthese primitive_type dims? r_parenthese unary_expression |

    {expression}
        l_parenthese expression r_parenthese unary_expression_not_plus_minus
|

    {name}
        l_parenthese name dims r_parenthese unary_expression_not_plus_minus;

multiplicative_expression =
    {unary_expression}
        unary_expression |

    {star}
        multiplicative_expression star unary_expression |

    {div}
        multiplicative_expression div unary_expression |

    {mod}
        multiplicative_expression mod unary_expression;

additive_expression =
    {multiplicative_expression}
        multiplicative_expression |

    {plus}
        additive_expression plus multiplicative_expression |

    {minus}
        additive_expression minus multiplicative_expression;

shift_expression =
    {additive_expression}
        additive_expression |

    {shift_left}
        shift_expression shift_left additive_expression |

    {signed_shift_right}
        shift_expression signed_shift_right additive_expression |

    {unsigned_shift_right}
        shift_expression unsigned_shift_right additive_expression;

relational_expression =
    {shift_expression}
        shift_expression |

    {lt}
        relational_expression lt shift_expression |

    {gt}
        relational_expression gt shift_expression |

    {lteq}
        relational_expression lteq shift_expression |

    {gteq}
        relational_expression gteq shift_expression |

    {instanceof}
        relational_expression instanceof reference_type;

equality_expression =
    {relational_expression}
        relational_expression |

    {eq}
        equality_expression eq relational_expression |

    {neq}
        equality_expression neq relational_expression;

and_expression =
    {equality_expression}
        equality_expression |

    {and_expression}
        and_expression bit_and equality_expression;

exclusive_or_expression =
    {and_expression}
        and_expression |

    {exclusive_or_expression}
        exclusive_or_expression bit_xor and_expression;

inclusive_or_expression =
    {exclusive_or_expression}
        exclusive_or_expression |

    {inclusive_or_expression}
        inclusive_or_expression bit_or exclusive_or_expression;

conditional_and_expression =
    {inclusive_or_expression}
        inclusive_or_expression |

    {conditional_and_expression}
        conditional_and_expression and inclusive_or_expression;

conditional_or_expression =
    {conditional_and_expression}
        conditional_and_expression |

    {conditional_or_expression}
        conditional_or_expression or conditional_and_expression;

conditional_expression =
    {conditional_or_expression}
        conditional_or_expression |

    {question}
        conditional_or_expression question expression colon
conditional_expression;

assignment_expression =
    {conditional_expression}
        conditional_expression |

    {assignment}
        assignment;

assignment =
    left_hand_side assignment_operator assignment_expression;

left_hand_side =
    {name}
        name |

    {field_access}
        field_access |

    {array_access}
        array_access;

assignment_operator =
    {assign}
        assign |

    {star_assign}
        star_assign |

    {div_assign}
        div_assign |

    {mod_assign}
        mod_assign |

    {plus_assign}
        plus_assign |

    {minus_assign}
        minus_assign |

    {shift_left_assign}
        shift_left_assign |

    {signed_shift_right_assign}
        signed_shift_right_assign |

    {unsigned_shift_right_assign}
        unsigned_shift_right_assign |

    {bit_and_assign}
        bit_and_assign |

    {bit_xor_assign}
        bit_xor_assign |

    {bit_or_assign}
        bit_or_assign;

expression =
    assignment_expression;

constant_expression =
    expression;

/********************************************************************
Litterals
********************************************************************/

boolean_literal =
    {true} true |
    {false} false;

null_literal =
    null;

integer_literal =
    {decimal} decimal_integer_literal |
    {hex} hex_integer_literal |
    {octal} octal_integer_literal;