I’ve just started looking into parameterised productions and I’m wondering if I’m expanding/interpreting them correctly.
Here is the first production for FunctionDeclaration:
FD_[Yield, Await, Default] :
function BI_[?Yield, ?Await] ( FP_[~Yield, ~Await] ) { FB_[~Yield, ~Await] }
(NOTE: I've abbreviated the non-terminals.)
I expanded this as follows:
FD :
function BI (FP) { FB }
FD_Yield :
function BI_Yield (FP) { FB }
FD_Await :
function BI_Await (FP) { FB }
FD_Yield_Await :
function BI_Yield_Await (FP) { FB }
Questions
- Am I reading/expanding the productions correctly?
I read FunctionBody[~Yield, ~Await]
as meaning "neither 'yield' nor 'await' are reserved words for instances of this FunctionBody".
-
Why were the
[~Yield]
and[~Await]
prefixes removed from the RHS ofBindingIdentifier
?
They were there in 2017, but have been omitted since. Initially, I thought that it was due to the newer specs using Early Errors to restrict the use of "await" and "yield" instead (see error #4 and #5), but the 2017 spec had these errors too.
- How might we arrive at a production like
FD_Yield : function BI_Yield (FP) { FB }
during a parse?
My understanding is that the _Yield
suffix gets appended to the FunctionDeclaration
non-terminal if it appears on the RHS of a GeneratorDeclaration
(because GeneratorBody : FunctionBody_Yield ==>+ FunctionDeclaration_Yield
).
So the FunctionDeclaration_Yield
production is applied when we encounter a function declaration inside a generator. The BindingIndentifier_Yield
non-terminal on the RHS ensures that it is a syntax error if this function declaration is named "yield" (see early error for BindingIdentifier_Yield
):
function* gen() {
function yield() {};
} // SyntaxError
(As an aside, it is legal for that function to contain a function named "yield" since the FunctionBody
non-terminal on the RHS does not inherit the _Yield
suffix, so the below is allowed:)
function* gen() {
function foo() {
function yield() {};
}
} // no error