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)