Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grammar ambiguities #275

Open
waldemarhorwat opened this issue Jul 12, 2022 · 5 comments
Open

Grammar ambiguities #275

waldemarhorwat opened this issue Jul 12, 2022 · 5 comments

Comments

@waldemarhorwat
Copy link

waldemarhorwat commented Jul 12, 2022

At the moment the grammar has a number of ambiguities.

MatchExpression

As written, the MatchExpression production is ambiguous with the existing CoverCallExpressionAndAsyncArrowHead production. The problem arises when parsing the comma in match(a,. There are two possible ways to parse it to proceed further: the comma in ArgumentList or the comma in Expression. Disambiguating between them would require infinite lookahead which is impossible in general due to lexing being dependent on parsing.

To fix it, use CoverCallExpressionAndAsyncArrowHead inside MatchExpression similar to how async arrow functions do it.

MatchPattern precedence

There are also several ambiguities within MatchPattern. Some examples of problematic MatchPatterns:

x or y and z parses as both (x or y) and z as well as x or (y and z)

${e} with x and y parses as both (${e} with x) and y as well as ${e} with (x and y)

To fix these, use techniques analogous to those in ECMAScript expressions: have separate MatchPattern nonterminals for each level of precedence.

MatchClauses

MatchClauses produce ambiguities due to not being separated by anything like a semicolon. In fact, semicolons are forbidden there, which seems unusual in something that looks like a series of statements in a block.

This already causes parsing ambiguities and will cause significant problems as we extend the expression syntax in the future:

match (e) {if (a): yield when (

Is first MatchClause's expression yield followed by a when MatchClause, or is it a yield expression that yields the result of calling a function named when?

To fix this, use semicolons between MatchClauses.

@ljharb
Copy link
Member

ljharb commented Jul 12, 2022

Re MatchExpression, thanks, we'll take a look :-)

Regarding MatchPattern precedence; our current plan is to make those an early error, like in exponentiation, and to require the parentheses. What technique would you suggest for that?

Re MatchClauses, i'm a bit confused. Whether or not it's likely there will be consensus to ever allow if to be an expression, I agree it shouldn't be boxed out. However, since it's starting with an if, that should only ever be a match guard, and the yield wouldn't be valid - because if (a): yield would be required (note the colon) to make it the RHS of a match clause.

@waldemarhorwat
Copy link
Author

I mentioned above how to fix the precedence ambiguities above. No need for early errors. Just create a hierarchy of MatchClause nonterminals, just like we have for expression nonterminals: MultiplicativeExpression, AdditiveExpression, etc.

Thanks for finding the typo in the third example. Yes, the problematic example should be match (e) {if (a): yield when (…. The problem remains.

@ljharb
Copy link
Member

ljharb commented Jul 12, 2022

ah right, because of the yield when.

I agree, requiring semicolons between match clauses seems like the best approach.

@Jack-Works
Copy link
Member

How can I "require" semicolons? Does that mean there is something to do with ASI?

@ljharb
Copy link
Member

ljharb commented Jul 13, 2022

I'd assume the same way they're required after statements and after class field declarations, but I'm not personally sure what mechanism achieves that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants