LARA

/* Joust: a Java lexer, parser, and pretty-printer written in OCaml
   Copyright (C) 2001  Eric C. Cooper <ecc@cmu.edu>
   Released under the GNU General Public License */
 
/* LALR(1) (ocamlyacc) grammar for Java
 
   Attempts to conform to:
 
   The Java Language Specification
   Second Edition
 
   James Gosling, Bill Joy, Guy Steele, Gilad Bracha */
 
/* adapted for use with Jahob by Viktor Kuncak, 2005-2008 */
 
%{
(** Joust parser, generated with ocamlyacc. *)
 
open List
open Syntax
%}
 
%token <Syntax.ident> IDENTIFIER
%token <string> LITERAL
%token <string> PRIMITIVE_TYPE
 
/*
 * 3.11 Separators
 */
%token LP		/* ( */
%token RP		/* ) */
%token LC		/* { */
%token RC		/* } */
%token LB		/* [ */
%token RB		/* ] */
%token SM		/* ; */
%token CM		/* , */
%token DOT		/* . */
 
/*
 * 3.12 Operators
 */
%token EQ		/* = */
%token GT		/* > */
%token LT		/* < */
%token NOT		/* ! */
%token COMPL		/* ~ */
%token COND		/* ? */
%token COLON		/* : */
%token EQ_EQ		/* == */
%token LE		/* <= */
%token GE		/* >= */
%token NOT_EQ		/* != */
%token AND_AND		/* && */
%token OR_OR		/* || */
%token INCR		/* ++ */
%token DECR		/* -- */
%token PLUS		/* + */
%token MINUS		/* - */
%token TIMES		/* * */
%token DIV		/* / */
%token AND		/* & */
%token OR		/* | */
%token XOR		/* ^ */
%token MOD		/* % */
%token LS		/* << */
%token SRS		/* >> */
%token URS		/* >>> */
%token <string> OPERATOR_EQ	/* += -= *= /= &= |= ^= %= <<= >>= >>>= */
%token <string> ANNOTATION /* vk: annotations for specification */
 
/*
 * 3.9 Keywords
 */
%token ABSTRACT BOOLEAN BREAK BYTE CASE CATCH CHAR CLASS CONST CONTINUE
%token DEFAULT DO DOUBLE ELSE EXTENDS FINAL FINALLY FLOAT FOR GOTO
%token IF IMPLEMENTS IMPORT INSTANCEOF INT INTERFACE LONG
%token NATIVE NEW PACKAGE PRIVATE PROTECTED PUBLIC RETURN
%token SHORT STATIC STRICTFP SUPER SWITCH SYNCHRONIZED
%token THIS THROW THROWS TRANSIENT TRY VOID VOLATILE WHILE
 
%token EOF
 
/*
 * The start production must begin with a lowercase letter,
 * because ocamlyacc defines the parsing function with that name.
 */
%start goal
%type <Syntax.compilation_unit> goal
 
%%
 
goal:
	CompilationUnit EOF  { add_comments $1 }
;
 
/* 3.8 */
 
Identifier:
	IDENTIFIER  { $1 }
;
 
/* 3.10 */
 
Literal:
	LITERAL  { $1 }
;
 
/* 4.1 */
 
Type:
	PrimitiveType  { $1 }
|	ReferenceType  { $1 }
;
 
/* 4.2 */
 
PrimitiveType:
	PRIMITIVE_TYPE  { named_type $1 }
;
 
/* 4.3 */
 
ReferenceType:
	ClassOrInterfaceType  { TypeName $1 }
|	ArrayType  { $1 }
;
 
ClassOrInterfaceType:
	Name  { rev $1 }
;
 
ClassType:
	Name  { rev $1 }
;
 
InterfaceType:
	Name  { rev $1 }
;
 
ArrayType:
	PrimitiveType LB RB  { ArrayType $1 }
|	Name LB RB  { ArrayType (TypeName (rev $1)) }
|	ArrayType LB RB  { ArrayType $1 }
;
 
/* 6.5 */
 
Name:
	Identifier  { [$1] }
|	Name DOT Identifier  { $3 :: $1 }
;
 
/* 7.3 */
 
CompilationUnit:
	PackageDeclarationOpt ImportDeclarationsOpt TypeDeclarationsOpt
	{ compilation_unit $1 $2 $3 }
