我目前有很多用于生成代码的拼接语法类。
他们看起来像这样:
(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
答案 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
系统在保留这两个方面非常谨慎概念截然不同,所以我认为它不会让您用另一个替换。
您是否要使宏更具可读性或更不易出错?如果是这样,也许再告诉我们一点。也许有办法做到这一点。