Cover grammar application should be more discoverable
gibson042 opened this issue · comments
There are several parts of the specification that make use of cover grammars, but the details can be buried. The most obvious example is at Left-Hand-Side Expressions, where there is a CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] production but no indication of the supplemental CallMemberExpression[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] refining its CoverCallExpressionAndAsyncArrowHead that appears after a lot of intervening productions.
I can think of a few ways to address this, and they're non-exclusive:
- Promote "Supplemental Syntax" into actual subsections so they appear in the table of contents.
- Annotate productions to indicate that they are subject to refinement (may require changing grammarkdown).
- Give each cover grammar goal symbol a dedicated subsection that references its refinements, such that e.g. clicking on |CoverCallExpressionAndAsyncArrowHead| in the |CallExpression| productions goes to a section that explains its use in both |CallExpression| (with a link to |CallMemberExpression|) and |AsyncArrowFunction| (with a link to |AsyncArrowHead|).
Annotate productions to indicate that they are subject to refinement (may require changing grammarkdown).
The production could even say what the refinement is. E.g.:
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList \
[must cover a ParenthesizedExpression]
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList \
[must cover an ArrowFormalParameters]
which would give you the supplementary nonterminal to click on.
For the LeftHandSideExpression cases, the must-covers are conditional, so you could say something like:
AssignmentExpression : LeftHandSideExpression \
[may be required to cover an AssignmentPattern] `=` AssignmentExpression
(or briefer words/symbols to that effect), with the understanding that the condition under which it must cover is spelled out in prose nearby.
Conceivably, we could devise meta-syntax to express the condition in the annotation, but it's probably not worth the bother.
Yes, that's the sort of thing I had in mind and that specific approach is already possible with prose assertions:
CallExpression[Yield, Await] :
CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [> (must cover a |CallMemberExpression|)] #callcover
…
CallExpression[Yield, Await] :
CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] (must cover a CallMemberExpression)
…