10
10
11
11
use ast;
12
12
use ext:: tt:: macro_parser;
13
- use parse:: { ParseSess , token } ;
13
+ use parse:: { token , ParseSess } ;
14
14
use print:: pprust;
15
15
use symbol:: keywords;
16
- use syntax_pos:: { DUMMY_SP , Span , BytePos } ;
16
+ use syntax_pos:: { BytePos , Span , DUMMY_SP } ;
17
17
use tokenstream;
18
18
19
19
use std:: rc:: Rc ;
@@ -68,7 +68,9 @@ pub struct SequenceRepetition {
68
68
/// for token sequences.
69
69
#[ derive( Clone , PartialEq , Eq , RustcEncodable , RustcDecodable , Hash , Debug , Copy ) ]
70
70
pub enum KleeneOp {
71
+ /// Kleene star (`*`) for zero or more repetitions
71
72
ZeroOrMore ,
73
+ /// Kleene star (`+`) for one or more repetitions
72
74
OneOrMore ,
73
75
}
74
76
@@ -83,7 +85,11 @@ pub enum TokenTree {
83
85
/// E.g. `$var`
84
86
MetaVar ( Span , ast:: Ident ) ,
85
87
/// E.g. `$var:expr`. This is only used in the left hand side of MBE macros.
86
- MetaVarDecl ( Span , ast:: Ident /* name to bind */ , ast:: Ident /* kind of nonterminal */ ) ,
88
+ MetaVarDecl (
89
+ Span ,
90
+ ast:: Ident , /* name to bind */
91
+ ast:: Ident , /* kind of nonterminal */
92
+ ) ,
87
93
}
88
94
89
95
impl TokenTree {
@@ -131,17 +137,20 @@ impl TokenTree {
131
137
/// Retrieve the `TokenTree`'s span.
132
138
pub fn span ( & self ) -> Span {
133
139
match * self {
134
- TokenTree :: Token ( sp, _) |
135
- TokenTree :: MetaVar ( sp, _) |
136
- TokenTree :: MetaVarDecl ( sp, _, _) |
137
- TokenTree :: Delimited ( sp, _) |
138
- TokenTree :: Sequence ( sp, _) => sp,
140
+ TokenTree :: Token ( sp, _)
141
+ | TokenTree :: MetaVar ( sp, _)
142
+ | TokenTree :: MetaVarDecl ( sp, _, _)
143
+ | TokenTree :: Delimited ( sp, _)
144
+ | TokenTree :: Sequence ( sp, _) => sp,
139
145
}
140
146
}
141
147
}
142
148
143
- pub fn parse ( input : tokenstream:: TokenStream , expect_matchers : bool , sess : & ParseSess )
144
- -> Vec < TokenTree > {
149
+ pub fn parse (
150
+ input : tokenstream:: TokenStream ,
151
+ expect_matchers : bool ,
152
+ sess : & ParseSess ,
153
+ ) -> Vec < TokenTree > {
145
154
let mut result = Vec :: new ( ) ;
146
155
let mut trees = input. trees ( ) ;
147
156
while let Some ( tree) = trees. next ( ) {
@@ -154,29 +163,39 @@ pub fn parse(input: tokenstream::TokenStream, expect_matchers: bool, sess: &Pars
154
163
Some ( kind) => {
155
164
let span = end_sp. with_lo ( start_sp. lo ( ) ) ;
156
165
result. push ( TokenTree :: MetaVarDecl ( span, ident, kind) ) ;
157
- continue
166
+ continue ;
158
167
}
159
168
_ => end_sp,
160
169
} ,
161
- tree => tree. as_ref ( ) . map ( tokenstream:: TokenTree :: span) . unwrap_or ( span) ,
170
+ tree => tree. as_ref ( )
171
+ . map ( tokenstream:: TokenTree :: span)
172
+ . unwrap_or ( span) ,
162
173
} ,
163
- tree => tree. as_ref ( ) . map ( tokenstream:: TokenTree :: span) . unwrap_or ( start_sp) ,
174
+ tree => tree. as_ref ( )
175
+ . map ( tokenstream:: TokenTree :: span)
176
+ . unwrap_or ( start_sp) ,
164
177
} ;
165
178
sess. missing_fragment_specifiers . borrow_mut ( ) . insert ( span) ;
166
- result. push ( TokenTree :: MetaVarDecl ( span, ident, keywords:: Invalid . ident ( ) ) ) ;
179
+ result. push ( TokenTree :: MetaVarDecl (
180
+ span,
181
+ ident,
182
+ keywords:: Invalid . ident ( ) ,
183
+ ) ) ;
167
184
}
168
185
_ => result. push ( tree) ,
169
186
}
170
187
}
171
188
result
172
189
}
173
190
174
- fn parse_tree < I > ( tree : tokenstream:: TokenTree ,
175
- trees : & mut I ,
176
- expect_matchers : bool ,
177
- sess : & ParseSess )
178
- -> TokenTree
179
- where I : Iterator < Item = tokenstream:: TokenTree > ,
191
+ fn parse_tree < I > (
192
+ tree : tokenstream:: TokenTree ,
193
+ trees : & mut I ,
194
+ expect_matchers : bool ,
195
+ sess : & ParseSess ,
196
+ ) -> TokenTree
197
+ where
198
+ I : Iterator < Item = tokenstream:: TokenTree > ,
180
199
{
181
200
match tree {
182
201
tokenstream:: TokenTree :: Token ( span, token:: Dollar ) => match trees. next ( ) {
@@ -189,43 +208,69 @@ fn parse_tree<I>(tree: tokenstream::TokenTree,
189
208
let sequence = parse ( delimited. tts . into ( ) , expect_matchers, sess) ;
190
209
let ( separator, op) = parse_sep_and_kleene_op ( trees, span, sess) ;
191
210
let name_captures = macro_parser:: count_names ( & sequence) ;
192
- TokenTree :: Sequence ( span, Rc :: new ( SequenceRepetition {
193
- tts : sequence,
194
- separator,
195
- op,
196
- num_captures : name_captures,
197
- } ) )
211
+ TokenTree :: Sequence (
212
+ span,
213
+ Rc :: new ( SequenceRepetition {
214
+ tts : sequence,
215
+ separator,
216
+ op,
217
+ num_captures : name_captures,
218
+ } ) ,
219
+ )
198
220
}
199
221
Some ( tokenstream:: TokenTree :: Token ( ident_span, ref token) ) if token. is_ident ( ) => {
200
222
let ident = token. ident ( ) . unwrap ( ) ;
201
223
let span = ident_span. with_lo ( span. lo ( ) ) ;
202
224
if ident. name == keywords:: Crate . name ( ) {
203
- let ident = ast:: Ident { name : keywords:: DollarCrate . name ( ) , ..ident } ;
225
+ let ident = ast:: Ident {
226
+ name : keywords:: DollarCrate . name ( ) ,
227
+ ..ident
228
+ } ;
204
229
TokenTree :: Token ( span, token:: Ident ( ident) )
205
230
} else {
206
231
TokenTree :: MetaVar ( span, ident)
207
232
}
208
233
}
209
234
Some ( tokenstream:: TokenTree :: Token ( span, tok) ) => {
210
- let msg = format ! ( "expected identifier, found `{}`" , pprust:: token_to_string( & tok) ) ;
235
+ let msg = format ! (
236
+ "expected identifier, found `{}`" ,
237
+ pprust:: token_to_string( & tok)
238
+ ) ;
211
239
sess. span_diagnostic . span_err ( span, & msg) ;
212
240
TokenTree :: MetaVar ( span, keywords:: Invalid . ident ( ) )
213
241
}
214
242
None => TokenTree :: Token ( span, token:: Dollar ) ,
215
243
} ,
216
244
tokenstream:: TokenTree :: Token ( span, tok) => TokenTree :: Token ( span, tok) ,
217
- tokenstream:: TokenTree :: Delimited ( span, delimited) => {
218
- TokenTree :: Delimited ( span, Rc :: new ( Delimited {
245
+ tokenstream:: TokenTree :: Delimited ( span, delimited) => TokenTree :: Delimited (
246
+ span,
247
+ Rc :: new ( Delimited {
219
248
delim : delimited. delim ,
220
249
tts : parse ( delimited. tts . into ( ) , expect_matchers, sess) ,
221
- } ) )
222
- }
250
+ } ) ,
251
+ ) ,
223
252
}
224
253
}
225
254
226
- fn parse_sep_and_kleene_op < I > ( input : & mut I , span : Span , sess : & ParseSess )
227
- -> ( Option < token:: Token > , KleeneOp )
228
- where I : Iterator < Item = tokenstream:: TokenTree > ,
255
+ /// Attempt to parse a single Kleene star, possibly with a separator.
256
+ ///
257
+ /// For example, in a pattern such as `$(a),*`, `a` is the pattern to be repeated, `,` is the
258
+ /// separator, and `*` is the Kleene operator. This function is specifically concerned with parsing
259
+ /// the last two tokens of such a pattern: namely, the optional separator and the Kleene operator
260
+ /// itself. Note that here we are parsing the _pattern_ itself, rather than trying to match some
261
+ /// stream of tokens against the pattern.
262
+ ///
263
+ /// This function will take some input iterator `input` corresponding to `span` and a parsing
264
+ /// session `sess`. If the next one (or possibly two) tokens in `input` correspond to a Kleene
265
+ /// operator and separator, then a tuple with `(separator, KleeneOp)` is returned. Otherwise, an
266
+ /// error with the appropriate span is emitted to `sess` and a dummy value is returned.
267
+ fn parse_sep_and_kleene_op < I > (
268
+ input : & mut I ,
269
+ span : Span ,
270
+ sess : & ParseSess ,
271
+ ) -> ( Option < token:: Token > , KleeneOp )
272
+ where
273
+ I : Iterator < Item = tokenstream:: TokenTree > ,
229
274
{
230
275
fn kleene_op ( token : & token:: Token ) -> Option < KleeneOp > {
231
276
match * token {
@@ -235,20 +280,40 @@ fn parse_sep_and_kleene_op<I>(input: &mut I, span: Span, sess: &ParseSess)
235
280
}
236
281
}
237
282
283
+ // We attempt to look at the next two token trees in `input`. I will call the first #1 and the
284
+ // second #2. If #1 and #2 don't match a valid KleeneOp with/without separator, that is an
285
+ // error, and we should emit an error on the most specific span possible.
238
286
let span = match input. next ( ) {
287
+ // #1 is a token
239
288
Some ( tokenstream:: TokenTree :: Token ( span, tok) ) => match kleene_op ( & tok) {
289
+ // #1 is a KleeneOp with no separator
240
290
Some ( op) => return ( None , op) ,
291
+
292
+ // #1 is not a KleeneOp, but may be a separator... need to look at #2
241
293
None => match input. next ( ) {
294
+ // #2 is a token
242
295
Some ( tokenstream:: TokenTree :: Token ( span, tok2) ) => match kleene_op ( & tok2) {
296
+ // #2 is a KleeneOp, so #1 must be a separator
243
297
Some ( op) => return ( Some ( tok) , op) ,
298
+
299
+ // #2 is not a KleeneOp... error
244
300
None => span,
245
301
} ,
246
- tree => tree. as_ref ( ) . map ( tokenstream:: TokenTree :: span) . unwrap_or ( span) ,
247
- }
302
+
303
+ // #2 is not a token at all... error
304
+ tree => tree. as_ref ( )
305
+ . map ( tokenstream:: TokenTree :: span)
306
+ . unwrap_or ( span) ,
307
+ } ,
248
308
} ,
249
- tree => tree. as_ref ( ) . map ( tokenstream:: TokenTree :: span) . unwrap_or ( span) ,
309
+
310
+ // #1 is not a token at all... error
311
+ tree => tree. as_ref ( )
312
+ . map ( tokenstream:: TokenTree :: span)
313
+ . unwrap_or ( span) ,
250
314
} ;
251
315
316
+ // Error...
252
317
sess. span_diagnostic . span_err ( span, "expected `*` or `+`" ) ;
253
318
( None , KleeneOp :: ZeroOrMore )
254
319
}
0 commit comments