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

"Raw identifiers" #724

Open
remexre opened this issue Nov 1, 2022 · 2 comments
Open

"Raw identifiers" #724

remexre opened this issue Nov 1, 2022 · 2 comments

Comments

@remexre
Copy link
Member

remexre commented Nov 1, 2022

(Note that this applies to Silver, I'm not suggesting it as something Silver automatically does for grammar specifications written in Silver.)

Rust has the notion of a raw identifier, which it uses to be able to add new keywords to new editions without breaking the ability to use those names in code in older editions.

For example, Rust 2018+ has Expr ::= Expr '.' 'await', where the await keyword was added as a reserved word in Rust 2018. If a Rust 2015 library wrote struct Foo { await: i32 } (defining a struct with a field named await), a Rust 2018 library should still be able to perform a field access. This can be done by writing foo.r#await rather than foo.await; r#<IDENT> is always treated as <IDENT>, even when <IDENT> is a reserved word.

This comes up in Silver when an extension introduces a reserved word, but it's also a completely normal name the programmer would like to be able to use, especially if some grammars are compiled with the extended compiler and others are compiled with the unextended one (this happens "organically" with melt.nix; is this something I should expect to not blow up btw?)

@krame505
Copy link
Member

krame505 commented Nov 1, 2022

This would be super easy to implement actually - transparent prefixes are intended for addressing just this sort of situation. All we would need to do is add 'r#' as a transparent prefix for IdLower_t and IdUpper_t in the Silver parser spec.

It is a bit annoying that we would need to consistently specify this in every Silver parser spec (silver-ableC, etc.) But it would be pretty trivial to support declaring transparent prefixes as modifiers on terminals or lexer classes.

@krame505
Copy link
Member

krame505 commented Nov 1, 2022

As an aside, I wonder if we can do even better with context-aware scanning, and be able to correctly parse these cases without the need for writing a prefix. We already do something like this in ableC, extending the "lexer hack" for disambiguation of type names / identifiers into a more general mechanism that allows one to define extension marking terminals that can be lexically shadowed (see https://github.com/melt-umn/ableC/blob/develop/grammars/edu.umn.cs.melt.ableC/concretesyntax/LexerHack.sv#L79.) I'm realising now that this is actually slightly broken for the "dot" namespace of structs, since these fields don't go in the parse-time environment that we track in the context parser attribute. Fixing this in ableC would require an annoying amount of parse-time type inference to determine the type on which the field is accessed, which probably isn't at all feasible in Silver. Also the use of #include for libraries helps us in ableC; to do this in Silver for normally-scoped names we would need to support initializing parser attributes when calling the parser to provide names imported/defined in other files... probably not as feasible as I thought when I started typing this comment.

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

No branches or pull requests

2 participants