Yield as contextual keyword

Alex Buckley alex.buckley at oracle.com
Fri May 24 21:44:05 UTC 2019

On 5/24/2019 1:19 PM, Tagir Valeev wrote:
> Hello! Answering myself
>>> The first token in a YieldStatement production is always preceded
>>> by one of these separator tokens: ;, {, }, ), or ->.
>> Seems I'm missing something. Could you please illustrate in which
>> case YieldStatement could be preceded by ')'?
> Nevermind. if(foo) yield bar; is a good example. Other my points
> still apply.
>> Also what about '->'? In lambda '->' is followed by an expression
>> or block, but not a statement. In switch '->' is followed by block,
>> throw or expression plus semicolon. Also could YieldStatement be
>> preceded by ':' in old switch format? E.g.
>> System.out.println(switch(0) { default: yield 1; }); // seems
>> legit

You're right that `->` should not appear in the list. Any `yield` which 
follows `->` is necessarily the start of an expression, so `yield` 
should be tokenized as an identifier there.

`:` is tricky. On the one hand, the space after `:` is sometimes 
desirous of an statement, so tokenize `yield` as a keyword:

- `default : yield (1);` in a switch expression (also `case ... :`)

- `L1 : yield (1);` in a switch expression (labeled statements are 
legitimate in a switch-labeled block! If there was no label, we would 
quickly say that this `yield` is a YieldStatement not an 
ExpressionStatement, and that if you want an ExpressionStatement which 
invokes a method, then qualify the invocation.)

On the other hand, the space after `:` is sometimes desirous of an 
expression, so tokenize `yield` as a identifier: (and it might be the 
name of a local variable, so no way to qualify)

- `for (String s : yield . f) ...`

- `m(a ? yield . f : yield . g)`


More information about the amber-spec-observers mailing list