When using syntax/parse, is there a good way to do something like this?

(define-splicing-syntax-class options
  (pattern (~seq (~or (~optional (~seq (~and #:a a?)))
                      (~optional (~seq (~and #:b b?)))
                      (~optional (~seq (~and #:c c?)))
                      (~optional (~seq (~and #:d d?))))
                 ...)
           #:attr a/b #'(a? b?)
           #:attr c/d #'(c? d?)))

When using the above syntax class to parse #'(#:a #:d #:b), then the a/b 
attribute should be #'(#:a #:b) and the c/d attribute should be #'(#:d). 
However, this doesn't work, of course, because if one of the options isn't 
defined, the attribute will be #f, and the attribute binding will fail.

I can get around that by doing something like this:

(define-splicing-syntax-class options
  (pattern (~seq (~or (~optional (~seq (~and #:a a?)))
                      (~optional (~seq (~and #:b b?)))
                      (~optional (~seq (~and #:c c?)))
                      (~optional (~seq (~and #:d d?))))
                 ...)
           #:attr a/b #`(#,@(if (attribute a?) #'(a?) #'())
                         #,@(if (attribute b?) #'(b?) #'()))
           #:attr c/d #`(#,@(if (attribute c?) #'(c?) #'())
                         #,@(if (attribute d?) #'(d?) #'()))))

But that's rather long-winded and verbose. Even better would be a way to group 
the clauses within the pattern, something like this:

(define-splicing-syntax-class options
  (pattern (~seq (~or (~and (~seq (~optional (~seq (~and #:a a?)))
                                  (~optional (~seq (~and #:b b?))))
                            a/b)
                      (~and (~seq (~optional (~seq (~and #:c c?)))
                                  (~optional (~seq (~and #:d d?))))
                            c/d))
                 ...)))

But that obviously doesn't work, and I'm not sure what it would do even if it 
compiled.

Anyway, is there a more concise way to do this? I know it's relatively easy 
using `template` from syntax/parse/experimental/template, but this is going 
into the Typed Racket code, so we're intentionally avoiding a dependency on 
that.

Alexis

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to