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

Changed java grammar to parse assertions



Hi,

I changed the java grammar. It should now be able to parse Java2 version 1.4
code containing assertions.

I'm no expert in formulating grammars so I'm unsure whether the changes I
made are good style. I would be quite happy if someone with a deeper insight
could comment on the rules I added. All changes are mark with [CHANGED]
tags.

Thanks,
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?;

    assert = 'assert';		/* [CHANGED] Leo: New keyword in JDK 1.4 (07/02/2003) */
    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 |

/* [CHANGED] Leo: New keyword in JDK 1.4 (07/02/2003) */
    {assert_statement_short}
        assert_statement_short |
        
    {assert_statement_long}
        assert_statement_long ;

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;

/* [CHANGED] Leo: New keyword in JDK 1.4 (07/02/2003) */    
assert_statement_short =
    assert expression semicolon;
    
assert_statement_long =
    assert [left]:expression colon [right]:expression semicolon;


/********************************************************************
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;