;
 
ImportDeclarations:
	ImportDeclaration  { [$1] }
|	ImportDeclarations ImportDeclaration  { $2 :: $1 }
;
 
ImportDeclarationsOpt:
	/* empty */  { [] }
|	ImportDeclarations  { rev $1 }
;
 
TypeDeclarations:
	TypeDeclaration  { $1 }
|	TypeDeclarations TypeDeclaration  { $1 @ $2 }
;
 
TypeDeclarationsOpt:
	/* empty */  { [] }
|	TypeDeclarations  { $1 }
;
 
/* 7.4.1 */
 
PackageDeclaration:
	PACKAGE Name SM  { rev $2 }
;
 
PackageDeclarationOpt:
	/* empty */  { None }
|	PackageDeclaration  { Some $1 }
;
 
/* 7.5 */
 
ImportDeclaration:
	SingleTypeImportDeclaration  { $1 }
|	TypeImportOnDemandDeclaration  { $1 }
;
 
/* 7.5.1 */
 
SingleTypeImportDeclaration:
	IMPORT Name SM  { rev $2 }
;
 
/* 7.5.2 */
 
TypeImportOnDemandDeclaration:
	IMPORT Name DOT TIMES SM  { rev (star_ident :: $2) }
;
 
/* 7.6 */
 
TypeDeclaration:
	ClassDeclaration  { [Class $1] }
|	InterfaceDeclaration  { [Interface $1] }
|	SM  { [] }
;
 
/* 8.1 */
 
ClassDeclaration:
	ModifiersOpt CLASS Identifier SuperOpt InterfacesOpt ClassBody
		{ class_decl $1 $3 $4 $5 $6 }
;
 
/* 8.1.1 */
/* 8.3.1 */
/* 8.4.3 */
/* 8.8.3 */
/* 9.1.1 */
/* 9.3 */
/* 9.4 */
 
/*
 * To avoid shift/reduce conflicts, we accept all modifiers
 * in front of all declarations.  The ones not applicable to
 * a particular kind of declaration must be detected in semantic actions.
 */
 
Modifiers:
	Modifier  { $1 }
|	Modifiers Modifier  { $2 @ $1 }
;
 
ModifiersOpt:
	/* empty */  { [] }
|	Modifiers  { rev $1 }
;
 
Modifier:
	PUBLIC AnnotationModOpt { $2 @ [Public]}
|	PROTECTED  { [Protected] }
|	PRIVATE AnnotationModOpt { $2 @ [Private] }
|	ABSTRACT  { [Abstract] }
|	STATIC  { [Static] }
|	FINAL  { [Final] }
|	STRICTFP  { [StrictFP] }
|	TRANSIENT  { [Transient] }
|	VOLATILE  { [Volatile] }
|	SYNCHRONIZED  { [Synchronized] }
|	NATIVE  { [Native] }
;
 
AnnotationModOpt:
| /* empty */ { [] }
| ANNOTATION { [AnnotationModifier $1] }
;
 
/* 8.1.3 */
 
Super:
	EXTENDS ClassType  { $2 }
;
 
SuperOpt:
	/* empty */  { None }
|	Super  { Some $1 }
;
 
/* 8.1.4 */
 
Interfaces:
	IMPLEMENTS InterfaceTypeList  { rev $2 }
;
 
InterfacesOpt:
	/* empty */  { [] }
|	Interfaces  { $1 }
;
 
InterfaceTypeList:
	InterfaceType  { [$1] }
|	InterfaceTypeList CM InterfaceType  { $3 :: $1 }
;
 
/* 8.1.5 */
 
ClassBody:
	LC ClassBodyDeclarationsOpt RC  { $2 }
;
 
ClassBodyDeclarations:
	ClassBodyDeclaration  { $1 }
|	ClassBodyDeclarations ClassBodyDeclaration  { $1 @ $2 }
;
 
ClassBodyDeclarationsOpt:
	/* empty */  { [] }
|	ClassBodyDeclarations  { $1 }
;
 
ClassBodyDeclaration:
	ClassMemberDeclaration  { $1 }
|	InstanceInitializer  { [$1] }
|	StaticInitializer  { [$1] }
|	ConstructorDeclaration  { [$1] }
;
 
