Racket 是否可以更改语法类的结果?

Racket 是否可以更改语法类的结果?,racket,Racket,我目前有一系列用于生成代码的拼接语法类。 它们看起来像这样: (定义拼接语法类vec exp (模式(~序号x y) #:结果为#'(vec x y))) 目标是能够在任何地方匹配序列xy,并将其替换为(vecxy) 目前我看到的唯一方法是创建一个名为result的属性并使用它: >(语法解析#'(位置4.2.5.7) [(:vec exp) (属性.结果)]) #"(vec 4.2 5.7) 有没有办法修改我的代码,这样我就可以通过编写以下代码得到相同的结果 >(语法解析#'(位置4.2.

我目前有一系列用于生成代码的拼接语法类。
它们看起来像这样:

(定义拼接语法类vec exp
(模式(~序号x y)
#:结果为#'(vec x y)))
目标是能够在任何地方匹配序列
xy
,并将其替换为
(vecxy)

目前我看到的唯一方法是创建一个名为
result
的属性并使用它:

>(语法解析#'(位置4.2.5.7)
[(:vec exp)
(属性.结果)])
#"(vec 4.2 5.7)
有没有办法修改我的代码,这样我就可以通过编写以下代码得到相同的结果

>(语法解析#'(位置4.2.5.7)
[(:vec exp)
(属性)])
#'(4.2 5.7) ;; 不是我想要的

我不这么认为。模式
(:vec exp)
意味着“输入必须是一个列表;将其元素绑定到模式变量
”。这些模式变量提供对匹配内容的访问。语法类返回的属性就是生成的属性。
语法解析
系统对于保持这两个概念的不同非常挑剔,因此我认为它不会让您用另一个替换其中一个


您是想让宏更可读还是更不容易出错?如果是这样,也许再多告诉我们一点。也许有办法做到这一点。

FWIW,你可以做到。不确定你是否能接受

(require syntax/parse
         (for-syntax syntax/parse))

(define-splicing-syntax-class vec-exp
  (pattern (~seq x y) #:with result #'(vec x y)))

(define-syntax ~res
  (pattern-expander
   (syntax-parser
     [(_ pat cls)
      #'(~and (~var PAT cls) (~bind [pat (attribute PAT.result)]))])))
然后:

> (syntax-parse #'(position 4.2 5.7)
    [(<name> (~res <pos> vec-exp))
     (attribute <pos>)])
#'(vec 4.2 5.7)
>(语法解析#'(位置4.2.5.7)
[(~res-vec-exp))
(属性)])
#"(vec 4.2 5.7)