Skip to content

Commit 34c92dd

Browse files
Merge pull request rust-lang#458 from ehuss/grammar-macro
Grammar: macros
2 parents 803412c + 3e7bb14 commit 34c92dd

9 files changed

+226
-42
lines changed

src/expressions.md

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
>       | [_BreakExpression_]\
2727
>       | [_RangeExpression_]\
2828
>       | [_ReturnExpression_]\
29+
>       | [_MacroInvocation_]\
2930
>    )
3031
>
3132
> _ExpressionWithBlock_ :\
@@ -341,6 +342,7 @@ They are never allowed before:
341342
[_LazyBooleanExpression_]: expressions/operator-expr.html#lazy-boolean-operators
342343
[_LiteralExpression_]: expressions/literal-expr.html
343344
[_LoopExpression_]: expressions/loop-expr.html
345+
[_MacroInvocation_]: macros.html#macro-invocation
344346
[_MatchExpression_]: expressions/match-expr.html
345347
[_MethodCallExpression_]: expressions/method-call-expr.html
346348
[_OperatorExpression_]: expressions/operator-expr.html

src/items.md

+13-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
> **<sup>Syntax:<sup>**\
44
> _Item_:\
5-
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> [_Visibility_]<sup>?</sup>\
5+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>\
6+
> &nbsp;&nbsp; &nbsp;&nbsp; _VisItem_\
7+
> &nbsp;&nbsp; | _MacroItem_
8+
>
9+
> _VisItem_:\
10+
> &nbsp;&nbsp; [_Visibility_]<sup>?</sup>\
611
> &nbsp;&nbsp; (\
712
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_Module_]\
813
> &nbsp;&nbsp; &nbsp;&nbsp; | [_ExternCrate_]\
@@ -17,9 +22,12 @@
1722
> &nbsp;&nbsp; &nbsp;&nbsp; | [_Trait_]\
1823
> &nbsp;&nbsp; &nbsp;&nbsp; | [_Implementation_]\
1924
> &nbsp;&nbsp; &nbsp;&nbsp; | [_ExternBlock_]\
20-
> &nbsp;&nbsp; &nbsp;&nbsp; | _Macro_\
21-
> &nbsp;&nbsp; &nbsp;&nbsp; | _MacroDefinition_\
2225
> &nbsp;&nbsp; )
26+
>
27+
> _MacroItem_:\
28+
> &nbsp;&nbsp; &nbsp;&nbsp; [_MacroInvocationSemi_]\
29+
> &nbsp;&nbsp; | [_MacroRulesDefinition_]
30+
2331

2432
An _item_ is a component of a crate. Items are organized within a crate by a
2533
nested set of [modules]. Every crate has a single "outermost" anonymous module;
@@ -61,6 +69,8 @@ which sub-item declarations may appear.
6169
[_ExternCrate_]: items/extern-crates.html
6270
[_Function_]: items/functions.html
6371
[_Implementation_]: items/implementations.html
72+
[_MacroInvocationSemi_]: macros.html#macro-invocation
73+
[_MacroRulesDefinition_]: macros-by-example.html
6474
[_Module_]: items/modules.html
6575
[_OuterAttribute_]: attributes.html
6676
[_StaticItem_]: items/static-items.html

src/items/implementations.md