AnnotationDecl: ANNOTATION { AnnotationDecl $1 };
 
 
ClassMemberDeclaration:
	FieldDeclaration  { $1 }
|	MethodDeclaration  { [Method $1] }
|	ClassDeclaration  { [Class $1] }
|	InterfaceDeclaration  { [Interface $1] }
|       AnnotationDecl { [$1] }
|	SM  { [] }
;
 
/* 8.3 */
 
FieldDeclaration:
	ModifiersOpt Type VariableDeclarators SM  { field_decls $1 $2 (rev $3) }
;
 
VariableDeclarators:
	VariableDeclarator  { [$1] }
|	VariableDeclarators CM VariableDeclarator  { $3 :: $1 }
;
 
VariableDeclarator:
	VariableDeclaratorId  { $1, None }
|	VariableDeclaratorId EQ VariableInitializer  { $1, Some $3 }
;
 
VariableDeclaratorId:
	Identifier  { IdentDecl $1 }
|	VariableDeclaratorId LB RB  { ArrayDecl $1 }
;
 
VariableInitializer:
	Expression  { ExprInit $1 }
|	ArrayInitializer  { $1 }
;
 
/* 8.4 */
 
MethodDeclaration:
	MethodHeader MethodBody  { method_decl $1 $2 }
;
 
MethodHeader:
	ModifiersOpt Type MethodDeclarator ThrowsOpt AnnotationOpt
		{ method_header $1 $2 $3 $4 $5 }
|	ModifiersOpt VOID MethodDeclarator ThrowsOpt AnnotationOpt
		{ method_header $1 void_type $3 $4 $5 }
;
 
MethodDeclarator:
	Identifier LP FormalParameterListOpt RP  { IdentDecl $1, $3 }
|	MethodDeclarator LB RB  { ArrayDecl (fst $1), snd $1 }
;
 
/* 8.4.1 */
 
FormalParameterList:
	FormalParameter  { [$1] }
|	FormalParameterList CM FormalParameter  { $3 :: $1 }
;
 
FormalParameterListOpt:
	/* empty */  { [] }
|	FormalParameterList  { rev $1 }
;
 
FormalParameter:
	FinalOpt AnnotationModOpt Type VariableDeclaratorId  
                { formal_decl ($1 @ $2) $3 $4 }
;
 
FinalOpt:
	/* empty */  { [] }
|	FINAL  { [Final] }
;
 
/* 8.4.4 */
 
Throws:
	THROWS ClassTypeList  { rev $2 }
;
 
ThrowsOpt:
	/* empty */  { [] }
|	Throws  { $1 }
;
 
ClassTypeList:
	ClassType  { [$1] }
|	ClassTypeList CM ClassType  { $3 :: $1 }
;
 
/* 8.4.5 */
 
MethodBody:
	Block  { $1 }
|	SM  { Empty }
;
 
/* 8.6 */
 
InstanceInitializer:
	Block  { InstanceInit $1 }
;
 
/* 8.7 */
 
StaticInitializer:
	STATIC Block  { StaticInit $2 }
;
 
/* 8.8 */
 
ConstructorDeclaration:
	ModifiersOpt ConstructorDeclarator ThrowsOpt AnnotationOpt ConstructorBody
		{ constructor $1 $2 $3 $4 $5 }
;
 
ConstructorDeclarator:
	Identifier LP FormalParameterListOpt RP  { $1, $3 }
;
 
/* 8.8.5 */
 
ConstructorBody:
	LC BlockStatementsOpt RC  { Block $2 }
|	LC ExplicitConstructorInvocation BlockStatementsOpt RC
		{ Block ($2 :: $3) }
;
 
/* 8.8.5.1 */
 
ExplicitConstructorInvocation:
	THIS LP ArgumentListOpt RP SM
		{ constructor_invocation [this_ident] $3 }
|	SUPER LP ArgumentListOpt RP SM
		{ constructor_invocation [super_ident] $3 }
|	Primary DOT SUPER LP ArgumentListOpt RP SM
		{ expr_super_invocation $1 $5 }
	/*
	 * Not in 2nd edition Java Language Specification.
	 */
