-
Notifications
You must be signed in to change notification settings - Fork 14
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
Expression statements can't begin with {, even in quasi #287
Comments
Thanks! 👍 Discussed this one with @sergot tonight. I think I have a proper fix for it, namely this: @@ -64,7 +64,7 @@ grammar _007::Parser::Syntax {
['=' <EXPR>]?
}
token statement:expr {
- <![{]> # }], you're welcome vim
+ <!before <!before '{{{'> '{'> # } }}}, you're welcome vim
<EXPR>
}
token statement:block { <pblock> } It passes all the tests on master. But I'd like to (a) explain/explore why that line is there in the first place, and (b) write a regression test involving unquotes first in an expression. |
Closes #287. As described in that issue, a statement starting with an unquote '{{{' wouldn't parse properly. This was a bug, ultimately caused by the fact that a statement starting with a '{' was deemed to *not* be an expression statement. The reason for this latter rule is that '{' starting a statement introduces a *statement block*, like so: { my thing = "statement block"; say("Hello, I'm a " ~ thing); } The same disambiguation technique exists in Perl 5, Perl 6, and JavaScript: '{' starts an object literal, except at the start of a statement where it starts a statement block. (Confounsing factor: I used to be able to demonstrate this as parsing errors in Chrome Devtools, Firefox, and Node -- but all these have lately improved their CLI parsing to introduce exceptions so that it magically understands your intent and prefers object literals. This also breaks some of the examples from the WAT talk.) Fortunately, LTM offers us an out here: a '{{{' "token" is not a type of '{' token, and so we should only disallow the former, not the latter. It's quite unambiguously the case that '{' can not occur at the start of an expression statement, but '{{{' *can*.
Fix uploaded as #289 — @dan-simon and @sergot, feel free to have a look when you have time. |
This fix looks good to me. We still have the analogous problem for object literals, but I don't think that can be fixed (for example, the empty object literal looks the same as the empty block). This being a problem is very rare, but it comes up in macros like
In this case one can just surround the object in parentheses. But if we ever want, for example, object destructuring assignment, that won't work. |
Agreed about the problem for object literals. They way that problem is solved outside of quasis is with this disambiguation rule:
As rules go, I'm pretty comfortable with this one, given that we want to avoid backtracking and given the unfortunate circumstance that object literals and blocks share a starter. The one interesting complication is that quasis try to be "minimal" in the sense that they evaluate to the syntactically "simplest" form: a But, first, that shouldn't affect the parse at all. Having the parse be influenced by such a minimality criterion — such as, for example, choosing to parse something as an empty object literal instead of an empty block because that would make it able to return a simpler form — would not be a good idea. Secondly, I don't know if that minimality rule is even necessary anymore, given the most recent happenings around |
While trying to debug
macro swap(a, b) { return quasi { my temp = {{{a}}}; {{{a}}} = {{{b}}}; {{{b}}} = temp; None } }; my w = 5; my z = 10; swap(w, z); say([w, z])
(the swap example from #194) I found that the error message seems to be due to the statement:expr token's definition being:
This causes issues in expressions like
Where the statement expression {{{a}}} + {{{b}}} starts with { and so is not accepted by statement:expr.
This issue also occurs with objects:
fails to parse.
I don't feel like I understand perl 6, the parser well enough to know how to fix this issue. I assume that <![{]> is there since we want to accept blocks (which start with {) as blocks rather than expressions, but I'm not sure.
The text was updated successfully, but these errors were encountered: