This section describes syntax-parse , the syntax/parse library’s facility for parsing syntax. Both syntax-parse and the specification facility, syntax classes, use a common language of syntax patterns, which is described in detail in Syntax Patterns.
Two parsing forms are provided: syntax-parse and syntax-parser .
syntax
( syntax-parse stx-exprparse-option...clause...+)
parse-option = #:contextcontext-expr| #:literals(literal...)| #:datum-literals(datum-literal...)| #:literal-sets(literal-set...)| #:track-literals| #:conventions(convention-id...)| #:local-conventions(convention-rule...)| #:disable-colon-notationliteral = literal-id| (pattern-idliteral-id)| (pattern-idliteral-id#:phasephase-expr)datum-literal = literal-id| (pattern-idliteral-id)literal-set = literal-set-id| (literal-set-idliteral-set-option...)literal-set-option = #:atcontext-id| #:phasephase-exprclause = (syntax-patternpattern-directive...body...+)
Each clause consists of a syntax pattern, an optional sequence of pattern directives, and a non-empty sequence of body forms.
If the syntax object fails to match any of the patterns (or all matches fail the corresponding clauses’ side conditions), a syntax error is raised.
The following options are supported:
#:contextcontext-exprWhen present, context-expr is used in reporting parse failures; otherwise stx-expr is used. If context-expr evaluates to (list whocontext-stx), then who appears in the error message as the form raising the error, and context-stx is used as the term. If context-expr evaluates to a symbol, it is used as who and stx-expr (the syntax to be destructured) is used as context-stx. If context-expr evaluates to a syntax object, it is used as context-stx and who is inferred as with raise-syntax-error .
The current-syntax-context parameter is also set to the syntax object context-stx.
Examples:a: expected identifier
at: 3
in: (a b 3)
lambda: expected identifier
at: 3
in: (lambda (a b 3) (+ a b))
check-id-list: expected identifier
at: 3
in: (a b 3)
#:literals(literal...)literal = literal-id| (pattern-idliteral-id)| (pattern-idliteral-id#:phasephase-expr)Unlike syntax-case , syntax-parse requires all literals to have a binding. To match identifiers by their symbolic names, use #:datum-literals or the ~datum pattern form instead. The #:literals option specifies identifiers that should be treated as literals rather than pattern variables. An entry in the literals list has two components: the identifier used within the pattern to signify the positions to be matched (pattern-id), and the identifier expected to occur in those positions (literal-id). If the entry is a single identifier, that identifier is used for both purposes.
If the #:phase option is given, then the literal is compared at phase phase-expr. Specifically, the binding of the literal-id at phase phase-expr must match the input’s binding at phase phase-expr.
In other words, the syntax-patterns are interpreted as if each occurrence of pattern-id were replaced with the following pattern:(~literal literal-id#:phasephase-expr)
#:datum-literals(datum-literal...)datum-literal = literal-id| (pattern-idliteral-id)Like #:literals, but the literals are matched as symbols instead of as identifiers.
In other words, the syntax-patterns are interpreted as if each occurrence of pattern-id were replaced with the following pattern:(~datum literal-id)
#:literal-sets(literal-set...)literal-set = literal-set-id| (literal-set-idliteral-set-option...)literal-set-option = #:atlctx| #:phasephase-exprMany literals can be declared at once via one or more literal sets, imported with the #:literal-sets option. See literal sets for more information.
If the #:at keyword is given, the lexical context of the lctx term is used to determine which identifiers in the patterns are treated as literals; this option is useful primarily for macros that generate syntax-parse expressions.
#:track-literalsIf specified, each final body expression is further constrained to produce a single value, which must be a syntax object, and its 'disappeared-use syntax property is automatically extended to include literals matched as part of pattern-matching. Literals are automatically tracked from uses of #:literals, #:literal-sets, or ~literal , but they can also be manually tracked using syntax-parse-state-cons! . The property is added or extended in the same way as a property added by syntax-parse-track-literals .
Due to the way the body forms are wrapped, specifying this option means the final body form will no longer be in tail position with respect to the enclosing syntax-parse form.
Added in version 6.90.0.29 of package base.
#:conventions(conventions-id...)Imports conventions that give default syntax classes to pattern variables that do not explicitly specify a syntax class.
#:local-conventions(convention-rule...)Uses the conventions specified. The advantage of #:local-conventions over #:conventions is that local conventions can be in the scope of syntax-class parameter bindings. See the section on conventions for examples.
#:disable-colon-notationSuppresses the “colon notation” for annotated pattern variables.
Examples:syntax-parse: not defined as syntax class
at: y
in: (syntax-parse (syntax (a b c)) ((x:y ...) (quote ok)))
'ok
syntax
( syntax-parser parse-option...clause...+)
syntax
( define/syntax-parse syntax-patternpattern-directive...stx-expr)
stx-expr : syntax?
#'(#:a1#:b2#:c3))#<syntax:eval:7:0 (#:a #:b #:c)>
Compare with define/with-syntax , a similar definition form that uses the simpler syntax-case patterns.