-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Syntax flaw: Function types and error sets ambiguity #1681
Comments
My answer assumes the language wants to have the ability to put arbitrary types on the left hand side of '!' as this may be useful to interface with C's possibly upcoming _Either(A, B) metatype which would allow Zig to interface with C++'s possibly upcoming value-based exceptions. Arbitrary types on the left hand side would also allow Zig-only code to propagate something other than an error set up the stack, if that's something people may want in the future. If people want this then maybe it's not a good idea to significantly simplify the grammar for '!' or the TypeExpr, but I think you could: A) Change TypeExpr to not include FnProto, forcing parentheses in additional cases such as "fn () (fn () void)" |
@Hejsil is there a problem with resolving these syntax ambiguities by choosing which syntax is more common and then accepting that as the resolution to the ambiguity? The big problem with the return type syntax was that it led to a confusing compile error, it was really easy to trigger the ambiguity, and required hacks in the parser. On the other hand this issue (and some of the other syntax flaw issues) seem innocuous to me. Do you see these issues as problems specifically with the formal grammar specification, or do you see them as problems that plague the language and require syntax changes? |
If you'd like opt 1 to be the default, make the LHS of '!' what it expects now minus 'fn'. Btw @Hejsil, "TypeExpr" is already being used in the grammar. I just noticed. |
@andrewrk All the ambiguities I report are in the formal grammar. There are a few reasons why I think we should resolve the ambiguities in the grammar instead of "the parser chooses what is more common":
async<comptime A> fn()void {}
// Parsed like this async<(comptime A> fn()void) {}
Having an unambiguous grammar makes it harder to have syntax problems like #760. It also allows for fast prototyping with parser generators which also allows us to validate, that the syntax we chose does not interact weirdly with other syntactic constructs. Ofc, we could also just leave the grammar ambiguous. I just think it defeats the purpose of having one. |
Just looked a little more into formalized grammars, and it seems that there is something called a Parsing expression grammar. The main strength of this grammar form is that it cannot be ambiguous:
This would make it easier to specify a correct grammar, though we still have to look out for rules that would require unlimited lookahead:
Ofc, a handwritten implementation can use as many tricks as it wants to avoid doing unlimited lookahead. |
Fixed: #1685 |
This simplified grammar of the function type syntax is ambiguous:
The text was updated successfully, but these errors were encountered: