Zulip Chat Archive
Stream: lean4
Topic: Unexpected token when pretty printing something
xiao (Sep 23 2025 at 22:50):
I defined a context to be a partial map from variables to natural numbers like the following.
inductive Context where
| empty: Context
| update: Context -> String -> Nat -> Context
| merge: Context -> Context -> Context
deriving Repr
I also wanted to add some customized syntax for it, so I did the following.
declare_syntax_cat context
syntax "[]": context
syntax term: context
syntax ident " : " term: context
syntax "[" term "]" " : " term: context
syntax context ", " context: context
syntax "[ctx| " context " ]": term
macro_rules
| `([ctx| [] ]) => `(Context.empty)
| `([ctx| $t:term ]) => `($t)
| `([ctx| $x:ident : $n]) => `(
Context.update .empty $(Lean.quote (toString x.getId)) $n
)
| `([ctx| [$x:term]: $n]) => `(Context.empty.update $x $n)
| `([ctx| $c1, $c2 ]) => `(Context.merge [ctx| $c1] [ctx| $c2])
Here, [ctx| x: 0] is defined to be Context.empty.update "x" 0, while sometimes x may be some Lean term, so I defined an escape bracket, i.e. [ctx| [s]: 0] is Context.empty.update s 0`.
def s := "some_name"
#check [ctx| []] -- Context.empty
#check [ctx| x: 3, y: 4, [s]: 8] -- (Context.empty.update "x" 3).merge ((Context.empty.update "y" 4).merge (Context.empty.update s 8))
Certainly, I wanted to pretty print it, so I added the following unexpanders.
@[app_unexpander Context.empty]
def unexpandContext_empty: Lean.PrettyPrinter.Unexpander
| `($_) => `([ctx| [] ])
@[app_unexpander Context.update]
def unexpandContext_update: Lean.PrettyPrinter.Unexpander
| `($_ $_ $x:term $v) => `([ctx| [$x] : $v ])
| _ => throw ()
@[app_unexpander Context.merge]
def unexpandContext_merge: Lean.PrettyPrinter.Unexpander
| `($_ [ctx| $x] [ctx| $y]) => `([ctx| $x, $y ])
| _ => throw ()
They worked well except that [ctx| x: 4] is pretty printed as [ctx| ["x"]: 4].
def s := "some_name"
#check [ctx| []] -- [ctx| [] ]
#check [ctx| x: 3, y: 4, [s]: 8] -- [ctx| ["x"] : 3, ["y"] : 4, [s] : 8 ]
I wanted it pretty-printed exactly as how I wrote it, i.e., [ctx|x: 4], so I changed the unexpandContext_update a little bit.
@[app_unexpander Context.update]
def unexpandContext_update: Lean.PrettyPrinter.Unexpander
| `($_ $_ $x:str $v) =>
let ident := Lean.mkIdent (Lean.Name.mkSimple x.getString)
`([ctx| $ident : $v ])
| `($_ $_ $x:term $v) => `([ctx| [$x] : $v ])
| _ => throw ()
Then, Lean complained unexpected token ':'; expected ']' at the : of `([ctx| $ident : $v ]).
What's the reason for that and how can I fixe it? I was following the meta-programming book. The error still occurred when I changed the : to some other symbol.
xiao (Sep 23 2025 at 22:51):
You can find the code here.
Robin Arnez (Sep 24 2025 at 06:22):
You often need to be explicit about what syntax kind you have:
`([ctx| $ident:ident : $v ])
should work
xiao (Sep 24 2025 at 16:01):
Robin Arnez 发言道:
You often need to be explicit about what syntax kind you have:
`([ctx| $ident:ident : $v ])should work
I see. It works. Thank you!.
Last updated: Dec 20 2025 at 21:32 UTC