@@ -361,17 +361,6 @@ pub fn is_ident(string: &str) -> bool {
361
361
}
362
362
}
363
363
364
- /// Is the character after the 'e' in a number valid for an exponent?
365
- ///
366
- /// If not the number will be passed to the parser with a suffix beginning with 'e' rather
367
- /// than an exponent (and will be rejected there).
368
- ///
369
- /// The way this function is written means that `1e_` is considered an invalid exponent
370
- /// rather than a number with suffix.
371
- fn is_exponent_second ( ch : char ) -> bool {
372
- matches ! ( ch, '0' ..='9' | '_' | '+' | '-' )
373
- }
374
-
375
364
impl Cursor < ' _ > {
376
365
/// Parses a token from the input string.
377
366
pub fn advance_token ( & mut self ) -> Token {
@@ -425,9 +414,7 @@ impl Cursor<'_> {
425
414
426
415
// Numeric literal.
427
416
c @ '0' ..='9' => {
428
- let literal_kind = self . number ( c) ;
429
- let suffix_start = self . pos_within_token ( ) ;
430
- self . eat_literal_suffix ( ) ;
417
+ let ( literal_kind, suffix_start) = self . number ( c) ;
431
418
TokenKind :: Literal { kind : literal_kind, suffix_start }
432
419
}
433
420
@@ -624,7 +611,7 @@ impl Cursor<'_> {
624
611
}
625
612
}
626
613
627
- fn number ( & mut self , first_digit : char ) -> LiteralKind {
614
+ fn number ( & mut self , first_digit : char ) -> ( LiteralKind , u32 ) {
628
615
debug_assert ! ( '0' <= self . prev( ) && self . prev( ) <= '9' ) ;
629
616
let mut base = Base :: Decimal ;
630
617
if first_digit == '0' {
@@ -634,21 +621,27 @@ impl Cursor<'_> {
634
621
base = Base :: Binary ;
635
622
self . bump ( ) ;
636
623
if !self . eat_decimal_digits ( ) {
637
- return Int { base, empty_int : true } ;
624
+ let suffix_start = self . pos_within_token ( ) ;
625
+ self . eat_literal_suffix ( ) ;
626
+ return ( Int { base, empty_int : true } , suffix_start) ;
638
627
}
639
628
}
640
629
'o' => {
641
630
base = Base :: Octal ;
642
631
self . bump ( ) ;
643
632
if !self . eat_decimal_digits ( ) {
644
- return Int { base, empty_int : true } ;
633
+ let suffix_start = self . pos_within_token ( ) ;
634
+ self . eat_literal_suffix ( ) ;
635
+ return ( Int { base, empty_int : true } , suffix_start) ;
645
636
}
646
637
}
647
638
'x' => {
648
639
base = Base :: Hexadecimal ;
649
640
self . bump ( ) ;
650
641
if !self . eat_hexadecimal_digits ( ) {
651
- return Int { base, empty_int : true } ;
642
+ let suffix_start = self . pos_within_token ( ) ;
643
+ self . eat_literal_suffix ( ) ;
644
+ return ( Int { base, empty_int : true } , suffix_start) ;
652
645
}
653
646
}
654
647
// Not a base prefix; consume additional digits.
@@ -660,40 +653,88 @@ impl Cursor<'_> {
660
653
'.' | 'e' | 'E' => { }
661
654
662
655
// Just a 0.
663
- _ => return Int { base, empty_int : false } ,
656
+ _ => {
657
+ let suffix_start = self . pos_within_token ( ) ;
658
+ self . eat_literal_suffix ( ) ;
659
+ return ( Int { base, empty_int : false } , suffix_start) ;
660
+ }
664
661
}
665
662
} else {
666
663
// No base prefix, parse number in the usual way.
667
664
self . eat_decimal_digits ( ) ;
668
665
} ;
669
666
670
- match self . first ( ) {
667
+ match ( self . first ( ) , self . second ( ) ) {
671
668
// Don't be greedy if this is actually an
672
669
// integer literal followed by field/method access or a range pattern
673
670
// (`0..2` and `12.foo()`)
674
- '.' if self . second ( ) != '.' && !is_id_start ( self . second ( ) ) => {
671
+ ( '.' , second ) if second != '.' && !is_id_start ( second) => {
675
672
// might have stuff after the ., and if it does, it needs to start
676
673
// with a number
677
674
self . bump ( ) ;
678
675
let mut empty_exponent = false ;
676
+ let mut suffix_start = self . pos_within_token ( ) ;
679
677
if self . first ( ) . is_ascii_digit ( ) {
680
678
self . eat_decimal_digits ( ) ;
681
- match self . first ( ) {
682
- 'e' | 'E' if is_exponent_second ( self . second ( ) ) => {
679
+ // This will be the start of the suffix if there is no exponent
680
+ suffix_start = self . pos_within_token ( ) ;
681
+ match ( self . first ( ) , self . second ( ) ) {
682
+ ( 'e' | 'E' , '_' ) => {
683
+ // check if series of `_` is ended by a digit. If yes
684
+ // include it in the number as exponent. If no include
685
+ // it in suffix.
686
+ self . bump ( ) ;
687
+ while matches ! ( self . first( ) , '_' ) {
688
+ self . bump ( ) ;
689
+ }
690
+ if self . first ( ) . is_ascii_digit ( ) {
691
+ self . eat_decimal_digits ( ) ;
692
+ suffix_start = self . pos_within_token ( ) ;
693
+ }
694
+ }
695
+ ( 'e' | 'E' , '0' ..'9' | '+' | '-' ) => {
696
+ // definitely an exponent
683
697
self . bump ( ) ;
684
698
empty_exponent = !self . eat_float_exponent ( ) ;
699
+ suffix_start = self . pos_within_token ( ) ;
685
700
}
686
701
_ => ( ) ,
687
702
}
688
703
}
689
- Float { base, empty_exponent }
704
+ self . eat_literal_suffix ( ) ;
705
+ ( Float { base, empty_exponent } , suffix_start)
706
+ }
707
+ ( 'e' | 'E' , '_' ) => {
708
+ // see above bock for similar apporach
709
+ let non_exponent_suffix_start = self . pos_within_token ( ) ;
710
+ self . bump ( ) ;
711
+ while matches ! ( self . first( ) , '_' ) {
712
+ self . bump ( ) ;
713
+ }
714
+ if self . first ( ) . is_ascii_digit ( ) {
715
+ self . eat_decimal_digits ( ) ;
716
+ let suffix_start = self . pos_within_token ( ) ;
717
+ self . eat_literal_suffix ( ) ;
718
+ ( Float { base, empty_exponent : false } , suffix_start)
719
+ } else {
720
+ // No digit means suffix, and therefore int
721
+ self . eat_literal_suffix ( ) ;
722
+ ( Int { base, empty_int : false } , non_exponent_suffix_start)
723
+ }
690
724
}
691
- 'e' | 'E' if is_exponent_second ( self . second ( ) ) => {
725
+ ( 'e' | 'E' , '0' ..='9' | '+' | '-' ) => {
726
+ // definitely an exponent
692
727
self . bump ( ) ;
693
728
let empty_exponent = !self . eat_float_exponent ( ) ;
694
- Float { base, empty_exponent }
729
+ let suffix_start = self . pos_within_token ( ) ;
730
+ self . eat_literal_suffix ( ) ;
731
+ ( Float { base, empty_exponent } , suffix_start)
732
+ }
733
+ _ => {
734
+ let suffix_start = self . pos_within_token ( ) ;
735
+ self . eat_literal_suffix ( ) ;
736
+ ( Int { base, empty_int : false } , suffix_start)
695
737
}
696
- _ => Int { base, empty_int : false } ,
697
738
}
698
739
}
699
740
@@ -942,6 +983,7 @@ impl Cursor<'_> {
942
983
}
943
984
}
944
985
986
+ /// Returns `true` if a digit was consumed (rather than just '_')
945
987
fn eat_decimal_digits ( & mut self ) -> bool {
946
988
let mut has_digits = false ;
947
989
loop {
@@ -979,7 +1021,7 @@ impl Cursor<'_> {
979
1021
/// Eats the float exponent. Returns true if at least one digit was met,
980
1022
/// and returns false otherwise.
981
1023
fn eat_float_exponent ( & mut self ) -> bool {
982
- debug_assert ! ( self . prev( ) == 'e' || self . prev ( ) == 'E' ) ;
1024
+ debug_assert ! ( matches! ( self . prev( ) , 'e' | 'E' ) ) ;
983
1025
if self . first ( ) == '-' || self . first ( ) == '+' {
984
1026
self . bump ( ) ;
985
1027
}
0 commit comments