defining-reusable-mixins.scrbl (3724B)
1 #lang scribble/manual 2 @require[scribble/example 3 "utils.rkt" 4 @for-label[phc-toolkit/untyped 5 extensible-parser-specifications 6 generic-syntax-expanders 7 racket/base 8 syntax/parse 9 (only-in racket/base [... …])]] 10 11 @title{Defining reusable parser mixins} 12 13 @defform[#:literals (pattern) 14 (define-eh-alternative-mixin name 15 maybe-splicing-class 16 maybe-define-splicing-class 17 (pattern clause-or-mixin) ...) 18 #:grammar 19 [(maybe-define-class 20 (code:line) 21 (code:line #:define-syntax-class class-name)) 22 (maybe-define-splicing-class 23 (code:line) 24 (code:line #:define-splicing-syntax-class splicing-name)) 25 (clause-or-mixin #,ntax-pattern 26 (~mixin #,-alternative-mixin) 27 (~or clause-or-mixin ...) 28 derived-or)]]{ 29 Defines an @deftech{eh-alternative mixin}, which is implemented as an @tech{ 30 eh-mixin expander}. An eh-alternative mixin is like an 31 @tech[#:doc '(lib "syntax/scribblings/syntax.scrbl")]{ellipsis-head alternative 32 set}, except that it can only appear as part of a @racket[~no-order] (possibly 33 nested under other eh-alternative mixins), and can contain some global 34 constraints. The global constraints, detailed below, allow the parser to 35 perform checks across two or more mixins. For example, given a set of options 36 that can appear in any order, it is possible to specify that two of them are 37 mutually exclusive, or that two other must appear in a certain order, 38 regardless of the order of the other options. 39 40 The @racket[derived-or] term covers any 41 @tech[#:doc '(lib "syntax/scribblings/syntax.scrbl")]{pattern expander} or 42 @tech{eh-mixin expander} application which expands to a 43 @racket[clause-or-mixin]. 44 45 The @racket[#:define-syntax-class] option defines a syntax class with the given 46 @racket[class-name] which matches @racket[{~no-order {~mixin name}}]. 47 48 The @racket[#:define-splicing-syntax-class] option defines a splicing syntax 49 class with the given @racket[class-name] which matches 50 @racket[{~seq-no-order {~mixin name}}].} 51 52 @deftogether[[@defthing[#:kind "for-syntax value" 53 eh-mixin-expander-type expander-type?] 54 @defproc[#:kind "for-syntax procedure" 55 (make-eh-mixin-expander) 56 (and/c expander? eh-mixin-expander?)] 57 @defproc[#:kind "for-syntax procedure" 58 (eh-mixin-expander? [v any/c]) 59 boolean?] 60 @defform[(define-eh-mixin-expander id transformer-procedure)] 61 @defproc[#:kind "for-syntax procedure" 62 (expand-all-eh-mixin-expanders [stx-tree syntax?]) 63 syntax?]]]{ 64 These functions and forms allow the creation and manipulation of @deftech{ 65 eh-mixin expanders}. These identifiers are generated by 66 @racket[define-expander-type]. For more information, see the documentation for 67 @racket[define-expander-type].} 68 69 @section{Using mixins} 70 71 @defform[(~mixin #,-alternative-mixin)]{ 72 Expands the @racket[#,-alternative-mixin], with no arguments. This is 73 equivalent to @racket[(_eh-alternative-mixin)], but @racket[~mixin] 74 additionally checks that the given @racket[_eh-alternative-mixin] is indeed an 75 @tech{eh-alternative mixin}. Otherwise, with the syntax, 76 @racket[(_eh-alternative-mixin)] the name @racket[_eh-alternative-mixin] would 77 be interpreted as a pattern variable by @racket[syntax-parse] if the expander 78 was not available for some reason (e.g. a missing import).} 79