@@ -490,7 +490,7 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
490
490
}
491
491
492
492
/// Process the matcher positions of `cur_items` until it is empty. In the process, this will
493
- /// produce more items in `next_items`, `eof_items`, and `bb_items`.
493
+ /// produce more items in `next_items` and `bb_items`.
494
494
///
495
495
/// For more info about the how this happens, see the module-level doc comments and the inline
496
496
/// comments of this function.
@@ -520,11 +520,10 @@ fn parse_tt_inner<'root, 'tt>(
520
520
// `token == Eof`.
521
521
let mut eof_items = EofItems :: None ;
522
522
523
- // Pop items from `cur_items` until it is empty.
524
523
while let Some ( mut item) = cur_items. pop ( ) {
525
524
// When unzipped trees end, remove them. This corresponds to backtracking out of a
526
- // delimited submatcher into which we already descended. In backtracking out again, we need
527
- // to advance the "dot" past the delimiters in the outer matcher.
525
+ // delimited submatcher into which we already descended. When backtracking out again, we
526
+ // need to advance the "dot" past the delimiters in the outer matcher.
528
527
while item. idx >= item. top_elts . len ( ) {
529
528
match item. stack . pop ( ) {
530
529
Some ( MatcherTtFrame { elts, idx } ) => {
@@ -541,19 +540,12 @@ fn parse_tt_inner<'root, 'tt>(
541
540
let len = item. top_elts . len ( ) ;
542
541
543
542
if idx < len {
544
- // We are in the middle of a matcher. Look at what token in the matcher we are trying
545
- // to match the current token (`token`) against. Depending on that, we may generate new
546
- // items.
543
+ // We are in the middle of a matcher. Compare the matcher's current tt against `token`.
547
544
match item. top_elts . get_tt ( idx) {
548
- // Need to descend into a sequence
549
545
TokenTree :: Sequence ( sp, seq) => {
550
- // Examine the case where there are 0 matches of this sequence. We are
551
- // implicitly disallowing OneOrMore from having 0 matches here. Thus, that will
552
- // result in a "no rules expected token" error by virtue of this matcher not
553
- // working.
554
- if seq. kleene . op == mbe:: KleeneOp :: ZeroOrMore
555
- || seq. kleene . op == mbe:: KleeneOp :: ZeroOrOne
556
- {
546
+ let op = seq. kleene . op ;
547
+ if op == mbe:: KleeneOp :: ZeroOrMore || op == mbe:: KleeneOp :: ZeroOrOne {
548
+ // Allow for the possibility of zero matches of this sequence.
557
549
let mut new_item = item. clone ( ) ;
558
550
new_item. match_cur += seq. num_captures ;
559
551
new_item. idx += 1 ;
@@ -563,20 +555,19 @@ fn parse_tt_inner<'root, 'tt>(
563
555
cur_items. push ( new_item) ;
564
556
}
565
557
558
+ // Allow for the possibility of one or more matches of this sequence.
566
559
cur_items. push ( MatcherPosHandle :: Box ( Box :: new ( MatcherPos :: repetition (
567
560
item, sp, seq,
568
561
) ) ) ) ;
569
562
}
570
563
571
- // We need to match a metavar (but the identifier is invalid)... this is an error
572
564
TokenTree :: MetaVarDecl ( span, _, None ) => {
565
+ // E.g. `$e` instead of `$e:expr`.
573
566
if sess. missing_fragment_specifiers . borrow_mut ( ) . remove ( & span) . is_some ( ) {
574
567
return Some ( Error ( span, "missing fragment specifier" . to_string ( ) ) ) ;
575
568
}
576
569
}
577
570
578
- // We need to match a metavar with a valid ident... call out to the black-box
579
- // parser by adding an item to `bb_items`.
580
571
TokenTree :: MetaVarDecl ( _, _, Some ( kind) ) => {
581
572
// Built-in nonterminals never start with these tokens, so we can eliminate
582
573
// them from consideration.
@@ -588,69 +579,57 @@ fn parse_tt_inner<'root, 'tt>(
588
579
}
589
580
}
590
581
591
- // We need to descend into a delimited submatcher or a doc comment. To do this, we
592
- // push the current matcher onto a stack and push a new item containing the
593
- // submatcher onto `cur_items`.
594
- //
595
- // At the beginning of the loop, if we reach the end of the delimited submatcher,
596
- // we pop the stack to backtrack out of the descent.
597
582
seq @ ( TokenTree :: Delimited ( ..)
598
583
| TokenTree :: Token ( Token { kind : DocComment ( ..) , .. } ) ) => {
584
+ // To descend into a delimited submatcher or a doc comment, we push the current
585
+ // matcher onto a stack and push a new item containing the submatcher onto
586
+ // `cur_items`.
587
+ //
588
+ // At the beginning of the loop, if we reach the end of the delimited
589
+ // submatcher, we pop the stack to backtrack out of the descent.
599
590
let lower_elts = mem:: replace ( & mut item. top_elts , Tt ( seq) ) ;
600
591
let idx = item. idx ;
601
592
item. stack . push ( MatcherTtFrame { elts : lower_elts, idx } ) ;
602
593
item. idx = 0 ;
603
594
cur_items. push ( item) ;
604
595
}
605
596
606
- // We just matched a normal token. We can just advance the parser.
607
- TokenTree :: Token ( t) if token_name_eq ( & t, token) => {
608
- item. idx += 1 ;
609
- next_items. push ( item) ;
597
+ TokenTree :: Token ( t) => {
598
+ // If the token matches, we can just advance the parser. Otherwise, this match
599
+ // hash failed, there is nothing to do, and hopefully another item in
600
+ // `cur_items` will match.
601
+ if token_name_eq ( & t, token) {
602
+ item. idx += 1 ;
603
+ next_items. push ( item) ;
604
+ }
610
605
}
611
606
612
- // There was another token that was not `token`... This means we can't add any
613
- // rules. NOTE that this is not necessarily an error unless _all_ items in
614
- // `cur_items` end up doing this. There may still be some other matchers that do
615
- // end up working out.
616
- TokenTree :: Token ( ..) => { }
617
-
607
+ // These cannot appear in a matcher.
618
608
TokenTree :: MetaVar ( ..) | TokenTree :: MetaVarExpr ( ..) => unreachable ! ( ) ,
619
609
}
620
610
} else if let Some ( repetition) = & item. repetition {
621
611
// We are past the end of a repetition.
622
612
debug_assert ! ( idx <= len + 1 ) ;
623
613
debug_assert ! ( matches!( item. top_elts, Tt ( TokenTree :: Sequence ( ..) ) ) ) ;
624
614
625
- // At this point, regardless of whether there is a separator, we should add all
626
- // matches from the complete repetition of the sequence to the shared, top-level
627
- // `matches` list (actually, `up.matches`, which could itself not be the top-level,
628
- // but anyway...). Moreover, we add another item to `cur_items` in which the "dot"
629
- // is at the end of the `up` matcher. This ensures that the "dot" in the `up`
630
- // matcher is also advanced sufficiently.
631
- //
632
- // NOTE: removing the condition `idx == len` allows trailing separators.
633
615
if idx == len {
634
- // Get the `up` matcher
616
+ // Add all matches from the sequence to `up`, and move the "dot" past the
617
+ // repetition in `up`. This allows for the case where the sequence matching is
618
+ // finished.
635
619
let mut new_pos = repetition. up . clone ( ) ;
636
-
637
- // Add matches from this repetition to the `matches` of `up`
638
620
for idx in item. match_lo ..item. match_hi {
639
621
let sub = item. matches [ idx] . clone ( ) ;
640
622
new_pos. push_match ( idx, MatchedSeq ( sub) ) ;
641
623
}
642
-
643
- // Move the "dot" past the repetition in `up`
644
624
new_pos. match_cur = item. match_hi ;
645
625
new_pos. idx += 1 ;
646
626
cur_items. push ( new_pos) ;
647
627
}
648
628
649
- // Check if we need a separator.
650
629
if idx == len && repetition. sep . is_some ( ) {
651
- // We have a separator, and it is the current token. We can advance past the
652
- // separator token.
653
630
if repetition. sep . as_ref ( ) . map_or ( false , |sep| token_name_eq ( token, sep) ) {
631
+ // The matcher has a separator, and it matches the current token. We can
632
+ // advance past the separator token.
654
633
item. idx += 1 ;
655
634
next_items. push ( item) ;
656
635
}
@@ -674,8 +653,8 @@ fn parse_tt_inner<'root, 'tt>(
674
653
}
675
654
}
676
655
677
- // If we reached the EOF , check that there is EXACTLY ONE possible matcher. Otherwise,
678
- // either the parse is ambiguous (which should never happen ) or there is a syntax error.
656
+ // If we reached the end of input , check that there is EXACTLY ONE possible matcher. Otherwise,
657
+ // either the parse is ambiguous (which is an error ) or there is a syntax error.
679
658
if * token == token:: Eof {
680
659
Some ( match eof_items {
681
660
EofItems :: One ( mut eof_item) => {
@@ -712,20 +691,19 @@ pub(super) fn parse_tt(
712
691
// `next_items`. After some post-processing, the contents of `next_items` replenish `cur_items`
713
692
// and we start over again.
714
693
//
715
- // This MatcherPos instance is allocated on the stack. All others -- and
716
- // there are frequently *no* others! -- are allocated on the heap.
694
+ // This MatcherPos instance is allocated on the stack. All others -- and there are frequently
695
+ // *no* others! -- are allocated on the heap.
717
696
let mut initial = MatcherPos :: new ( ms) ;
718
697
let mut cur_items = smallvec ! [ MatcherPosHandle :: Ref ( & mut initial) ] ;
719
698
720
699
loop {
721
700
let mut next_items = SmallVec :: new ( ) ;
722
701
723
- // Matcher positions black-box parsed by parser.rs (`parser`)
702
+ // Matcher positions black-box parsed by `Parser`.
724
703
let mut bb_items = SmallVec :: new ( ) ;
725
704
726
705
// Process `cur_items` until either we have finished the input or we need to get some
727
- // parsing from the black-box parser done. The result is that `next_items` will contain a
728
- // bunch of possible next matcher positions in `next_items`.
706
+ // parsing from the black-box parser done.
729
707
if let Some ( result) = parse_tt_inner (
730
708
parser. sess ,
731
709
ms,
@@ -740,10 +718,7 @@ pub(super) fn parse_tt(
740
718
// `parse_tt_inner` handled all cur_items, so it's empty.
741
719
assert ! ( cur_items. is_empty( ) ) ;
742
720
743
- // We need to do some post processing after the `parse_tt_inner`.
744
- //
745
721
// Error messages here could be improved with links to original rules.
746
-
747
722
match ( next_items. len ( ) , bb_items. len ( ) ) {
748
723
( 0 , 0 ) => {
749
724
// There are no possible next positions AND we aren't waiting for the black-box
@@ -787,8 +762,7 @@ pub(super) fn parse_tt(
787
762
}
788
763
789
764
( _, _) => {
790
- // We need to call the black-box parser to get some nonterminal, but something is
791
- // wrong.
765
+ // Too many possibilities!
792
766
return bb_items_ambiguity_error (
793
767
macro_name,
794
768
next_items,
0 commit comments