【发布时间】:2018-05-21 20:49:44
【问题描述】:
来自https://www.gnu.org/software/guile/manual/html_node/Syntax-Rules.html#Syntax-Rules我得到了以下宏示例:
(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))
我很难理解. tail 匹配的部分以及原因。我尝试使用... 而不是. 并将其放在tail 后面,以便捕获未捕获语法错误的示例,因为它没有进入第一个匹配案例,但它不起作用并且告诉我这是省略号的错误用法。我的猜测是,在同一嵌套级别中不能有两个省略号,因为很难知道哪个省略号匹配什么。有点像正则表达式在某些情况下的计算成本很高。
那么. tail 在示例中匹配什么,为什么没有捕获到那个示例?
【问题讨论】: