通过嵌套宏中的省略号捕获可变数量的参数;缺少模式变量错误 [英] Capturing a variable number of arguments via an ellipsis in a nested macro; Missing pattern variable error

查看:84
本文介绍了通过嵌套宏中的省略号捕获可变数量的参数;缺少模式变量错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑两个宏的情况: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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