1010
1111use ast;
1212use ext:: tt:: macro_parser;
13- use parse:: { ParseSess , token } ;
13+ use parse:: { token , ParseSess } ;
1414use print:: pprust;
1515use symbol:: keywords;
16- use syntax_pos:: { DUMMY_SP , Span , BytePos } ;
16+ use syntax_pos:: { BytePos , Span , DUMMY_SP } ;
1717use tokenstream;
1818
1919use std:: rc:: Rc ;
@@ -68,7 +68,9 @@ pub struct SequenceRepetition {
6868/// for token sequences.
6969#[ derive( Clone , PartialEq , Eq , RustcEncodable , RustcDecodable , Hash , Debug , Copy ) ]
7070pub enum KleeneOp {
71+ /// Kleene star (`*`) for zero or more repetitions
7172 ZeroOrMore ,
73+ /// Kleene star (`+`) for one or more repetitions
7274 OneOrMore ,
7375}
7476
@@ -83,7 +85,11 @@ pub enum TokenTree {
8385 /// E.g. `$var`
8486 MetaVar ( Span , ast:: Ident ) ,
8587 /// 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+ ) ,
8793}
8894
8995impl TokenTree {
@@ -131,17 +137,20 @@ impl TokenTree {
131137 /// Retrieve the `TokenTree`'s span.
132138 pub fn span ( & self ) -> Span {
133139 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,
139145 }
140146 }
141147}
142148
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 > {
145154 let mut result = Vec :: new ( ) ;
146155 let mut trees = input. trees ( ) ;
147156 while let Some ( tree) = trees. next ( ) {
@@ -154,29 +163,39 @@ pub fn parse(input: tokenstream::TokenStream, expect_matchers: bool, sess: &Pars
154163 Some ( kind) => {
155164 let span = end_sp. with_lo ( start_sp. lo ( ) ) ;
156165 result. push ( TokenTree :: MetaVarDecl ( span, ident, kind) ) ;
157- continue
166+ continue ;
158167 }
159168 _ => end_sp,
160169 } ,
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) ,
162173 } ,
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) ,
164177 } ;
165178 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+ ) ) ;
167184 }
168185 _ => result. push ( tree) ,
169186 }
170187 }
171188 result
172189}
173190
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 > ,
180199{
181200 match tree {
182201 tokenstream:: TokenTree :: Token ( span, token:: Dollar ) => match trees. next ( ) {
@@ -189,43 +208,69 @@ fn parse_tree<I>(tree: tokenstream::TokenTree,
189208 let sequence = parse ( delimited. tts . into ( ) , expect_matchers, sess) ;
190209 let ( separator, op) = parse_sep_and_kleene_op ( trees, span, sess) ;
191210 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+ )
198220 }
199221 Some ( tokenstream:: TokenTree :: Token ( ident_span, ref token) ) if token. is_ident ( ) => {
200222 let ident = token. ident ( ) . unwrap ( ) ;
201223 let span = ident_span. with_lo ( span. lo ( ) ) ;
202224 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+ } ;
204229 TokenTree :: Token ( span, token:: Ident ( ident) )
205230 } else {
206231 TokenTree :: MetaVar ( span, ident)
207232 }
208233 }
209234 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+ ) ;
211239 sess. span_diagnostic . span_err ( span, & msg) ;
212240 TokenTree :: MetaVar ( span, keywords:: Invalid . ident ( ) )
213241 }
214242 None => TokenTree :: Token ( span, token:: Dollar ) ,
215243 } ,
216244 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 {
219248 delim : delimited. delim ,
220249 tts : parse ( delimited. tts . into ( ) , expect_matchers, sess) ,
221- } ) )
222- }
250+ } ) ,
251+ ) ,
223252 }
224253}
225254
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 > ,
229274{
230275 fn kleene_op ( token : & token:: Token ) -> Option < KleeneOp > {
231276 match * token {
@@ -235,20 +280,40 @@ fn parse_sep_and_kleene_op<I>(input: &mut I, span: Span, sess: &ParseSess)
235280 }
236281 }
237282
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.
238286 let span = match input. next ( ) {
287+ // #1 is a token
239288 Some ( tokenstream:: TokenTree :: Token ( span, tok) ) => match kleene_op ( & tok) {
289+ // #1 is a KleeneOp with no separator
240290 Some ( op) => return ( None , op) ,
291+
292+ // #1 is not a KleeneOp, but may be a separator... need to look at #2
241293 None => match input. next ( ) {
294+ // #2 is a token
242295 Some ( tokenstream:: TokenTree :: Token ( span, tok2) ) => match kleene_op ( & tok2) {
296+ // #2 is a KleeneOp, so #1 must be a separator
243297 Some ( op) => return ( Some ( tok) , op) ,
298+
299+ // #2 is not a KleeneOp... error
244300 None => span,
245301 } ,
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+ } ,
248308 } ,
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) ,
250314 } ;
251315
316+ // Error...
252317 sess. span_diagnostic . span_err ( span, "expected `*` or `+`" ) ;
253318 ( None , KleeneOp :: ZeroOrMore )
254319}
0 commit comments