我的拼接语法类定义如下。语法类匹配两个语句(第一个模式)、其中一个语句(第三个和第二个模式)的序列,甚至可能根本不匹配这些语句(最后一个模式)。
正如您所看到的,有相当多的“重复”代码,因为每个模式要么返回模式中捕获的某些内容的属性,要么返回空的内容。我遇到的问题是,目前该语句从来都不是真正可选的,因为最后一个模式must匹配某事。在这种情况下,一组空括号()
.
问题是:如何使该声明真正成为可选的?作为一个附带问题 - 可以通过更好地利用头部模式来压缩代码吗?
(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 ...) #'()])
这两个都使用一个空的(~seq)
case(匹配 0 个术语)以使其可选,而不是()
,匹配 1 个术语。然后可以像这样定义与原始语法类类似的语法类:
(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 个术语,这必须是()
当两个选项都不存在时。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)