+9-6
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111
> &nbsp;&nbsp; `}`
1212
>
1313
> _InherentImplItem_ :\
14-
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>\
15-
> &nbsp;&nbsp; [_Visibility_]<sup>?</sup>\
16-
> &nbsp;&nbsp; ( [_ConstantItem_] | [_Function_] | [_Method_] )
14+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> (\
15+
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_MacroInvocationSemi_]\
16+
> &nbsp;&nbsp; &nbsp;&nbsp; | ( [_Visibility_]<sup>?</sup> ( [_ConstantItem_] | [_Function_] | [_Method_] ) )\
17+
> &nbsp;&nbsp; )
1718
>
1819
> _TraitImpl_ :\
1920
> &nbsp;&nbsp; `unsafe`<sup>?</sup> `impl` [_Generics_] `!`<sup>?</sup>
@@ -25,9 +26,10 @@
2526
> &nbsp;&nbsp; `}`
2627
>
2728
> _TraitImplItem_ :\
28-
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>\
29-
> &nbsp;&nbsp; [_Visibility_]<sup>?</sup>\
30-
> &nbsp;&nbsp; ( [_TypeAlias_] | [_ConstantItem_] | [_Function_] | [_Method_] )
29+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> (\
30+
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_MacroInvocationSemi_]\
31+
> &nbsp;&nbsp; &nbsp;&nbsp; | ( [_Visibility_]<sup>?</sup> ( [_TypeAlias_] | [_ConstantItem_] | [_Function_] | [_Method_] ) )\
32+
> &nbsp;&nbsp; )
3133
3234
An _implementation_ is an item that associates items with an _implementing type_.
3335
Implementations are defined with the keyword `impl` and contain functions
@@ -180,6 +182,7 @@ attributes].
180182
[_Function_]: items/functions.html
181183
[_Generics_]: items/generics.html
182184
[_InnerAttribute_]: attributes.html
185+
[_MacroInvocationSemi_]: macros.html#macro-invocation
183186
[_Method_]: items/associated-items.html#methods
184187
[_OuterAttribute_]: attributes.html
185188
[_TypeAlias_]: items/type-aliases.html