|	Name DOT SUPER LP ArgumentListOpt RP SM
		{ constructor_invocation (rev (super_ident :: $1)) $5 }
;
 
/* 9.1 */
 
InterfaceDeclaration:
	ModifiersOpt INTERFACE Identifier
		ExtendsInterfacesOpt InterfaceBody
			{ interface_decl $1 $3 $4 $5 }
;
 
/* 9.1.2 */
 
ExtendsInterfaces:
	EXTENDS InterfaceType  { [$2] }
|	ExtendsInterfaces CM InterfaceType  { $3 :: $1 }
;
 
ExtendsInterfacesOpt:
	/* empty */  { [] }
|	ExtendsInterfaces  { rev $1 }
;
 
/* 9.1.3 */
 
InterfaceBody:
	LC InterfaceAnnotations InterfaceMemberDeclarationsOpt RC  { $2 @ $3 }
;
 
InterfaceAnnotations:
  /* empty */                     { [] }
| ANNOTATION InterfaceAnnotations { AnnotationDecl $1 :: $2 }
;
 
InterfaceMemberDeclarations:
	InterfaceMemberDeclaration  { $1 }
|	InterfaceMemberDeclarations InterfaceMemberDeclaration  { $1 @ $2 }
;
 
InterfaceMemberDeclarationsOpt:
	/* empty */  { [] }
|	InterfaceMemberDeclarations  { $1 }
;
 
InterfaceMemberDeclaration:
	ConstantDeclaration  { $1 }
|	AbstractMethodDeclaration  { [Method $1] }
|	ClassDeclaration  { [Class $1] }
|	InterfaceDeclaration  { [Interface $1] }
|	SM  { [] }
;
 
/* 9.3 */
 
/*
 * Note: semicolon is missing in 2nd edition Java Language Specification.
 */
 
ConstantDeclaration:
	ModifiersOpt Type VariableDeclarators SM
		{ field_decls $1 $2 (rev $3) }
;
 
/* 9.4 */
 
AnnotationOpt:
|  /* empty */ { None }
| ANNOTATION { Some $1 }
 
AbstractMethodDeclaration:
	ModifiersOpt Type MethodDeclarator ThrowsOpt AnnotationOpt SM
		{ method_header $1 $2 $3 $4 $5 }
|	ModifiersOpt VOID MethodDeclarator ThrowsOpt AnnotationOpt SM
		{ method_header $1 void_type $3 $4 $5 }
;
 
/* 10.6 */
 
ArrayInitializer:
	LC CommaOpt RC  { ArrayInit [] }
|	LC VariableInitializers CommaOpt RC  { ArrayInit (rev $2) }
;
 
VariableInitializers:
	VariableInitializer  { [$1] }
|	VariableInitializers CM VariableInitializer  { $3 :: $1 }
;
 
CommaOpt:
	/* empty */  { () }
|	CM  { () }
;
 
/* 14.2 */
 
Block:
	LC BlockStatementsOpt RC  { Block $2 }
;
 
BlockStatements:
	BlockStatement  { $1 }
|	BlockStatements BlockStatement  { $1 @ $2 }
;
 
BlockStatementsOpt:
	/* empty */  { [] }
|	BlockStatements  { $1 }
;
 
BlockStatement:
	LocalVariableDeclarationStatement  { $1 }
|	ClassDeclaration  { [LocalClass $1] }
|	Statement  { [$1] }
;
 
/* 14.4 */
 
LocalVariableDeclarationStatement:
	LocalVariableDeclaration SM  { $1 }
;
 
LocalVariableDeclaration:
	Type VariableDeclarators  { var_decls [] $1 (rev $2) }
|	FINAL Type VariableDeclarators  { var_decls [Final] $2 (rev $3) }
;
 
/* 14.5 */
 
Statement:
	StatementWithoutTrailingSubstatement  { $1 }
|	LabeledStatement  { $1 }
|	IfThenStatement  { $1 }
|	IfThenElseStatement  { $1 }
|	WhileStatement  { $1 }
|	ForStatement  { $1 }
|       AnnotationStatement { $1 }
;
 
StatementNoShortIf:
	StatementWithoutTrailingSubstatement  { $1 }
