通过嵌套宏中的省略号捕获可变数量的参数;(Capturing a variable number of arguments via an ellipsis in a nested macro; Mis

编程入门 行业动态 更新时间:2024-10-10 04:26:35
通过嵌套宏中的省略号捕获可变数量的参数;(Capturing a variable number of arguments via an ellipsis in a nested macro; Missing pattern variable error)

考虑两个宏的场景: outer-macro定义了一些实体的一般结构, inner-macro在外部宏的范围inner-macro扩展。 我的意图被捕获在下面的代码中,其中预期的输出是一个打印语句。 此示例将引发内部宏的模式的以下错误: (_ value ...) 。

syntax: no pattern variables before ellipsis in template in: ...

我打算以与外部宏观的body ...模式相同的方式value ... 事实上,“价值”的清单正是我所需要的(不一定非常灵活的省略号模式)。 可悲的是,这种方式不起作用。 我如何在内部宏中捕获可变数量的参数?

#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)"

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: ...

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>是语法模板,其中...序列按字面意思处理。 因此,你可以包装一段语法来包含直接的省略号:

> #'(... (syntax-rules () [(x ...) (list x ...)])) #<syntax:4:9 (syntax-rules () ((x ...) (li...>

你可以用它来包围你的内部宏定义来转义内部的椭圆:

(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 ),所以正确的实现应该如下:

(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 ...)]))

这应该按预期工作。

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 ...)]))

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 ...)]))

This should work as intended.

更多推荐

本文发布于:2023-08-07 10:57:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1464303.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:省略号   嵌套   数量   参数   variable

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!