通过嵌套宏中的省略号捕获可变数量的参数;缺少模式变量错误 [英] Capturing a variable number of arguments via an ellipsis in a nested macro; Missing pattern variable error
问题描述
考虑两个宏的情况:outer-macro
定义某些实体的一般结构,而inner-macro
在外部宏的范围内扩展.以下代码捕获了我的意图,其中预期的输出是打印语句.此示例对内部宏的模式抛出以下错误:(_ value ...)
.
Consider a scenario of two macros: the outer-macro
defines a general structure of some entity, and the inner-macro
expands in the scope of the outer macro. My intent is captured in the following code, where the expected output is a print statement. This example throws the following error for the pattern of the inner macro: (_ value ...)
.
syntax: no pattern variables before ellipsis in template in: ...
我打算以与外部宏的body ...
模式相同的方式使用value ...
.实际上,值"列表正是我所需要的(不一定是非常灵活的省略号模式").遗憾的是,这种方式无法正常工作.如何捕获内部宏中可变数量的参数?
I intend to use value ...
in the same way as the body ...
pattern of the outer macro. In fact, a list of the 'values' is exactly what I need (not necessarily a very flexible 'ellipsis pattern'). Sadly it does not work this way. How can I capture a variable amount of arguments in the inner macro?
#lang racket
(require
racket/stxparam
(for-syntax syntax/parse))
(define-syntax-parameter inner-macro
(lambda (stx)
(raise-syntax-error 'inner-macro "generic error message" stx)))
(define-syntax (outter-macro stx)
(syntax-parse stx
[(_ body:expr ...+)
#'(syntax-parameterize
([inner-macro
(lambda (stx)
(syntax-case stx ()
[(_ value ...)
(printf "values are: ~a~n" (list value ...))]))])
body ...)]))
(outter-macro
(inner-macro 'a 'b 'c))
; expected result
; > "values are: (a b c)"
推荐答案
要逃避"语法模板中的省略号,可以使用语法(... <form>)
,其中<form>
是处理...
序列的语法模板字面上地.因此,您可以包装一段语法以包括文字省略号:
To "escape" ellipses in syntax templates, you can use the syntax (... <form>)
, where <form>
is a syntax template where ...
sequences are treated literally. Therefore, you can wrap a piece of syntax to include literal ellipses:
> #'(... (syntax-rules ()
[(x ...) (list x ...)]))
#<syntax:4:9 (syntax-rules () ((x ...) (li...>
您可以使用它来包围内部宏定义以逃避内部椭圆:
You can use this to surround your inner macro definition to escape the inner ellipses:
(define-syntax (outer-macro stx)
(syntax-parse stx
[(_ body:expr ...+)
#'(syntax-parameterize
([inner-macro
(lambda (stx)
(... (syntax-case stx ()
[(_ value ...)
(printf "values are: ~a~n" (list value ...))])))])
body ...)]))
但是,这实际上并不完全正确,因为您的syntax-case
正文是错误的-它不返回语法对象.您只是在(printf ...)
之前缺少了#'
(或者您可以使用syntax-rules
),因此正确的实现应为以下方式:
However, this is actually not quite right, because your syntax-case
body is wrong—it does not return a syntax object. You are just missing a #'
before the (printf ...)
(or you could use syntax-rules
), so the correct implementation should be the following:
(define-syntax (outer-macro stx)
(syntax-parse stx
[(_ body:expr ...+)
#'(syntax-parameterize
([inner-macro
(lambda (stx)
(... (syntax-case stx ()
[(_ value ...)
#'(printf "values are: ~a~n" (list value ...))])))])
body ...)]))
这应该可以正常工作.
这篇关于通过嵌套宏中的省略号捕获可变数量的参数;缺少模式变量错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!