Conformément à Suggestion de @dlatikay en suivant une intuition existante, une recherche sur CoveredParenthesizedExpression
a permis de mieux comprendre ce qui se passe ici.
Apparemment, la raison pour laquelle un non-terminal ne peut pas être trouvé dans la base de données des spec pour expliquer pourquoi (foo)
est acceptable en tant que LeftHandExpression
est étonnamment simple. Je suppose que vous comprenez comment fonctionnent les analyseurs syntaxiques, et qu'ils fonctionnent en deux étapes distinctes : Lexing y Analyse syntaxique .
Ce que j'ai appris de cette petite recherche, c'est que la construction (foo)
n'est pas techniquement livré à l'analyseur syntaxique, et donc au moteur, comme vous pourriez le penser.
var foo = (((bar)));
Comme nous le savons tous, une telle chose est parfaitement légale. Pourquoi ? Eh bien, visuellement, vous pouvez juste ignorer la parenthèse alors que l'affirmation reste parfaitement logique.
De même, voici un autre exemple valable, même du point de vue de la lisibilité humaine, car les parenthèses n'explicitent que ce que PEMDAS rend déjà implicite.
(3 + ((4 * 5) / 2)) === 3 + 4 * 5 / 2
>> true
On peut en déduire une observation clé, si l'on comprend comment les analyseurs syntaxiques fonctionnent déjà. (rappelez-vous, Javascript est toujours analysé ( lire : compilé ) et puis run) Donc, dans un sens direct, ces parenthèses sont "énoncer l'évidence" .
Donc, tout cela étant dit, que se passe-t-il exactement ?
En gros, les parenthèses (à l'exception des paramètres de fonction) sont regroupées en fonction des symboles qui les contiennent. En termes simples, cela signifie que les parenthèses ne sont interprétées que pour guider l'analyseur syntaxique dans le regroupement de ce qu'il lit. Si le contexte des parenthèses est déjà "en ordre", et ne nécessite donc aucune modification de l'information émise par l'analyseur. AST le code (machine) est alors émis comme si ces parenthèses n'existaient pas du tout.
L'analyseur est plus ou moins paresseux, en supposant que les parenthèses sont impertinentes. (ce qui dans ce cas limite, n'est pas vrai)
Ok, et où cela se passe-t-il exactement ?
Selon 12.2.1.5 Sémantique statique : IsValidSimpleAssignmentTarget dans la spécification,
PrimaryExpression : (CouvertureParenthesizedExpressionAndArrowParameterList)
- Soit expr une expression couverte de CoverParenthesizedExpressionAndArrowParameterList.
- Retourne IsValidSimpleAssignmentTarget de expr.
I.E. Si vous attendez primaryExpression
retourner ce qui se trouve à l'intérieur de la parenthèse et l'utiliser.
Pour cette raison, dans ce scénario, il ne convertit pas (foo)
en CoveredParenthesizedExpression{ inner: "foo" }
il le convertit simplement en foo
ce qui préserve le fait qu'il s'agit d'un Identifier
et donc syntaxiquement, sans être nécessairement lexical valable.
TL;DR
C'est wat.
Vous voulez en savoir un peu plus ?
Vérifiez La réponse de @Bergi .