src/items/traits.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99
> &nbsp;&nbsp; `}`
1010
>
1111
> _TraitItem_ :\
12-
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> (_TraitFunc_ | _TraitMethod_ | _TraitConst_ | _TraitType_)
12+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> (\
13+
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; _TraitFunc_\
14+
> &nbsp;&nbsp; &nbsp;&nbsp; | _TraitMethod_\
15+
> &nbsp;&nbsp; &nbsp;&nbsp; | _TraitConst_\
16+
> &nbsp;&nbsp; &nbsp;&nbsp; | _TraitType_\
17+
> &nbsp;&nbsp; &nbsp;&nbsp; | [_MacroInvocationSemi_]\
18+
> &nbsp;&nbsp; )
1319
>
1420
> _TraitFunc_ :\
1521
> &nbsp;&nbsp; &nbsp;&nbsp; _TraitFunctionDecl_ ( `;` | [_BlockExpression_] )
@@ -205,6 +211,7 @@ trait T {
205211
[_FunctionQualifiers_]: items/functions.html
206212
[_FunctionReturnType_]: items/functions.html
207213
[_Generics_]: items/generics.html
214+
[_MacroInvocationSemi_]: macros.html#macro-invocation
208215
[_OuterAttribute_]: attributes.html
209216
[_Pattern_]: patterns.html
210217
[_SelfParam_]: items/associated-items.html#methods

src/macros-by-example.md

+96-29
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,51 @@
11
# Macros By Example
22

3+
> **<sup>Syntax</sup>**\
4+
> _MacroRulesDefinition_ :\
5+
> &nbsp;&nbsp; `macro_rules` `!` [IDENTIFIER] _MacroRulesDef_
6+
>
7+
> _MacroRulesDef_ :\
8+
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _MacroRules_ `)` `;`\
9+
> &nbsp;&nbsp; | `[` _MacroRules_ `]` `;`\
10+
> &nbsp;&nbsp; | `{` _MacroRules_ `}`
11+
>
12+
> _MacroRules_ :\
13+
> &nbsp;&nbsp; _MacroRule_ ( `;` _MacroRule_ )<sup>\*</sup> `;`<sup>?</sup>
14+
>
15+
> _MacroRule_ :\
16+
> &nbsp;&nbsp; _MacroMatcher_ `=>` _MacroTranscriber_
17+
>
18+
> _MacroMatcher_ :\
19+
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _MacroMatch_<sup>\*</sup> `)`\
20+
> &nbsp;&nbsp; | `[` _MacroMatch_<sup>\*</sup> `]`\
21+
> &nbsp;&nbsp; | `{` _MacroMatch_<sup>\*</sup> `}`
22+
>
23+
> _MacroMatch_ :\
24+
> &nbsp;&nbsp; &nbsp;&nbsp; [_Token_]<sub>_except $ and delimiters_</sub>\
25+
> &nbsp;&nbsp; | _MacroMatcher_\
26+
> &nbsp;&nbsp; | `$` [IDENTIFIER] `:` _MacroFragSpec_\
27+
> &nbsp;&nbsp; | `$` `(` _MacroMatch_<sup>+</sup> `)` _MacroRepSep_<sup>?</sup> _MacroKleeneOp_
28+
>
29+
> _MacroFragSpec_ :\
30+
> &nbsp;&nbsp; &nbsp;&nbsp; `block` | `expr` | `ident` | `item` | `lifetime`\
31+
> &nbsp;&nbsp; | `meta` | `pat` | `path` | `stmt` | `tt` | `ty` | `vis`
32+
>
33+
> _MacroRepSep_ :\
34+
> &nbsp;&nbsp; [_Token_]<sub>_except delimiters and kleene operators_</sub>
35+
>
36+
> _MacroKleeneOp_<sub>2015</sub> :\
37+
> &nbsp;&nbsp; `*` | `+`
38+
>
39+
> _MacroKleeneOp_<sub>2018+</sub> :\
40+
> &nbsp;&nbsp; `*` | `+` | `?`
41+
>
42+
> _MacroTranscriber_ :\
43+
> &nbsp;&nbsp; [_DelimTokenTree_]
44+
345
`macro_rules` allows users to define syntax extension in a declarative way. We
446
call 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

1150
The macro expander looks up macro invocations by name, and tries each macro
1251
rule in turn. It transcribes the first successful match. Matching and
@@ -20,31 +59,32 @@ balanced, but they are otherwise not special.
2059
In the matcher, `$` _name_ `:` _designator_ matches the nonterminal in the Rust
2160
syntax 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_]&nbsp;(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

4989
In the transcriber, the
5090
designator 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+
97149
2. 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

src/macros.md

+89
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,95 @@ There are two ways to define new macros:
99
* [Macros by Example] define new syntax in a higher-level, declarative way.
1010
* [Procedural Macros] can be used to implement custom derive.
1111

12+
## Macro Invocation
13+
14+
> **<sup>Syntax</sup>**\
15+
> _MacroInvocation_ :\
16+
> &nbsp;&nbsp; [_SimplePath_] `!` _DelimTokenTree_
17+
>
18+
> _DelimTokenTree_ :\
19+
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _TokenTree_<sup>\*</sup> `)`\
20+
> &nbsp;&nbsp; | `[` _TokenTree_<sup>\*</sup> `]`\
21+
> &nbsp;&nbsp; | `{` _TokenTree_<sup>\*</sup> `}`
22+
>
23+
> _TokenTree_ :\
24+
> &nbsp;&nbsp; [_Token_]<sub>_except delimiters_</sub> | _DelimTokenTree_
25+
>
26+
> _MacroInvocationSemi_ :\
27+
> &nbsp;&nbsp; &nbsp;&nbsp; [_SimplePath_] `!` `(` _TokenTree_<sup>\*</sup> `)` `;`\
28+
> &nbsp;&nbsp; | [_SimplePath_] `!` `[` _TokenTree_<sup>\*</sup> `]` `;`\
29+
> &nbsp;&nbsp; | [_SimplePath_] `!` `{` _TokenTree_<sup>\*</sup> `}`
30+
31+
A macro invocation executes a macro at compile time and replaces the
32+
invocation with the result of the macro. Macros may be invoked in the
33+
following situations:
34+
35+
* [Expressions] and [statements]
36+
* [Patterns]
37+
* [Types]
38+
* [Items] including [associated items]
39+
* [`macro_rules`] transcribers
40+
41+
When used as an item or a statement, the _MacroInvocationSemi_ form is used
42+
where a semicolon is required at the end when not using curly braces.
43+
[Visibility qualifiers] are never allowed before a macro invocation or
44+
[`macro_rules`] definition.
45+
46+
```rust
47+
// Used as an expression.
48+
let x = vec![1,2,3];
49+
50+
// Used as a statement.
51+
println!("Hello!");
52+
53+
// Used in a pattern.
54+
macro_rules! pat {
55+
($i:ident) => (Some($i))
56+
}
57+
58+
if let pat!(x) = Some(1) {
59+
assert_eq!(x, 1);
60+
}
61+
62+
// Used in a type.
63+
macro_rules! Tuple {
64+
{ $A:ty, $B:ty } => { ($A, $B) };
65+
}
66+
67+
type N2 = Tuple!(i32, i32);
68+
69+
// Used as an item.
70+
# use std::cell::RefCell;
71+
thread_local!(static FOO: RefCell<u32> = RefCell::new(1));
72+
73+
// Used as an associated item.
74+
macro_rules! const_maker {
75+
($t:ty, $v:tt) => { const CONST: $t = $v; };
76+
}
77+
trait T {
78+
const_maker!{i32, 7}
79+
}
80+
81+
// Macro calls within macros.
82+
macro_rules! example {
83+
() => { println!("Macro call in a macro!") };
84+
}
85+
// Outer macro `example` is expanded, then inner macro `println` is expanded.
86+
example!();
87+
```
88+
1289
[Macros by Example]: macros-by-example.html
1390
[Procedural Macros]: procedural-macros.html
91+
[_SimplePath_]: paths.html#simple-paths
92+
[_Token_]: tokens.html
93+
[associated items]: items/associated-items.html
1494
[compiler plugins]: ../unstable-book/language-features/plugin.html
95+
[delimiters]: tokens.html#delimiters
96+
[expressions]: expressions.html
97+
[items]: items.html
98+
[`macro_rules`]: macros-by-example.html
99+
[patterns]: patterns.html
100+
[statements]: statements.html
101+
[tokens]: tokens.html
102+
[types]: types.html
103+
[visibility qualifiers]: visibility-and-privacy.html

src/patterns.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
> &nbsp;&nbsp; | [_TuplePattern_]\
1313
> &nbsp;&nbsp; | [_GroupedPattern_]\
1414
> &nbsp;&nbsp; | [_SlicePattern_]\
15-
> &nbsp;&nbsp; | [_PathPattern_]
15+
> &nbsp;&nbsp; | [_PathPattern_]\
16+
> &nbsp;&nbsp; | [_MacroInvocation_]
1617
1718
Patterns are used to match values against structures and to,
1819
optionally, bind variables to values inside these structures. They are also
@@ -653,6 +654,7 @@ refer to refutable constants or enum variants for enums with multiple variants.
653654
[_GroupedPattern_]: #grouped-patterns
654655
[_IdentifierPattern_]: #identifier-patterns
655656
[_LiteralPattern_]: #literal-patterns
657+
[_MacroInvocation_]: macros.html#macro-invocation
656658
[_PathInExpression_]: paths.html#paths-in-expressions
657659
[_PathPattern_]: #path-patterns
658660
[_Pattern_]: #patterns

src/statements.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
> &nbsp;&nbsp; &nbsp;&nbsp; `;`\
66
> &nbsp;&nbsp; | [_Item_]\
77
> &nbsp;&nbsp; | [_LetStatement_]\
8-
> &nbsp;&nbsp; | [_ExpressionStatement_]
8+
> &nbsp;&nbsp; | [_ExpressionStatement_]\
9+
> &nbsp;&nbsp; | [_MacroInvocationSemi_]
910
1011

1112
A *statement* is a component of a [block], which is in turn a component of an
@@ -130,6 +131,7 @@ statement are [`cfg`], and [the lint check attributes].
130131
[_Expression_]: expressions.html
131132
[_Item_]: items.html
132133
[_LetStatement_]: #let-statements
134+
[_MacroInvocationSemi_]: macros.html#macro-invocation
133135
[_OuterAttribute_]: attributes.html
134136
[_Pattern_]: patterns.html
135137
[_Type_]: types.html

0 commit comments

Comments
 (0)