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中没有指定这方面。