|	LabeledStatementNoShortIf  { $1 }
|	IfThenElseStatementNoShortIf  { $1 }
|	WhileStatementNoShortIf  { $1 }
|	ForStatementNoShortIf  { $1 }
;
 
StatementWithoutTrailingSubstatement:
	Block  { $1 }
|	EmptyStatement  { $1 }
|	ExpressionStatement  { $1 }
|	SwitchStatement  { $1 }
|	DoStatement  { $1 }
|	BreakStatement  { $1 }
|	ContinueStatement  { $1 }
|	ReturnStatement  { $1 }
|	SynchronizedStatement  { $1 }
|	ThrowStatement  { $1 }
|	TryStatement  { $1 }
;
 
/* 14.6 */
 
EmptyStatement:
	SM  { Empty }
;
 
/* 14.7 */
 
LabeledStatement:
	Identifier COLON Statement  { Label ($1, $3) }
;
 
LabeledStatementNoShortIf:
	Identifier COLON StatementNoShortIf  { Label ($1, $3) }
;
 
/* 14.8 */
 
ExpressionStatement:
	StatementExpression SM  { Expr $1 }
;
 
/* vkuncak */
 
AnnotationStatement:
  ANNOTATION {AnnotationStmt $1};
 
StatementExpression:
	Assignment  { $1 }
|	PreIncrementExpression  { $1 }
|	PreDecrementExpression  { $1 }
|	PostIncrementExpression  { $1 }
|	PostDecrementExpression  { $1 }
|	MethodInvocation  { $1 }
|	ClassInstanceCreationExpression  { $1 }
;
 
/* 14.9 */
 
IfThenStatement:
	IF LP Expression RP Statement
		{ If ($3, $5, None) }
;
 
IfThenElseStatement:
	IF LP Expression RP StatementNoShortIf ELSE Statement
		{ If ($3, $5, Some $7) }
;
 
IfThenElseStatementNoShortIf:
	IF LP Expression RP StatementNoShortIf ELSE StatementNoShortIf
		{ If ($3, $5, Some $7) }
;
 
/* 14.10 */
 
SwitchStatement:
	SWITCH LP Expression RP SwitchBlock
		{ Switch ($3, $5) }
;
 
SwitchBlock:
	LC RC  { [] }
|	LC SwitchLabels RC  { [$2, []] }
|	LC SwitchBlockStatementGroups RC  { rev $2 }
|	LC SwitchBlockStatementGroups SwitchLabels RC
		{ rev ((rev $3, []) :: $2) }
;
 
SwitchBlockStatementGroups:
	SwitchBlockStatementGroup  { [$1] }
|	SwitchBlockStatementGroups SwitchBlockStatementGroup  { $2 :: $1 }
;
 
SwitchBlockStatementGroup:
	SwitchLabels BlockStatements  { rev $1, $2 }
;
 
SwitchLabels:
	SwitchLabel  { [$1] }
|	SwitchLabels SwitchLabel  { $2 :: $1 }
;
 
SwitchLabel:
	CASE ConstantExpression COLON  { Case $2 }
|	DEFAULT COLON  { Default }
;
 
/* 14.11 */
 
WhileStatement:
	WHILE AnnotationOpt LP Expression RP Statement
		{ While ($2, $4, $6) }
;
 
WhileStatementNoShortIf:
	WHILE AnnotationOpt LP Expression RP StatementNoShortIf
		{ While ($2, $4, $6) }
;
 
/* 14.12 */
 
DoStatement:
	DO Statement WHILE LP Expression RP SM
		{ Do ($2, $5) }
;
 
/* 14.13 */
 
ForStatement:
	FOR LP ForInitOpt SM ExpressionOpt SM ForUpdateOpt RP
		Statement
			{ For ($3, $5, $7, $9) }
;
 
ForStatementNoShortIf:
	FOR LP ForInitOpt SM ExpressionOpt SM ForUpdateOpt RP
		StatementNoShortIf
			{ For ($3, $5, $7, $9) }
;
 
ForInit:
	StatementExpressionList  { rev $1 }
|	LocalVariableDeclaration  { $1 }
;
 
ForInitOpt:
	/* empty */  { [] }
|	ForInit  { $1 }
;
 
ExpressionOpt:
	/* empty */  { None }
|	Expression  { Some $1 }
;
 
ForUpdate:
	StatementExpressionList  { rev $1 }
