8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use ast:: { TokenTree , TtDelimited , TtSequence , TtToken } ;
12
- use ast;
11
+ use ast:: { self , TokenTree , TtDelimited , TtSequence , TtToken } ;
13
12
use codemap:: { Span , DUMMY_SP } ;
14
13
use ext:: base:: { ExtCtxt , MacResult , SyntaxExtension } ;
15
14
use ext:: base:: { NormalTT , TTMacroExpander } ;
@@ -19,9 +18,8 @@ use ext::tt::macro_parser::{parse, parse_or_else};
19
18
use parse:: lexer:: { new_tt_reader, new_tt_reader_with_doc_flag} ;
20
19
use parse:: parser:: Parser ;
21
20
use parse:: attr:: ParserAttr ;
22
- use parse:: token:: { special_idents, gensym_ident, NtTT , Token } ;
21
+ use parse:: token:: { self , special_idents, gensym_ident, NtTT , Token } ;
23
22
use parse:: token:: Token :: * ;
24
- use parse:: token;
25
23
use print;
26
24
use ptr:: P ;
27
25
@@ -336,16 +334,20 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
336
334
337
335
let tok = if let TtToken ( _, ref tok) = * token { tok } else { unreachable ! ( ) } ;
338
336
// If T' is in the set FOLLOW(NT), continue. Else, reject.
339
- match & next_token {
340
- & Eof => return Some ( ( sp, tok. clone ( ) ) ) ,
341
- _ if is_in_follow ( cx , & next_token , frag_spec . as_str ( ) ) => continue ,
342
- next => {
337
+ match ( & next_token, is_in_follow ( cx , & next_token , frag_spec . as_str ( ) ) ) {
338
+ ( & Eof , _ ) => return Some ( ( sp, tok. clone ( ) ) ) ,
339
+ ( _ , Ok ( true ) ) => continue ,
340
+ ( next, Ok ( false ) ) => {
343
341
cx. span_err ( sp, format ! ( "`${0}:{1}` is followed by `{2}`, which \
344
342
is not allowed for `{1}` fragments",
345
343
name. as_str( ) , frag_spec. as_str( ) ,
346
344
token_to_string( next) ) . as_slice ( ) ) ;
347
345
continue
348
346
} ,
347
+ ( _, Err ( msg) ) => {
348
+ cx. span_err ( sp, msg. as_slice ( ) ) ;
349
+ continue
350
+ }
349
351
}
350
352
} ,
351
353
TtSequence ( sp, ref seq) => {
@@ -412,51 +414,50 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
412
414
last
413
415
}
414
416
415
- fn is_in_follow ( cx : & ExtCtxt , tok : & Token , frag : & str ) -> bool {
417
+ fn is_in_follow ( _ : & ExtCtxt , tok : & Token , frag : & str ) -> Result < bool , String > {
416
418
if let & CloseDelim ( _) = tok {
417
- return true ;
418
- }
419
-
420
- match frag {
421
- "item" => {
422
- // since items *must* be followed by either a `;` or a `}`, we can
423
- // accept anything after them
424
- true
425
- } ,
426
- "block" => {
427
- // anything can follow block, the braces provide a easy boundary to
428
- // maintain
429
- true
430
- } ,
431
- "stmt" | "expr" => {
432
- match * tok {
433
- FatArrow | Comma | Semi => true ,
434
- _ => false
435
- }
436
- } ,
437
- "pat" => {
438
- match * tok {
439
- FatArrow | Comma | Eq => true ,
440
- _ => false
441
- }
442
- } ,
443
- "path" | "ty" => {
444
- match * tok {
445
- Comma | FatArrow | Colon | Eq | Gt => true ,
446
- Ident ( i, _) if i. as_str ( ) == "as" => true ,
447
- _ => false
448
- }
449
- } ,
450
- "ident" => {
451
- // being a single token, idents are harmless
452
- true
453
- } ,
454
- "meta" | "tt" => {
455
- // being either a single token or a delimited sequence, tt is
456
- // harmless
457
- true
458
- } ,
459
- _ => cx. bug ( format ! ( "unrecognized builtin nonterminal {}" ,
460
- frag) . as_slice ( ) ) ,
419
+ Ok ( true )
420
+ } else {
421
+ match frag {
422
+ "item" => {
423
+ // since items *must* be followed by either a `;` or a `}`, we can
424
+ // accept anything after them
425
+ Ok ( true )
426
+ } ,
427
+ "block" => {
428
+ // anything can follow block, the braces provide a easy boundary to
429
+ // maintain
430
+ Ok ( true )
431
+ } ,
432
+ "stmt" | "expr" => {
433
+ match * tok {
434
+ FatArrow | Comma | Semi => Ok ( true ) ,
435
+ _ => Ok ( false )
436
+ }
437
+ } ,
438
+ "pat" => {
439
+ match * tok {
440
+ FatArrow | Comma | Eq => Ok ( true ) ,
441
+ _ => Ok ( false )
442
+ }
443
+ } ,
444
+ "path" | "ty" => {
445
+ match * tok {
446
+ Comma | FatArrow | Colon | Eq | Gt => Ok ( true ) ,
447
+ Ident ( i, _) if i. as_str ( ) == "as" => Ok ( true ) ,
448
+ _ => Ok ( false )
449
+ }
450
+ } ,
451
+ "ident" => {
452
+ // being a single token, idents are harmless
453
+ Ok ( true )
454
+ } ,
455
+ "meta" | "tt" => {
456
+ // being either a single token or a delimited sequence, tt is
457
+ // harmless
458
+ Ok ( true )
459
+ } ,
460
+ _ => Err ( format ! ( "unrecognized builtin nonterminal `{}`" , frag) )
461
+ }
461
462
}
462
463
}
0 commit comments