如何匹配球拍中的语法?

时间:2018-06-30 01:43:57

标签: racket

我想编写一个与给定语法是if还是cond匹配的宏,我尝试这样写:

(define-syntax (foo stx)
  (syntax-case stx ()
    [(_ (if a b)) #'"if!"] 
    [(_ (cond a b) #'"cond!"]))

,但始终与第一种情况匹配。如何区分这两种情况?

1 个答案:

答案 0 :(得分:1)

syntax-case模式中,标识符匹配任何东西。您已经假设这是对的:编写模式(if a b)时,假设您假设a将匹配任何语法,而不仅仅是文字标识符aif标识符也是如此-您实际上并没有检查标识符是否为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

有关更多信息,请see the documentation for syntax/parse