Hi Tagir,

On 1/13/2019 2:53 AM, Tagir Valeev wrote:
Ah, ok, we moved away slightly from the spec draft [1]. I was not
aware, because I haven't wrote parser by myself. The draft says:

SwitchLabeledRule:
   SwitchLabeledExpression
   SwitchLabeledBlock
   SwitchLabeledThrowStatement

SwitchLabeledExpression:
   SwitchLabel -> Expression ;
SwitchLabeledBlock:
   SwitchLabel -> Block ;
SwitchLabeledThrowStatement:
   SwitchLabel -> ThrowStatement ;

Instead we implement it like:

SwitchLabeledRule:
   SwitchLabel -> SwitchLabeledRuleStatement
SwitchLabeledRuleStatement:
   ExpressionStatement
   Block
   ThrowStatement

So we assume that the right part of SwitchLabeledRule is always a
statement and reused ExpressionStatement to express Expression plus
semicolon, because syntactically it looks the same.

That's an odd assumption, because SwitchLabeledRule appears in the SwitchBlock of a SwitchExpression, and we obviously intend any kind of expression to be allowed after the -> in a switch expression. That is, in a switch expression, what comes after the -> is not just an expression statement (x=y, ++x, --x, x++, x--, x.m(), new X()) but any expression (including this, X.class, x.f, x[i], x::m). Only in a switch statement do we restrict the kind of expression allowed after the -> but that's a semantic rule (14.11.2), not syntactic, in order to share the grammar between switch expressions and switch statements.

Strictly following a spec draft here looks even more ugly, because it
requires more object types in our code model and reduces the
flexibility when we need to perform code transformation. E.g. if we
want to wrap expression into block, currently we just need to replace
an ExpressionStatement with a Block not touching a SwitchLabel at
all. Had we mirrored the spec in our code model, we would need to
replace SwitchLabeledExpression with SwitchLabeledBlock which looks
more annoying.

Understood. The grammar is specified like it is in order to introduce the critical terms "switch labeled expression", "switch labeled block", and "switch labeled throw statement". Aligning production names with critical terms is longstanding JLS style.

Alex

Reply via email to