Macros 方案宏什么与什么匹配?

Macros 方案宏什么与什么匹配?,macros,scheme,matching,Macros,Scheme,Matching,从中,我得到了以下宏示例: (define-syntax simple-let (syntax-rules () ((_ (head ... ((x . y) val) . tail) body1 body2 ...) (syntax-error "expected an identifier but got" (x . y))) ((_ ((name val) ...) body1 body2 ...) ((lam

从中,我得到了以下宏示例:

(define-syntax simple-let
  (syntax-rules ()
    ((_ (head ... ((x . y) val) . tail)
        body1 body2 ...)
     (syntax-error
      "expected an identifier but got"
      (x . y)))
    ((_ ((name val) ...) body1 body2 ...)
     ((lambda (name ...) body1 body2 ...)
      val ...))))
我试图了解这个宏是如何工作的。所以我给它加了一点注释:

;; EXAMPLE 7
;; Reporting errors at macro-expansion time (read time, compile time).
(define-syntax simple-let
  (syntax-rules ()
    [(simple-let (head ... ((x . y) val) . tail)
                                        ; (1) head ... can also be zero times?
                                        ; (2) what is `. tail` matching?
                                        ; (3) can I not use two ellipsis on the
                                        ; same level instead of `. tail`?
                 body1
                 body2 ...)
     (syntax-error "expected an identifier but got"
                   (x . y))]
    ;; if there ((a . b) val) is not matched
    [(simple-let ((name val) ...)
                 body1
                 body2 ...)
     ((lambda (name ...)
        body1
        body2 ...)
      val ...)]))
就其工作原理而言,我唯一不了解的部分是第一个匹配表达式:

(simple-let (head ... ((x . y) val) . tail)
所以我试了几个例子:

;; simply working
(simple-let ([a 3])
            (+ a 4))

;; caught
(simple-let ([(a . b) 3])  ; Q: What is `. tail` matching in this one?
            (+ a 4))
(simple-let ([a 3] [(b . c) 3])  ; Q: What is `. tail` matching in this one?
            (+ a b))

;; not caught
(simple-let ([a 3] [(b . c) 3] [d 4])  ; Q: Why is `. tail` not matching `[d 4]`?
            (+ a b))
我很难理解什么是
。尾部
匹配及其原因。我尝试使用
..
而不是
,并将其放在
尾部
后面,以便捕获语法错误未被捕获的示例,因为它没有进入第一个匹配情况,但不起作用,并告诉我这是省略号的错误用法。我的猜测是,一个人不能在同一嵌套级别上有两个省略号,因为很难知道哪个省略号与哪个匹配。有点像正则表达式,在某些情况下计算量会变得很高


那么
有什么作用呢。尾部
在示例中匹配,为什么一个示例没有被捕获?

通常尾部与列表的其余部分匹配,例如

对于与模式(1.x)匹配的“(1 2 3 4),x匹配“(2 3 4)

结果令人困惑,因此需要到源代码处查看实现(请参阅ice-9/psyntax.scm)

在这里可以看到省略号被翻译成(每个+xyz),在这个例子中z是tail,并且与最后一个cdr相匹配,在所有例子中都是'()

在这个例子中。。。我是格雷迪和。尾巴不是。如果您对这种行为的记录方式不满意,或者希望更改实现,您可以在guile-devel邮件列表中询问:guile-devel@gnu.org


Guile还将语法分析作为一个可下载的库(搜索Guile语法分析),这是racket的语法分析的一个端口。几年前(如果您好奇,请参阅racket的文档),我用语法分析对您的示例进行了编码,并按照您的预期执行。

与其他一些在线资源相比,我发现Guile文档中的示例很好地解释了这一点,但有一点除外。很高兴知道计划之间存在如此微妙的差异。我天真地认为行为会是一样的,因为Guile和Racket符合一些RNR,但可能这些RNR中没有指定这方面。