我想编写一个与给定语法是if
还是cond
匹配的宏,我尝试这样写:
(define-syntax (foo stx)
(syntax-case stx ()
[(_ (if a b)) #'"if!"]
[(_ (cond a b) #'"cond!"]))
,但始终与第一种情况匹配。如何区分这两种情况?
答案 0 :(得分:1)
在syntax-case
模式中,标识符匹配任何东西。您已经假设这是对的:编写模式(if a b)
时,假设您假设a
将匹配任何语法,而不仅仅是文字标识符a
。 if
标识符也是如此-您实际上并没有检查标识符是否为if
,您只是在匹配任何语法并将其绑定到名为{{1}的模式变量}。
这是文字列表的用途。当您将标识符放入文字列表中时,它会告诉if
检查该特定标识符,而不是绑定模式变量。因此,您可能需要这样做,而不是:
syntax-case
但是,请注意(define-syntax (foo stx)
(syntax-case stx (if cond)
[(_ (if a b)) #'"if!"]
[(_ (cond a b) #'"cond!"]))
已经很老了,而Racket在近十年的时间里已经提供了更好的语法匹配库syntax-case
。在任何情况下,我都建议在syntax/parse
上使用它。上述宏的syntax-case
等效项如下:
syntax/parse
…基本相同,但是(require (for-syntax syntax/parse))
(define-syntax (foo stx)
(syntax-parse stx
#:literals [if cond]
[(_ (if a b)) #'"if!"]
[(_ (cond a b) #'"cond!"]))
的模式语言比syntax-parse
的模式语言丰富得多。例如,如果您想省略syntax-case
声明,则可以使用#:literals
注释各个文字模式:
~literal