【发布时间】:2013-10-05 19:57:30
【问题描述】:
假设我有以下宏:
(define-syntax-rule (qq x) '(1 x))
我可以将看起来像 (qq (qq 2)) 的东西扩展为 '(1 (1 2)) 而不是 (1 (qq 2) 吗?
我说“看起来像”的原因是因为到目前为止唯一的hint I found 表明由内而外的宏扩展很棘手,所以我想知道是否有更明智的方法来获得我想要的最终结果。
我最初的动机与 Racket 的 parser generator library 有关:为了创建语法,库提供了一个如下所示的 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 先扩展,它将把 list-rules 本身视为非终端,而不是将其扩展为真正的非终端(numbers 和 numberx)。
【问题讨论】:
-
请花几分钟时间学习如何format Lisp code。