Racket 匹配可选模式并绑定属性的拼接语法类

Racket 匹配可选模式并绑定属性的拼接语法类,racket,Racket,下面定义了一个拼接语法类。syntax类匹配由两个语句(第一个模式)、一个语句(第三个和第二个模式)组成的序列,甚至可能根本不匹配这些语句(最后一个模式) 正如您所看到的,有相当多的“重复”代码,因为每个模式要么返回模式中捕获的某些内容的属性,要么返回一个空的内容。我的问题是,目前该语句从来都不是真正可选的,因为最后一个模式必须匹配某些内容。在本例中,一组空括号() 问题是:我怎样才能使这个陈述真正具有选择性?作为一个附带问题,代码是否可以通过更好地使用头部模式来压缩 (define-splic

下面定义了一个拼接语法类。syntax类匹配由两个语句(第一个模式)、一个语句(第三个和第二个模式)组成的序列,甚至可能根本不匹配这些语句(最后一个模式)

正如您所看到的,有相当多的“重复”代码,因为每个模式要么返回模式中捕获的某些内容的属性,要么返回一个空的内容。我的问题是,目前该语句从来都不是真正可选的,因为最后一个模式必须匹配某些内容。在本例中,一组空括号
()

问题是:我怎样才能使这个陈述真正具有选择性?作为一个附带问题,代码是否可以通过更好地使用头部模式来压缩

(define-splicing-syntax-class signal-subscriptions-and-declarations
  #:description "subscriptions to signals and signal declarations"

  ; Match the case where both a subscription and declaration statement is present
  (pattern (~seq subscribed:signal-subscriptions  declared:signal-declarations)
           #:with (subscription-collection  ...) #'(subscribed.signal-collection ...)
           #:with (subscription-signal-id   ...) #'(subscribed.signal-identifier ...)
           #:with (declaration-signal-id    ...) #'(declared.signal-identifier ...))

  ; Match the case where no declaration statement is present
  (pattern subscribed:signal-subscriptions
           #:with (subscription-collection ...) #'(subscribed.signal-collection ...)
           #:with (subscription-signal-id  ...) #'(subscribed.signal-identifier ...)
           #:with (declaration-signal-id   ...) #'())

  ; Match the case where no subscription statement is present
  (pattern declared:signal-declarations
           #:with (subscription-collection ...) #'()
           #:with (subscription-signal-id  ...) #'()
           #:with (declaration-signal-id   ...) #'(declared.signal-identifier ...))

  (pattern ()
           #:with (subscription-collection ...) #'()
           #:with (subscription-signal-id  ...) #'()
           #:with (declaration-signal-id   ...) #'()))

听起来你有两个不同的东西,都是可选的。因此,有两个单独的语法类是有意义的,如下所示:

(define-splicing-syntax-class opt-signal-subscriptions
  ;; Match the case where a subscription is present
  [pattern (~seq subscribed:signal-subscriptions)
           #:with (subscription-collection  ...) #'(subscribed.signal-collection ...)
           #:with (subscription-signal-id   ...) #'(subscribed.signal-identifier ...)]
  ;; Match the case where no subscription is present
  [pattern (~seq)
           #:with (subscription-collection  ...) #'()
           #:with (subscription-signal-id   ...) #'()])

(define-splicing-syntax-class opt-signal-declarations
  ;; Match the case where a declaration statement is present
  [pattern (~seq declared:signal-declarations)
           #:with (declaration-signal-id    ...) #'(declared.signal-identifier ...)]
  ;; Match the case where no declaration statement is present
  [pattern (~seq)
           #:with (declaration-signal-id    ...) #'()])
(define-splicing-syntax-class signal-subscriptions-and-declarations
  #:description "subscriptions to signals and signal declarations"
  #:auto-nested-attributes
  [pattern (~seq :opt-signal-subscriptions :opt-signal-declarations)])
两者都使用空的
(~seq)
大小写(匹配0个术语)使其成为可选的,而不是匹配1个术语的
()
。然后,可以这样定义与原始语法类类似的语法类:

(define-splicing-syntax-class opt-signal-subscriptions
  ;; Match the case where a subscription is present
  [pattern (~seq subscribed:signal-subscriptions)
           #:with (subscription-collection  ...) #'(subscribed.signal-collection ...)
           #:with (subscription-signal-id   ...) #'(subscribed.signal-identifier ...)]
  ;; Match the case where no subscription is present
  [pattern (~seq)
           #:with (subscription-collection  ...) #'()
           #:with (subscription-signal-id   ...) #'()])

(define-splicing-syntax-class opt-signal-declarations
  ;; Match the case where a declaration statement is present
  [pattern (~seq declared:signal-declarations)
           #:with (declaration-signal-id    ...) #'(declared.signal-identifier ...)]
  ;; Match the case where no declaration statement is present
  [pattern (~seq)
           #:with (declaration-signal-id    ...) #'()])
(define-splicing-syntax-class signal-subscriptions-and-declarations
  #:description "subscriptions to signals and signal declarations"
  #:auto-nested-attributes
  [pattern (~seq :opt-signal-subscriptions :opt-signal-declarations)])

这与原来的不同,因为它可以匹配0、1或2个术语,而您的术语至少需要1个术语,当两个选项都不存在时,必须是
()

作为注释,在
信号订阅和声明
中,您需要命名订阅和声明模式变量,并在
#:with
子句中包含要向类用户提供的所有内容(来自订阅和声明变量)哦,抱歉,我的意思是包含自动嵌套属性,这是另一种方法。我不知道。酷。谢谢