[go: nahoru, domu]

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] selector/typeArgument-related ambiguity. #3039

Open
modulovalue opened this issue May 3, 2023 · 2 comments
Open

[grammar] selector/typeArgument-related ambiguity. #3039

modulovalue opened this issue May 3, 2023 · 2 comments
Assignees

Comments

@modulovalue
Copy link

A recent change made it possible to give function invocations type arguments without having to invoke the function with value arguments.

void main() {
  final a = foo<int>;
  print(a); 
}

void foo<T>() {}

It looks like this change has lead to a new production typeArguments in the selector production rule in the ANTLR-based grammar spec.

https://github.com/dart-lang/sdk/blob/b06b994a4eea9eb88ef5b40060bd8ff16b848868/tools/spec_parser/Dart.g#L971-L982

It looks like the language spec grammar snippets have not yet been adjusted to reflect this change i.e. the selector grammar snippet does not contain a typeArguments production.

<selector> ::= `!'
\alt <assignableSelector>
\alt <argumentPart>
<argumentPart> ::=
<typeArguments>? <arguments>

If we were to add a typeArguments production to the selector production rule, then I think this would give id<int>() 2 parse trees:

                ...
1. primary              selector*
   identifier           selector      selector
   identifier           typeArguments argumentPart
   identifier           typeArguments typeArguments? arguments
   identifier           typeArguments      null      arguments
      'id'                  '<int>'                     '()'


                ...
2. primary              selector*
   identifier           selector
   identifier           argumentPart
   identifier           typeArguments arguments
      'id'                  '<int>'      '()'

I'm wondering what a grammar that does not have this ambiguity would look like?

@modulovalue
Copy link
Author

So it looks like, according to this comment by Erik, that this is resolved in favor of the second parse tree because the typeArguments arguments production comes first and that the language specification does not attempt to present a grammar that is deterministic wrt to the parse tree that it describes.

@modulovalue
Copy link
Author

I think I've found a grammar that doesn't have this ambiguity. @eernst if you agree, can we make this change to the ANTLR-based grammar spec (and eventually the language spec)?

The idea is that a selector can only appear as a selector*, so any alternative of selector will be able to follow any other alternative of selector. The third production (argumentPart) of selector can therefore be replaced with arguments because there's already a typeArguments production in selector i.e. I think we can change:

selector
    :    '!'
    |    assignableSelector
    |    argumentPart
    |    typeArguments
    ;

to

selector
    :    '!'
    |    assignableSelector
    |    arguments
    |    typeArguments
    ;

It looks to me like this only removes the ambiguity mentioned in this issue and doesn't change the language that the grammar describes.

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

Successfully merging a pull request may close this issue.

2 participants