;
 
ForUpdateOpt:
	/* empty */  { [] }
|	ForUpdate  { $1 }
;
 
StatementExpressionList:
	StatementExpression  { [Expr $1] }
|	StatementExpressionList CM StatementExpression  { Expr $3 :: $1 }
;
 
/* 14.14 */
 
BreakStatement:
	BREAK IdentifierOpt SM  { Break $2 }
;
 
IdentifierOpt:
	/* empty */  { None }
|	Identifier  { Some $1 }
;
 
/* 14.15 */
 
ContinueStatement:
	CONTINUE IdentifierOpt SM  { Continue $2 }
;
 
/* 14.16 */
 
ReturnStatement:
	RETURN ExpressionOpt SM  { Return $2 }
;
 
/* 14.17 */
 
ThrowStatement:
	THROW Expression SM  { Throw $2 }
;
 
/* 14.18 */
 
SynchronizedStatement:
	SYNCHRONIZED LP Expression RP Block  { Sync ($3, $5) }
;
 
/* 14.19 */
 
TryStatement:
	TRY Block Catches  { Try ($2, rev $3, None) }
|	TRY Block CatchesOpt Finally  { Try ($2, $3, Some $4) }
;
 
Catches:
	CatchClause  { [$1] }
|	Catches CatchClause  { $2 :: $1 }
;
 
CatchesOpt:
	/* empty */  { [] }
|	Catches  { rev $1 }
;
 
CatchClause:
	CATCH LP FormalParameter RP Block  { $3, $5 }
	/*
	 * Not in 2nd edition Java Language Specification.
	 */
|	CATCH LP FormalParameter RP EmptyStatement  { $3, $5 }
;
 
Finally:
	FINALLY Block  { $2 }
;
 
/* 15.8 */
 
Primary:
	PrimaryNoNewArray  { $1 }
|	ArrayCreationExpression  { $1 }
;
 
PrimaryNoNewArray:
	Literal  { Literal $1 }
|	ClassLiteral  { $1 }
|	THIS  { Name [this_ident] }
|	Name DOT THIS  { Name (rev (this_ident :: $1)) }
|	LP Expression RP  { $2 }
|	ClassInstanceCreationExpression  { $1 }
|	FieldAccess  { $1 }
|	MethodInvocation  { $1 }
|	ArrayAccess  { $1 }
;
 
/* 15.8.2 */
 
ClassLiteral:
	PrimitiveType DOT CLASS  { ClassLiteral $1 }
|	Name DOT CLASS  { ClassLiteral (TypeName (rev $1)) }
|	ArrayType DOT CLASS  { ClassLiteral $1 }
|	VOID DOT CLASS  { ClassLiteral void_type }
;
 
/* 15.9 */
 
/* 	NEW ClassOrInterfaceType LP ArgumentListOpt RP ClassBodyOpt
		{ NewClass (TypeName $2, $4, $6, None) } 
*/
 
ClassInstanceCreationExpression:
| 	NEW ClassOrInterfaceType LP ArgumentListOpt RP ClassBodyOpt
		{ NewClass (TypeName $2, $4, $6, None) } 
|	NEW ANNOTATION ClassOrInterfaceType LP ArgumentListOpt RP ClassBodyOpt 
		{ NewClass (TypeName $3, $5, $7, Some $2) } 
|	Primary DOT NEW Identifier LP ArgumentListOpt RP ClassBodyOpt
		{ NewQualifiedClass ($1, $4, $6, $8) }
	/*
	 * Not in 2nd edition Java Language Specification.
	 */
|	Name DOT NEW Identifier LP ArgumentListOpt RP ClassBodyOpt
		{ NewQualifiedClass (Name (rev $1), $4, $6, $8) }
;
 
ArgumentList:
	Expression  { [$1] }
|	ArgumentList CM Expression  { $3 :: $1 }
;
 
ArgumentListOpt:
	/* empty */  { [] }
|	ArgumentList  { rev $1 }
;
 
ClassBodyOpt:
	/* empty */  { None }
|	ClassBody  { Some $1 }
;
 
/* 15.10 */
 
ArrayCreationExpression:
	NEW PrimitiveType DimExprs DimsOpt
		{ NewArray ($2, rev $3, $4, None, None) }
