[racket] syntax/parse ellipses question

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Fri Jun 11 15:56:39 EDT 2010

Eric Dobson wrote:
> I'm trying to use the syntax/parse library, and am running into a
> weird problem when using ~or. It works without ellipses, but with
> ellipses it complains about a duplicated attribute. I would assume
> that the attributes with the same name in an ~or pattern were the same
> attribute that could just match in different ways. A simplified
> version is below, the first 4 examples work, and the fifth does not.
> Is there a restriction that I am missing for why this does not work?

There are three variants of ~or: single-term ~or, head ~or, and 
ellipsis-head ~or. Ellipsis-head ~or has different rules for attributes, 
which the docs seem not to explain. I'll update the docs.

> (syntax-parse #'(1 2 3)
>  [((~or x:number) ...) (syntax->datum #'(x ...))])
> (syntax-parse #'(a b c)
>  [((~or x:id) ...) (syntax->datum #'(x ...))])

Both of the above are ellipsis-head ~or, not that it matters.

> (syntax-parse #'(1)
>  [((~or x:id x:number)) (syntax->datum #'(x))])
> (syntax-parse #'(a)
>  [((~or x:id x:number)) (syntax->datum #'(x))])

These are both single-term ~or.

> #;
> (syntax-parse #'(a 1 b)
>  [((~or x:id x:number) ...) (syntax->datum #'(x ...))])

This is ellipsis-head ~or. The difference is that ellipsis-head ~or 
accumulates different alternatives' attributes independently. The 
different alternatives must have disjoint attributes. (For now, anyway; 
I'm considering relaxing that restriction.) For example,

(syntax-parse #'(a b #:c d e #:f g)
   [((~or x:id (~seq k:keyword kx:id)) ...)
    #'((x ...) ((k kx) ...))])
=> #<syntax ((a b e) ((#:c d) (#:f g)))>

You can turn the ~or back into a single-term ~or by putting another 
pattern form between it and the ellipses. For example,

(syntax-parse #'(a 1 b)
   [((~and (~or x:id x:number)) ...) ___])

Hope that helps!


Posted on the users mailing list.