Scheme macro 什么匹配什么?
Scheme macro what does match what?
从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
在示例中匹配了什么,为什么没有捕获到一个示例?
通常尾部匹配列表的其余部分,例如
对于匹配模式 (1 . x) 的 '(1 2 3 4),x 匹配 '(2 3 4)。
结果令人困惑,因此需要查看源代码以查看实现(参见 ice-9/psyntax.scm)
可以看到省略号被转换为 (each+ x y z),在这种情况下 z 是尾巴并且匹配最后一个 cdr,在所有情况下都是 '()。
在示例中...已经准备好并且。尾巴不是。如果您对这种行为的记录方式不满意或想更改实现方式,您可以在 guile-devel 邮件列表中提问:guile-devel@gnu.org
Guile 也有 syntax-parse 作为可下载的库(搜索 guile-syntax-parse),它是几年前球拍的 syntax-parse 的一个端口(参见球拍的文档如果你好奇的话)我用 syntax-parse 对你的例子进行了编码,并且按照你的预期执行。
从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
在示例中匹配了什么,为什么没有捕获到一个示例?
通常尾部匹配列表的其余部分,例如
对于匹配模式 (1 . x) 的 '(1 2 3 4),x 匹配 '(2 3 4)。
结果令人困惑,因此需要查看源代码以查看实现(参见 ice-9/psyntax.scm)
可以看到省略号被转换为 (each+ x y z),在这种情况下 z 是尾巴并且匹配最后一个 cdr,在所有情况下都是 '()。
在示例中...已经准备好并且。尾巴不是。如果您对这种行为的记录方式不满意或想更改实现方式,您可以在 guile-devel 邮件列表中提问:guile-devel@gnu.org
Guile 也有 syntax-parse 作为可下载的库(搜索 guile-syntax-parse),它是几年前球拍的 syntax-parse 的一个端口(参见球拍的文档如果你好奇的话)我用 syntax-parse 对你的例子进行了编码,并且按照你的预期执行。