|	NEW PrimitiveType Dims ArrayInitializer
		{ NewArray ($2, [], $3, Some $4, None) }
|	NEW Name DimExprs DimsOpt
		{ NewArray (TypeName (rev $2), rev $3, $4, None, None) }
|	NEW Name Dims ArrayInitializer
		{ NewArray (TypeName (rev $2), [], $3, Some $4, None) }
 
|	NEW ANNOTATION PrimitiveType DimExprs DimsOpt
		{ NewArray ($3, rev $4, $5, None, Some $2) }
|	NEW ANNOTATION PrimitiveType Dims ArrayInitializer
		{ NewArray ($3, [], $4, Some $5, Some $2) }
|	NEW ANNOTATION Name DimExprs DimsOpt
		{ NewArray (TypeName (rev $3), rev $4, $5, None, Some $2) }
|	NEW ANNOTATION Name Dims ArrayInitializer
		{ NewArray (TypeName (rev $3), [], $4, Some $5, Some $2) }
;
 
DimExprs:
	DimExpr  { [$1] }
|	DimExprs DimExpr  { $2 :: $1 }
;
 
DimExpr:
	LB Expression RB  { $2 }
;
 
Dims:
	LB RB  { 1 }
|	Dims LB RB  { $1 + 1 }
;
 
DimsOpt:
	/* empty */  { 0 }
|	Dims  { $1 }
;
 
/* 15.11 */
 
FieldAccess:
	Primary DOT Identifier
		{ Dot ($1, $3) }
|	SUPER DOT Identifier
		{ Name [super_ident; $3] }
|	Name DOT SUPER DOT Identifier
		{ Name (rev ($5 :: super_ident :: $1)) }
;
 
/* 15.12 */
 
MethodInvocation:
	Name LP ArgumentListOpt RP  { Call (Name (rev $1), $3) }
|	Primary DOT Identifier LP ArgumentListOpt RP
		{ Call (Dot ($1, $3), $5) }
|	SUPER DOT Identifier LP ArgumentListOpt RP
		{ Call (Name [super_ident; $3], $5) }
|	Name DOT SUPER DOT Identifier LP ArgumentListOpt RP
		{ Call (Name (rev ($5 :: super_ident :: $1)), $7) }
;
 
/* 15.13 */
 
ArrayAccess:
	Name LB Expression RB  { ArrayAccess (Name (rev $1), $3) }
|	PrimaryNoNewArray LB Expression RB  { ArrayAccess ($1, $3) }
;
 
/* 15.14 */
 
PostfixExpression:
	Primary  { $1 }
|	Name  { Name (rev $1) }
|	PostIncrementExpression  { $1 }
|	PostDecrementExpression  { $1 }
;
 
/* 15.14.1 */
 
PostIncrementExpression:
	PostfixExpression INCR  { Postfix ($1, "++") }
;
 
/* 15.14.2 */
 
PostDecrementExpression:
	PostfixExpression DECR  { Postfix ($1, "--") }
;
 
/* 15.15 */
 
UnaryExpression:
	PreIncrementExpression  { $1 }
|	PreDecrementExpression  { $1 }
|	PLUS UnaryExpression  { Prefix ("+", $2) }
|	MINUS UnaryExpression  { Prefix ("-", $2) }
|	UnaryExpressionNotPlusMinus  { $1 }
;
 
PreIncrementExpression:
	INCR UnaryExpression  { Prefix ("++", $2) }
;
 
PreDecrementExpression:
	DECR UnaryExpression  { Prefix ("--", $2) }
;
 
UnaryExpressionNotPlusMinus:
	PostfixExpression  { $1 }
|	COMPL UnaryExpression  { Prefix ("~", $2) }
|	NOT UnaryExpression  { Prefix ("!", $2) }
|	CastExpression  { $1 }
;
 
/* 15.16 */
 
/* Original rule:
 
CastExpression:
	LP PrimitiveType DimsOpt RP UnaryExpression
|	LP ReferenceType RP UnaryExpressionNotPlusMinus
;
 
*/
 
/*
 * Modified (overly liberal) rule for LALR(1) grammar.
 * Semantic action must ensure that '( Expression )' is really '( Name )'
 */
 
