Package ca.mcgill.sable.gagnon.java;

/*******************************************************************
 * 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';
	default = 'default';
	if = 'if';
	private = 'private';
	throw = 'throw';
	boolean = 'boolean';
	do = 'do';
	implements = 'implements';
	protected = 'protected';   
	throws = 'throws';
	break = 'break';
	double = 'double';  
	import = 'import';
	public = 'public';
	transient = 'transient';
	byte = 'byte';
	else = 'else';  
	instanceof = 'instanceof';      
	return = 'return';
	try = 'try';
	case = 'case';   
	extends = 'extends'; 
	int = 'int';
	short = 'short';   
	void = 'void';
	catch = 'catch'; 
	final = 'final';
	interface = 'interface';
	static = 'static';
	volatile = 'volatile';
	char = 'char';
	finally = 'finally';
	long = 'long';
	super = 'super'; 
	while = 'while';
	class = 'class'; 
	float = 'float';
	native = 'native';
	switch = 'switch';
	const = 'const';
	for = 'for';   
	new = 'new';
	synchronized = 'synchronized';
	continue = 'continue';
	goto = 'goto';
	package = 'package';
	this = 'this';

	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 l_bracket r_bracket |

	{name}
		name l_bracket r_bracket |

	{array_type}
		array_type l_bracket r_bracket;

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

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

class_member_declaration =
	{field_declaration}
		field_declaration |

	{method_declaration}
		method_declaration;

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

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

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;

local_variable_declaration_statement =
	local_variable_declaration semicolon;

local_variable_declaration =
	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;

class_instance_creation_expression =
	new class_type l_parenthese argument_list? r_parenthese;

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

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;
