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

时间:2019-03-27 15:25:06

标签: racket

我目前有很多用于生成代码的拼接语法类。
他们看起来像这样:

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

目标是能够在任何地方匹配序列x y并将其替换为(vec x y)

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

> (syntax-parse #'(position 4.2 5.7)
    [(<name> <pos>:vec-exp)
     (attribute <pos>.result)])
#'(vec 4.2 5.7)

是否可以更改代码,以便通过编写以下代码来获得相同的结果?

> (syntax-parse #'(position 4.2 5.7)
    [(<name> <pos>:vec-exp)
     (attribute <pos>)])
#'(4.2 5.7) ;; not what I want

2 个答案:

答案 0 :(得分:2)

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)

答案 1 :(得分:1)

我不这么认为。模式(<name> <pos>:vec-exp)的意思是“输入必须是一个列表;将其元素绑定到模式变量<name><pos>。”这些模式变量提供对匹配的内容的访问。语法类返回的属性是生成的内容。 syntax-parse系统在保留这两个方面非常谨慎概念截然不同,所以我认为它不会让您用另一个替换。

您是否要使宏更具可读性或更不易出错?如果是这样,也许再告诉我们一点。也许有办法做到这一点。