假设我有以下宏:
(define-syntax-rule (qq x) '(1 x))
我可以做一些看起来像(qq (qq 2))
扩展'(1 (1 2))
而不是的东西(1 (qq 2)
吗?
我说“看起来像”的原因是因为到目前为止我发现的唯一提示表明由内而外的宏扩展很棘手,所以我想知道是否有更明智的方法来获得我想要的最终结果。
我最初的动机与 Racket 的解析器生成器库有关:为了创建语法,该库提供了一个parser
如下所示的宏:
(define my-parser (parser
(start start) (end EOF)
(tokens value-tokens op-tokens)
(error (lambda (a b c) (void)))
(grammar
(start [(numbers) $1])
(numbers [(numberx) (reverse $1)])
(numberx [() empty]
[(numberx NUM) (cons $2 $1)])
)
))
我的语法有很多我想抽象出来的样板。例如,我希望能够定义某种list-rules
抽象,让我写出类似于
(define my-parser (parser
(start start) (end EOF)
(tokens value-tokens op-tokens)
(error (lambda (a b c) (void)))
(grammar
(start [(numbers) $1])
(list-rules NUM numbers numberx)
)
))
但是,如果parser
get 首先扩展,它将把list-rules
自己视为非终结符,而不是将其扩展为真正的非终结符(numbers
and numberx
)。