I found a few problems with the grammar specification for Java 7 and I thought it would be useful to document them here for further reference. I’ve also added the modified production rules that c4 uses.

  1. Expression2Rest

Expression2Rest:
  { InfixOp Expression3 }
  instanceof Type

This production doesn’t take into account cases like:

if (x == 1 && y instanceof String) { ... }

Modified version:

Expression2Rest:
  { InfixOp Expression3 | instanceof Type }
  1. Expression3

Expression3:
  PrefixOp Expression3
  '(' Type ')' Expression3
  '(' Expression ')' Expression3
  Primary { Selector } { PostfixOp }

The italicized parentheses should be ignored. We treat them as terminals.

  1. CatchType

CatchType:
  Identifier { '|' Identifier }

Modified version:

CatchType:
  QualifiedIdentifier { '|' QualifiedIdentifier }
  1. Creator

Creator:
  NonWildcardTypeArguments CreatedName ClassCreatorRest
  CreatedName ( ClassCreatorRest | ArrayCreatorRest )

We have to take into account primitive arrays and we add one more production rule to Creator. For example:

int[] a = new int[1];

Modified version:

Creator:
  NonWildcardTypeArguments CreatedName ClassCreatorRest
  CreatedName ( ClassCreatorRest | ArrayCreatorRest )
  BasicType ArrayCreatorRest
  1. NonWildcardTypeArguments

NonWildcardTypeArguments: < TypeList >

And TypeList expands to

TypeList: ReferenceType { , ReferenceType }

The problem is that it won’t take into account arrays. Examples:

< String[] >
< int[] >

Modified version:

NonWildcardTypeArguments: < TypeList2 >
TypeList2: Type { , Type }

The parser or the output code has to check for the invalid input of primitives that are not arrays.

  1. TypeArgument

TypeArgument:
  ReferenceType
  ? [ ( extends | super ) ReferenceType ]

Like NonWildcardTypeArguments, this production rule doesn’t take into account arrays, including basic type arrays.

Modified version:

TypeArgument:
  Type
  ? [ ( extends | super ) Type ]
  1. ForControl

ForControl:
  ForVarControl
  ForInit ; [Expression] ; [ForUpdate]

We have to make ForInit optional to handle this case

for (;;) { ... }

Modified version:

ForControl:
  ForVarControl
  [ForInit] ; [Expression] ; [ForUpdate]
  1. Expression

Expression: Expression1 [ AssignmentOperator Expression1 ]

This prevents multiple assignments like a = b = 1

Modified version:

Expression: Expression1 [ AssignmentOperator Expression ]
  1. IdentifierSuffix

IdentifierSuffix:
  '[' ( {'[]'} . class | Expression ) ']'

Modified version:

IdentifierSuffix:
  '[' ( ']' {'[]'} . class | Expression ']' )
  1. AnnotationTypeBody

Modified version:

AnnotationTypeBody:
  [AnnotationTypeElementDeclarations]