pre.scrbl (3610B)
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{Pre operations} 12 13 @defform[#:kind "eh-mixin expander" 14 (~named-seq #,tribute-name #,ntax-pattern ...)]{ 15 Equivalent to @racket[{~seq #,ntax-pattern ...}], but also binds the 16 @racket[#,tribute-name] to the whole sequence. If the sequence appears inside 17 an @racket[~optional] or @racket[~or] clause that fails, the 18 @racket[_attribute-name] is still bound to the empty sequence. 19 20 Known issues: this may not behave as expected if @racket[~named-seq] appears 21 under ellipses. 22 23 This probably should bind the sequence attribute @emph{before} the "global" 24 operations, instead of being a "post" operation, and may be changed in that way 25 the future.} 26 27 @defform[#:kind "eh-mixin expander" 28 (~maybe/empty #,ntax-pattern ...)]{ 29 30 Optionally matches @racket[{~seq #,ntax-pattern ...}]. If the match fails, it 31 matches these same sequence of patterns against the empty syntax list 32 @racket[#'()]. This form can be used in an ellipsis-head position. This is 33 implemented in both cases as a "pre" action.} 34 35 @defform[#:kind "eh-mixin expander" 36 (~optional/else #,ntax-pattern 37 maybe-defaults 38 else-post-fail ... 39 maybe-name) 40 #:grammar 41 [(maybe-defaults (code:line) 42 (code:line #:defaults (default-binding ...))) 43 (else-post-fail 44 (code:line #:else-post-fail message #:when condition) 45 (code:line #:else-post-fail #:when condition message) 46 (code:line #:else-post-fail message #:unless unless-condition) 47 (code:line #:else-post-fail #:unless unless-condition message)) 48 (maybe-name (code:line) 49 (code:line #:name #,tribute-name))]]{ 50 Like @racket[~optional], but with conditional post-failures when the pattern is 51 not matched. An @racket[~optional/else] pattern can be matched zero or one time 52 as part of the @racket[~seq-no-order] or @racket[~no-order]. When it is not 53 matched (i.e. matched zero times): 54 @itemlist[ 55 @item{it uses the default values for the attributes as specified with 56 @racket[#:defaults].} 57 @item{for each @racket[#:else-post-fail] clause, it checks whether the 58 @racket[condition] or @racket[unless-condition] is true or false, 59 respectively. If this is the case the whole @racket[~seq-no-order] or 60 @racket[~no-order] is rejected with the given @racket[_message]. The 61 behaviour of @racket[#:else-post-fail] is the same as the behaviour of 62 @racket[~post-fail], except that the "post" conditional failure can only be 63 executed if the optional @racket[_syntax-pattern] was not matched. 64 65 Note that there is an implicit cut (@racket[~!]) between the no-order 66 patterns and the "post" checks, so after a @racket[~post-fail] fails, 67 @racket[syntax-parse] does not backtrack and attempt different combinations 68 of patterns to match the sequence, nor does it backtrack and attempt to match 69 a shorter sequence. This is by design, as it allows for better error messages 70 (syntax-parse would otherwise attempt and possibly succeed in matching a 71 shorter sequence, then just treat the remaining terms as 72 "unexpected terms").}] 73 74 The meaning of @racket[#:name #,tribute-name] option is the same as for 75 @racket[~optional].}