11# Macros By Example
22
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 ` \
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+
345` macro_rules ` allows users to define syntax extension in a declarative way. We
446call such extensions "macros by example" or simply "macros".
547
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.
1049
1150The macro expander looks up macro invocations by name, and tries each macro
1251rule in turn. It transcribes the first successful match. Matching and
@@ -20,31 +59,32 @@ balanced, but they are otherwise not special.
2059In the matcher, ` $ ` _ name_ ` : ` _ designator_ matches the nonterminal in the Rust
2160syntax named by _ designator_ . Valid designators are:
2261
23- * ` item ` : an [ item]
24- * ` block ` : a [ block]
25- * ` stmt ` : a [ statement]
26- * ` pat ` : a [ pattern]
27- * ` expr ` : an [ expression]
28- * ` ty ` : a [ type]
29- * ` ident ` : an [ identifier] or [ keyword]
30- * ` path ` : a [ path]
31- * ` tt ` : a token tree (a single [ token] by matching ` () ` , ` [] ` , or ` {} ` )
32- * ` meta ` : the contents of an [ attribute]
33- * ` lifetime ` : a lifetime. Examples: ` 'static ` , ` 'a ` .
34- * ` vis ` : a (visibility qualifier)[ visibility-and-privacy]
35-
36- [ item ] : items.html
37- [ block ] : expressions/block-expr.html
38- [ statement ] : statements.html
39- [ pattern ] : patterns.html
40- [ expression ] : expressions.html
41- [ type ] : types.html
42- [ identifier ] : identifiers.html
43- [ keyword ] : keywords.html
44- [ path ] : paths.html
62+ * ` item ` : an [ _ Item_ ]
63+ * ` block ` : a [ _ BlockExpression_ ]
64+ * ` stmt ` : a [ _ Statement_ ] without the trailing semicolon
65+ * ` pat ` : a [ _ Pattern_ ]
66+ * ` expr ` : an [ _ Expression_ ]
67+ * ` ty ` : a [ _ Type_ ]
68+ * ` ident ` : an [ IDENTIFIER_OR_KEYWORD]
69+ * ` path ` : a [ _ TypePath_ ] style path
70+ * ` tt ` : a [ _ TokenTree_ ]   ; (a single [ token] or tokens in matching delimiters ` () ` , ` [] ` , or ` {} ` )
71+ * ` meta ` : a [ _ MetaItem_ ] , the contents of an attribute
72+ * ` lifetime ` : a [ LIFETIME_TOKEN]
73+ * ` vis ` : a [ _ Visibility_ ] qualifier
74+
75+ [ IDENTIFIER_OR_KEYWORD ] : identifiers.html
76+ [ LIFETIME_TOKEN ] : tokens.html#lifetimes-and-loop-labels
77+ [ _BlockExpression_ ] : expressions/block-expr.html
78+ [ _Expression_ ] : expressions.html
79+ [ _Item_ ] : items.html
80+ [ _MetaItem_ ] : attributes.html
81+ [ _Pattern_ ] : patterns.html
82+ [ _Statement_ ] : statements.html
83+ [ _TokenTree_ ] : macros.html#macro-invocation
84+ [ _TypePath_ ] : paths.html#paths-in-types
85+ [ _Type_ ] : types.html
86+ [ _Visibility_ ] : visibility-and-privacy.html
4587[ token ] : tokens.html
46- [ attribute ] : attributes.html
47- [ visibility-and-privacy ] : visibility-and-privacy.html
4888
4989In the transcriber, the
5090designator is already known, and so only the name of a matched nonterminal comes
@@ -94,9 +134,36 @@ Rust syntax is restricted in two ways:
94134 a macro definition like ` $i:expr [ , ] ` is not legal, because ` [ ` could be part
95135 of an expression. A macro definition like ` $i:expr, ` or ` $i:expr; ` would be legal,
96136 however, because ` , ` and ` ; ` are legal separators. See [ RFC 550] for more information.
137+ Specifically:
138+
139+ * ` expr ` and ` stmt ` may only be followed by one of ` => ` , ` , ` , or ` ; ` .
140+ * ` pat ` may only be followed by one of ` => ` , ` , ` , ` = ` , ` | ` , ` if ` , or ` in ` .
141+ * ` path ` and ` ty ` may only be followed by one of ` => ` , ` , ` , ` = ` , ` | ` , ` ; ` ,
142+ ` : ` , ` > ` , ` >> ` , ` [ ` , ` { ` , ` as ` , ` where ` , or a macro variable of ` block `
143+ fragment type.
144+ * ` vis ` may only be followed by one of ` , ` , ` priv ` , a raw identifier, any
145+ token that can begin a type, or a macro variable of ` ident ` , ` ty ` , or
146+ ` path ` fragment type.
147+ * All other fragment types have no restrictions.
148+
971492 . The parser must have eliminated all ambiguity by the time it reaches a ` $ `
98150 _ name_ ` : ` _ designator_ . This requirement most often affects name-designator
99151 pairs when they occur at the beginning of, or immediately after, a ` $(...)* ` ;
100- requiring a distinctive token in front can solve the problem.
152+ requiring a distinctive token in front can solve the problem. For example:
153+
154+ ``` rust
155+ // The matcher `$($i:ident)* $e:expr` would be ambiguous because the parser
156+ // would be forced to choose between an identifier or an expression. Use some
157+ // token to distinguish them.
158+ macro_rules! example {
159+ ($ (I $ i : ident )* E $ e : expr ) => { ($ ($ i )-* ) * $ e };
160+ }
161+ let foo = 2 ;
162+ let bar = 3 ;
163+ // The following expands to `(foo - bar) * 5`
164+ example! (I foo I bar E 5 );
165+ ```
101166
102167[ RFC 550 ] : https://github.com/rust-lang/rfcs/blob/master/text/0550-macro-future-proofing.md
168+ [ _DelimTokenTree_ ] : macros.html
169+ [ _Token_ ] : tokens.html
0 commit comments