extensible-parser-specifica.../scribblings/defining-reusable-mixins.scrbl

80 lines
3.6 KiB
Racket

#lang scribble/manual
@require[scribble/example
"utils.rkt"
@for-label[phc-toolkit/untyped
extensible-parser-specifications
generic-syntax-expanders
racket/base
syntax/parse
(only-in racket/base [... ])]]
@title{Defining reusable parser mixins}
@defform[#:literals (pattern)
(define-eh-alternative-mixin name
maybe-splicing-class
maybe-define-splicing-class
(pattern clause-or-mixin) ...)
#:grammar
[(maybe-define-class
(code:line)
(code:line #:define-syntax-class class-name))
(maybe-define-splicing-class
(code:line)
(code:line #:define-splicing-syntax-class splicing-name))
(clause-or-mixin #,ntax-pattern
(~mixin #,-alternative-mixin)
(~or clause-or-mixin ...)
derived-or)]]{
Defines an @deftech{eh-alternative mixin}, which is implemented as an @tech{
eh-mixin expander}. An eh-alternative mixin is like an
@tech[#:doc '(lib "syntax/scribblings/syntax.scrbl")]{ellipsis-head alternative
set}, except that it can only appear as part of a @racket[~no-order] (possibly
nested under other eh-alternative mixins), and can contain some global
constraints. The global constraints, detailed below, allow the parser to
perform checks across two or more mixins. For example, given a set of options
that can appear in any order, it is possible to specify that two of them are
mutually exclusive, or that two other must appear in a certain order,
regardless of the order of the other options.
The @racket[derived-or] term covers any
@tech[#:doc '(lib "syntax/scribblings/syntax.scrbl")]{pattern expander} or
@tech{eh-mixin expander} application which expands to a
@racket[clause-or-mixin].
The @racket[#:define-syntax-class] option defines a syntax class with the given
@racket[class-name] which matches @racket[{~no-order {~mixin name}}].
The @racket[#:define-splicing-syntax-class] option defines a splicing syntax
class with the given @racket[class-name] which matches
@racket[{~seq-no-order {~mixin name}}].}
@deftogether[[@defthing[#:kind "for-syntax value"
eh-mixin-expander-type expander-type?]
@defproc[#:kind "for-syntax procedure"
(make-eh-mixin-expander)
(and/c expander? eh-mixin-expander?)]
@defproc[#:kind "for-syntax procedure"
(eh-mixin-expander? [v any/c])
boolean?]
@defform[(define-eh-mixin-expander id transformer-procedure)]
@defproc[#:kind "for-syntax procedure"
(expand-all-eh-mixin-expanders [stx-tree syntax?])
syntax?]]]{
These functions and forms allow the creation and manipulation of @deftech{
eh-mixin expanders}. These identifiers are generated by
@racket[define-expander-type]. For more information, see the documentation for
@racket[define-expander-type].}
@section{Using mixins}
@defform[(~mixin #,-alternative-mixin)]{
Expands the @racket[#,-alternative-mixin], with no arguments. This is
equivalent to @racket[(_eh-alternative-mixin)], but @racket[~mixin]
additionally checks that the given @racket[_eh-alternative-mixin] is indeed an
@tech{eh-alternative mixin}. Otherwise, with the syntax,
@racket[(_eh-alternative-mixin)] the name @racket[_eh-alternative-mixin] would
be interpreted as a pattern variable by @racket[syntax-parse] if the expander
was not available for some reason (e.g. a missing import).}