1.7 Literal Sets and Conventions
Sometimes the same literals are recognized in a number of different
places. The most common example is the literals for fully expanded
programs, which are used in many analysis and transformation
tools. Specifying literals individually is burdensome and error-prone.
As a remedy, syntax/parse offers literal
sets. A literal set is defined via define-literal-set and
used via the #:literal-set option of syntax-parse.
|  | 
|  | 
| | literal |  | = |  | literal-id |  |  |  | | |  | (pattern-id literal-id) |  |  |  |  |  |  |  | maybe-phase |  | = |  |  |  |  |  | | |  | #:for-template |  |  |  | | |  | #:for-syntax |  |  |  | | |  | #:for-label |  |  |  | | |  | #:phase phase-level |  |  |  |  |  |  |  | maybe-datum-literals |  | = |  |  |  |  |  | | |  | #:datum-literals (datum-literal ...) |  |  |  |  |  |  |  | maybe-imports |  | = |  |  |  |  |  | | |  | #:literal-sets (imported-litset-id ...) | 
 | 
Defines 
id as a 
literal set. Each 
literal can
have a separate 
pattern-id and 
literal-id. The
pattern-id determines what identifiers in the pattern are
treated as literals. The 
literal-id determines what
identifiers the literal matches. If the 
#:literal-sets option
is present, the contents of the given 
imported-litset-ids are
included.
The literals in a literal set always refer to the bindings at phase
phase-level relative to the enclosing module. If the
#:for-template option is given, phase-level is
-1; #:for-syntax means 1, and
#:for-label means #f. If no phase keyword option is
given, then phase-level is 0.
For example:
In the literal set common-lits, the literal x always
recognizes identifiers bound to the variable x defined in
module 'common.
The following module defines an equivalent literal set, but imports
the 'common module for-template instead:
When a literal set is used with the #:phase phase-expr
option, the literals’ fixed bindings are compared against the binding of
the input literal at the specified phase. Continuing the example:
The occurrence of x in the pattern matches any identifier
whose binding at phase 1 is the x from module
'common.
Given the name of a literal set, produces a predicate that recognizes
identifiers in the literal set. The predicate takes one required
argument, an identifier 
id, and one optional argument, the
phase 
phase at which to examine the binding of 
id;
the 
phase argument defaults to
(syntax-local-phase-level).
| (define-conventions name-id convention-rule ...)
 | 
|  | 
| | convention-rule |  | = |  | (name-pattern syntax-class) |  |  |  |  |  |  |  | name-pattern |  | = |  | exact-id |  |  |  | | |  | name-rx |  |  |  |  |  |  |  | syntax-class |  | = |  | syntax-class-id |  |  |  | | |  | (syntax-class-id expr ...) | 
 | 
Defines 
conventions that supply default syntax classes for
pattern variables. A pattern variable that has no explicit syntax
class is checked against each 
name-pattern, and the first one
that matches determines the syntax class for the pattern. If no
name-pattern matches, then the pattern variable has no syntax
class.
| Examples: | 
| |  |  |  |  | '(a b c) |  |  |  |  |  | '(a (b c) 1 (2 3)) | 
 | 
Local conventions, introduced with the #:local-conventions
keyword argument of syntax-parse and syntax class
definitions, may refer to local bindings:
| Examples: | 
| |  |  |  |  | | > (define (parse-natlist> bound x) |  | (syntax-parse x |  | #:local-conventions ([NS (natlist> bound)]) |  | [NS 'ok])) | 
 |  | > (parse-natlist> 0 #'(1 2 3)) |  | 'ok |  | > (parse-natlist> 5 #'(8 6 4 2)) |  | ?: expected number > 5 |  |   at: 4 |  |   in: (8 6 4 2) |  |   parsing context:  |  |    while parsing nat> |  |     term: 4 |  |     location: eval:21.0 |  |    while parsing natlist> |  |     term: (8 6 4 2) |  |     location: eval:21.0 | 
 |