1
1
# Macros By Example
2
2
3
+ > ** <sup >Syntax</sup >** \
4
+ > _ MacroRulesDefinition_ :\
5
+ >   ;  ; ` macro_rules ` ` ! ` [ IDENTIFIER] _ MacroRulesDef_
6
+ >
7
+ > _ MacroRulesDef_ :\
8
+ >   ;  ;   ;  ; ` ( ` _ MacroRules_ ` ) ` ` ; ` \
9
+ >   ;  ; | ` [ ` _ MacroRules_ ` ] ` ` ; ` \
10
+ >   ;  ; | ` { ` _ MacroRules_ ` } `
11
+ >
12
+ > _ MacroRules_ :\
13
+ >   ;  ; _ MacroRule_ ( ` ; ` _ MacroRule_ )<sup >\* </sup > ` ; ` <sup >?</sup >
14
+ >
15
+ > _ MacroRule_ :\
16
+ >   ;  ; _ MacroMatcher_ ` => ` _ MacroTranscriber_
17
+ >
18
+ > _ MacroMatcher_ :\
19
+ >   ;  ;   ;  ; ` ( ` _ MacroMatch_ <sup >\* </sup > ` ) ` \
20
+ >   ;  ; | ` [ ` _ MacroMatch_ <sup >\* </sup > ` ] ` \
21
+ >   ;  ; | ` { ` _ MacroMatch_ <sup >\* </sup > ` } `
22
+ >
23
+ > _ MacroMatch_ :\
24
+ >   ;  ;   ;  ; [ _ Token_ ] <sub >_ except $ and delimiters_ </sub >\
25
+ >   ;  ; | _ MacroMatcher_ \
26
+ >   ;  ; | ` $ ` [ IDENTIFIER] ` : ` _ MacroFragSpec_ \
27
+ >   ;  ; | ` $ ` ` ( ` _ MacroMatch_ <sup >+</sup > ` ) ` _ MacroRepSep_ <sup >?</sup > _ MacroKleeneOp_
28
+ >
29
+ > _ MacroFragSpec_ :\
30
+ >   ;  ;   ;  ; ` block ` | ` expr ` | ` ident ` | ` item ` | ` lifetime ` | ` literal ` \
31
+ >   ;  ; | ` meta ` | ` pat ` | ` path ` | ` stmt ` | ` tt ` | ` ty ` | ` vis `
32
+ >
33
+ > _ MacroRepSep_ :\
34
+ >   ;  ; [ _ Token_ ] <sub >_ except delimiters and kleene operators_ </sub >
35
+ >
36
+ > _ MacroKleeneOp_ <sub >2015</sub > :\
37
+ >   ;  ; ` * ` | ` + `
38
+ >
39
+ > _ MacroKleeneOp_ <sub >2018+</sub > :\
40
+ >   ;  ; ` * ` | ` + ` | ` ? `
41
+ >
42
+ > _ MacroTranscriber_ :\
43
+ >   ;  ; [ _ DelimTokenTree_ ]
44
+
3
45
` macro_rules ` allows users to define syntax extension in a declarative way. We
4
46
call such extensions "macros by example" or simply "macros".
5
47
6
- Currently, macros can expand to expressions, statements, items, or patterns.
7
-
8
- (A ` sep_token ` is any token other than ` * ` and ` + ` . A ` non_special_token ` is
9
- any token other than a delimiter or ` $ ` .)
48
+ Macros can expand to expressions, statements, items, types, or patterns.
10
49
11
50
The macro expander looks up macro invocations by name, and tries each macro
12
51
rule in turn. It transcribes the first successful match. Matching and
@@ -27,11 +66,11 @@ syntax named by _designator_. Valid designators are:
27
66
* ` expr ` : an [ expression]
28
67
* ` ty ` : a [ type]
29
68
* ` ident ` : an [ identifier] or [ keyword]
30
- * ` path ` : a [ path ]
31
- * ` tt ` : a token tree (a single [ token] by matching ` () ` , ` [] ` , or ` {} ` )
69
+ * ` path ` : a [ _ TypePath _ ] style path
70
+ * ` tt ` : a [ token tree] & nbsp ; (a single [ token] or tokens in matching delimiters ` () ` , ` [] ` , or ` {} ` )
32
71
* ` meta ` : the contents of an [ attribute]
33
- * ` lifetime ` : a lifetime. Examples: ` 'static ` , ` 'a ` .
34
- * ` vis ` : a ( visibility qualifier) [ visibility-and-privacy ]
72
+ * ` lifetime ` : a [ lifetime] . Examples: ` 'static ` , ` 'a ` .
73
+ * ` vis ` : a [ visibility qualifier]
35
74
36
75
[ item ] : items.html
37
76
[ block ] : expressions/block-expr.html
@@ -41,10 +80,12 @@ syntax named by _designator_. Valid designators are:
41
80
[ type ] : types.html
42
81
[ identifier ] : identifiers.html
43
82
[ keyword ] : keywords.html
44
- [ path ] : paths.html
83
+ [ _TypePath_ ] : paths.html#paths-in-types
84
+ [ token tree ] : macros.html#macro-invocation
45
85
[ token ] : tokens.html
46
86
[ attribute ] : attributes.html
47
- [ visibility-and-privacy ] : visibility-and-privacy.html
87
+ [ lifetime ] : tokens.html#lifetimes-and-loop-labels
88
+ [ visibility qualifier ] : visibility-and-privacy.html
48
89
49
90
In the transcriber, the
50
91
designator is already known, and so only the name of a matched nonterminal comes
@@ -94,9 +135,36 @@ Rust syntax is restricted in two ways:
94
135
a macro definition like ` $i:expr [ , ] ` is not legal, because ` [ ` could be part
95
136
of an expression. A macro definition like ` $i:expr, ` or ` $i:expr; ` would be legal,
96
137
however, because ` , ` and ` ; ` are legal separators. See [ RFC 550] for more information.
138
+ Specifically:
139
+
140
+ * ` expr ` and ` stmt ` may only be followed by one of ` => ` , ` , ` , or ` ; ` .
141
+ * ` pat ` may only be followed by one of ` => ` , ` , ` , ` = ` , ` | ` , ` if ` , or ` in ` .
142
+ * ` path ` and ` ty ` may only be followed by one of ` => ` , ` , ` , ` = ` , ` | ` , ` ; ` ,
143
+ ` : ` , ` > ` , ` [ ` , ` { ` , ` as ` , ` where ` , or a macro variable of ` block `
144
+ fragment type.
145
+ * ` vis ` may only be followed by one of ` , ` , ` priv ` , a raw identifier, any
146
+ token that can begin a type, or a macro variable of ` ident ` , ` ty ` , or
147
+ ` path ` fragment type.
148
+ * All other fragment types have no restrictions.
149
+
97
150
2 . The parser must have eliminated all ambiguity by the time it reaches a ` $ `
98
151
_ name_ ` : ` _ designator_ . This requirement most often affects name-designator
99
152
pairs when they occur at the beginning of, or immediately after, a ` $(...)* ` ;
100
- requiring a distinctive token in front can solve the problem.
153
+ requiring a distinctive token in front can solve the problem. For example:
154
+
155
+ ``` rust
156
+ // The matcher `$($i:ident)* $e:expr` would be ambiguous because the parser
157
+ // would be forced to choose between an identifier or an expression. Use some
158
+ // token to distinguish them.
159
+ macro_rules! example {
160
+ ($ (I $ i : ident )* E $ e : expr ) => { ($ ($ i )-* ) * $ e };
161
+ }
162
+ let foo = 2 ;
163
+ let bar = 3 ;
164
+ // The following expands to `(foo - bar) * 5`
165
+ example! (I foo I bar E 5 );
166
+ ```
101
167
102
168
[ RFC 550 ] : https://github.com/rust-lang/rfcs/blob/master/text/0550-macro-future-proofing.md
169
+ [ _DelimTokenTree_ ] : macros.html
170
+ [ _Token_ ] : tokens.html
0 commit comments