Re: [Java Spec Report] JSR 201 enhanced-for comments

Eric Blake <[email protected]> Thu, 19 Feb 2004 06:24:38 -0700
Newsgroups gmane.comp.java.spec-report
Message-ID <[email protected]>
Found the solution.  However, jikes uses its own parser generator (derived 
from IBM's lpg) rather than yacc, so you will have to translate this to yacc 
yourself if you want to see yacc's reaction.

Originally, the JLS asks for:
BlockStatement:
   LocalVariableDeclarationStatement
   Statement

LocalVariableDeclarationStatement:
   LocalVariableDeclaration ';'
LocalVariableDeclaration:
   'final'opt Type VariableDeclaration
Type:
   ReferenceType
ReferenceType:
   ClassOrInterfaceType
ClassOrInterfaceType:
   ClassType
ClassType:
   TypeName                    // or just Name

Statement:
   ExpressionStatement
ExpressionStatement:
   StatementExpression ';'
StatementExpression:
   PostIncrementExpression
PostIncrementExpression:
   PostfixExpression '++'
PostfixExpression:
   ExpressionName              // or just Name

Therefore, the parser is stuck with a reduce/reduce, deciding whether 'a[' 
starts ClassType or PostfixExpression (ie. 'a[]b;' vs. 'a[1]++;').

So, in my grammar, I had previously inline expanded Type in 
LocalVariableDeclaration, like so.
LocalVariableDeclaration:
   PrimitiveType Dimsopt VariableDeclarators
   Name VariableDeclarators
   Name Dims VariableDeclarators
   Modifiers Type VariableDeclarators
// here, using Modifiers instead of 'final', to allow for JSR 175.

This meant that the existing definition of FormalParameter now causes a 
shift/reduce conflict (ie. does 'for(a b' start 'for(a b:c)' or 'for(a b;;)').
FormalParameter:
   'final'opt Type VariableDeclaratorId

So the solution - simply inline expand FormalParameter in the same manner as 
LocalVariableDeclaration.
FormalParameter:
   PrimitiveType Dimsopt VariableDeclaratorId
   Name VariableDeclaratorId
   Name Dims VariableDeclaratorId
   Modifiers Type VariableDeclarators // again, Modifiers instead of 'final'

You also need the following tweaks to support JSR 14:
LocalVariableDeclaration:
   ... // the four above, plus
   ClassOrInterface TypeArguments Dimsopt VariableDeclarators
FormalParameter:
   ... // the four above, plus
   ClassOrInterface TypeArguments Dimsopt VariableDeclaratorId
ClassOrInterface:
   Name
   ClassOrInterface TypeArguments '.' Name

The LALR(1) grammar that jikes uses is always available online, in the latest 
CVS revisions of the HEAD and generics-branch branches for java.g (for now, 
the branch choice determines whether partial JSR 14 support is in the grammar, 
although it has not been updated to support type parameter wildcards):
http://www-124.ibm.com/developerworks/oss/cvs/jikes/jikes/src/java.g
Where I differ from the JLS, I have documented the change.


Neal Gafter wrote:
> Eric is certainly correct with regards to the short if grammar changes.  
> Those changes are needed to make the language unambiguous in dealing 
> with the dangling else problem for constructs such as
> 
>     if (expr) for (Type v : expr) if (expr) stmt1; else stmt2;
> 
> About the FormalParameter issue, it isn't clear to me to see why there 
> is a problem.  If you have a choice between FormalParameter and 
> LocalVariableDeclaration, it can only be due to being inside a for 
> loop.   A single-character lookahead should resolve the ambiguity: if 
> you see a ',' or '=' then it is a VariableDeclarator; if you see a ':' 
> it is a FormalParameter.  I'd like to see the itemset of the problem 
> LALR(1) parser state to better understand the issue; can you make a yacc 
> grammar available to me?  There was a genuine language ambiguity when we 
> changed the assert statement, but I believe there is no underlying 
> language or grammar ambiguity in the for-each loop.
> 
> I suggest you try the following grammar factoring.  Transform a copy of 
> the grammar rule LocalVariableDeclaration by inlining 
> VariableDeclarators, changing it from
> 
>     LocalVariableDeclaration:
>         finalopt Type VariableDeclarators
> 
> to:
> 
>     ForLocalVariableDeclaration:
>         finalopt Type VariableDeclarator
>         finalopt Type VariableDeclarators, VariableDeclarator
> 
> and then inlining VariableDeclarator in the first line resulting in
> 
>     ForLocalVariableDeclaration:
>         finalopt Type VariableDeclaratorId
>         finalopt Type VariableDeclaratorId = VariableInitializer
>         finalopt Type VariableDeclarators, VariableDeclarator
> 
> and finally, substituting the nonterminal FormalParameter for the first 
> of these:
> 
>     ForLocalVariableDeclaration:
>         FormalParameter
>         finalopt Type VariableDeclaratorId = VariableInitializer
>         finalopt Type VariableDeclarators, VariableDeclarator
> 
> [Warning: I haven't tested these musings with a parser generator.]
> 
> Regards,
> Neal
> 
> 
> Eric Blake wrote:
> 
>> In trying to implement this, I found a HUGE problem - the proposed 
>> grammar is not LALR(1).  Remember how JSR 41 (assert statement) 
>> changed its grammar long after the public draft closed, because the 
>> proposed grammar was not LALR(1)?
>>
>>
>>>  /EnhancedForStatement:/
>>>       for ( /FormalParameter/ : /Expression/ )
>>>           /Statement/
>>
>>
>>
>> When the parser sees "for (@A final int i", your proposal makes it 
>> impossible to decide whether you are starting a FormalParameter or 
>> LocalVariableDeclaration (as part of ForInitopt).  You are going to 
>> have to factor this statement out; I haven't yet had time to tackle 
>> the problem, but if I can find a factorization that works, I will post 
>> it.
>>
>> You also need to add:
>> EnhancedForStatementNoShortIf:
>>    'for' '(' <whatever factorization works> ':' Expression ')'
>>        StatementNoShortIf
>>
>> And you should explicitly list:
>> Statement:
>>    <all existing productions>
>>    EnhancedForStatement
>> StatementNoShortIf:
>>    <all existing productions>
>>    EnhancedForStatementNoShortIf:
>>
> 
> 
> 

-- 
Someday, I might put a cute statement here.

Eric Blake             [email protected]



------------------------ Yahoo! Groups Sponsor ---------------------~-->
Buy Ink Cartridges or Refill Kits for your HP, Epson, Canon or Lexmark
Printer at MyInks.com. Free s/h on orders $50 or more to the US & Canada.
http://www.c1tracking.com/l.asp?cid=5511
http://us.click.yahoo.com/mOAaAA/3exGAA/qnsNAA/5cFolB/TM
---------------------------------------------------------------------~->

To unsubscribe from this mailing list, send an email to:
[email protected]
 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
     http://groups.yahoo.com/group/java-spec-report/

<*> To unsubscribe from this group, send an email to:
     [email protected]

<*> Your use of Yahoo! Groups is subject to:
     http://docs.yahoo.com/info/terms/