CastExpression:
	LP PrimitiveType RP UnaryExpression  { Cast ($2, $4) }
|	LP Expression RP UnaryExpressionNotPlusMinus
		{ Cast (type_name $2, $4) }
|	LP ArrayType RP UnaryExpressionNotPlusMinus  { Cast ($2, $4) }
;
 
/* 15.17 */
 
MultiplicativeExpression:
	UnaryExpression  { $1 }
|	MultiplicativeExpression TIMES UnaryExpression
		{ Infix ($1, "*", $3) }
|	MultiplicativeExpression DIV UnaryExpression
		{ Infix ($1, "/", $3) }
|	MultiplicativeExpression MOD UnaryExpression
		{ Infix ($1, "%", $3) }
;
 
/* 15.18 */
 
AdditiveExpression:
	MultiplicativeExpression  { $1 }
|	AdditiveExpression PLUS MultiplicativeExpression
		{ Infix ($1, "+", $3) }
|	AdditiveExpression MINUS MultiplicativeExpression
		{ Infix ($1, "-", $3) }
;
 
/* 15.19 */
 
ShiftExpression:
	AdditiveExpression  { $1 }
|	ShiftExpression LS AdditiveExpression  { Infix ($1, "<<", $3) }
|	ShiftExpression SRS AdditiveExpression  { Infix ($1, ">>", $3) }
|	ShiftExpression URS AdditiveExpression  { Infix ($1, ">>>", $3) }
;
 
/* 15.20 */
 
RelationalExpression:
	ShiftExpression  { $1 }
|	RelationalExpression LT ShiftExpression  { Infix ($1, "<", $3) }
|	RelationalExpression GT ShiftExpression  { Infix ($1, ">", $3) }
|	RelationalExpression LE ShiftExpression  { Infix ($1, "<=", $3) }
|	RelationalExpression GE ShiftExpression  { Infix ($1, ">=", $3) }
|	RelationalExpression INSTANCEOF ReferenceType  { InstanceOf ($1, $3) }
;
 
/* 15.21 */
 
EqualityExpression:
	RelationalExpression  { $1 }
|	EqualityExpression EQ_EQ RelationalExpression
		{ Infix ($1, "==", $3) }
|	EqualityExpression NOT_EQ RelationalExpression
		{ Infix ($1, "!=", $3) }
;
 
/* 15.22 */
 
AndExpression:
	EqualityExpression  { $1 }
|	AndExpression AND EqualityExpression  { Infix ($1, "&", $3) }
;
 
ExclusiveOrExpression:
	AndExpression  { $1 }
|	ExclusiveOrExpression XOR AndExpression  { Infix ($1, "^", $3) }
;
 
InclusiveOrExpression:
	ExclusiveOrExpression  { $1 }
|	InclusiveOrExpression OR ExclusiveOrExpression  { Infix ($1, "|", $3) }
;
 
/* 15.23 */
 
ConditionalAndExpression:
	InclusiveOrExpression  { $1 }
|	ConditionalAndExpression AND_AND InclusiveOrExpression
		{ Infix ($1, "&&", $3) }
;
 
/* 15.24 */
 
ConditionalOrExpression:
	ConditionalAndExpression  { $1 }
|	ConditionalOrExpression OR_OR ConditionalAndExpression
		{ Infix ($1, "||", $3) }
;
 
/* 15.25 */
 
ConditionalExpression:
	ConditionalOrExpression  { $1 }
|	ConditionalOrExpression COND Expression COLON ConditionalExpression
		{ Conditional ($1, $3, $5) }
;
 
/* 15.26 */
 
AssignmentExpression:
	ConditionalExpression  { $1 }
|	Assignment  { $1 }
;
 
Assignment:
	LeftHandSide AssignmentOperator AssignmentExpression
		{ Assignment ($1, $2, $3) }
;
 
LeftHandSide:
	Name  { Name (rev $1) }
|	FieldAccess  { $1 }
|	ArrayAccess  { $1 }
;
 
AssignmentOperator:
	EQ  { "=" }
|	OPERATOR_EQ  { $1 }
;
 
/* 15.27 */
 
Expression:
	AssignmentExpression  { $1 }
;
 
/* 15.28 */
 
ConstantExpression:
	Expression  { $1 }
;