Zulip Chat Archive
Stream: metaprogramming / tactics
Topic: Can DSLs avoid collision with keywords ?
Ray Myers (Jan 04 2025 at 23:36):
Hi all, this one might be easy for people who have made Elaborators but I'm stuck. I'm reading the Lean Metaprogramming book and making an S-expression DSL, and I'm trying to figure out how to define my own kind of identifier that behaves differently than Lean's built-in ident
. For instance, -
should be allowed within an identifier, and keywords like if
can be identifiers.
Could someone point me in the right direction? Thanks!
import Lean
inductive Sexpr : Type where
| list : List Sexpr → Sexpr
| symbol : String → Sexpr
declare_syntax_cat sexpr
syntax str : sexpr
syntax "(" sexpr* ")" : sexpr
syntax ident : sexpr
open Lean Elab Meta in
partial def elabSexpr : Syntax → MetaM Expr
| `(sexpr| $x:ident) => mkAppM ``Sexpr.symbol #[mkStrLit x.getId.getString!]
| `(sexpr| ( $xs:sexpr* ) ) => do
let xsElab ← xs.mapM (fun x => elabSexpr x)
mkAppM `Sexpr.list #[ ← mkListLit (mkConst `Sexpr) xsElab.toList ]
| _ => throwUnsupportedSyntax
elab ">>" p:sexpr "<<" : term => elabSexpr p
#check >> (s a) <<
#check >> (if a b) <<
-- unexpected token 'if'; expected ')'
Ray Myers (Jan 05 2025 at 09:30):
Looks like this overlaps with this question as luck would have it...
#general > How can I parse custom tokens with the Lean Parser?
Spanky (Jan 05 2025 at 09:53):
I had quite a similar few days ago (the overlapping question you linked).
I found a few solutions:
- You can roll your own parser for identifiers. It's fiddly and tedious and requires a lot of effort to work well, but it allows you to define identifiers exactly like you want them.
- Instead of
ident
, userawIdent
(Lean.Parser.rawIdent
) in yoursyntax
declaration (but keep usingident
in the syntax quotations).rawIdent
is a similar toident
, but which ignores the registered tokens and that doesn't support namespacing. It doesn't give you full control over what's an allowed identifier, but it's perfect for prototyping. - Use
«if»
instead ofif
, that way theident
parser treats it as an identifier rather than a keyword.
Last updated: May 02 2025 at 03:31 UTC