I have just made some changes to the grammar, specifically relating to anonymous inner classes and array instantiations.
The problem is caused by the fact that conditionals in if and while statements do not have to have parentheses around them. This causes conflicts between the class member list/array initializer and the block of the if/while statement. Here are two examples:
class X { void foo() { if blah == new Runnable() {} // member list, or block for the if statement? {} // block for the if statement, or another block after it? } }
class X { void foo() { if blah == new X[0] {} // array initializer for "new X[0]", or block for the if statement {} // block for the if statement, or another block after it? } }
Since there is no way to tell which is meant in either of these cases, it is necessary to change the grammar and avoid this ambiguity.
For the first example, the syntax for anonymous inner classes has been changed to be slightly more readable, by adding a “class” keyword between the constructor parameters and the member list:
class X { void foo() { if blah == new Runnable() class {} // member list {} // block for the if statement } }
For the second example, the offending case has been disallowed. It is no longer possible to use an array initializer if the number of elements in the array is provided. Therefore the new syntax is:
class X { void foo() { if blah == new X[] {} // array initializer for "new X[]" {} // block for the if statement } }
This was a difficult decision, however I think it is better to disallow this relatively uncommon scenario in favour of removing the parentheses from if and while statements.