@@ -356,17 +356,6 @@ pub fn is_ident(string: &str) -> bool {
356
356
}
357
357
}
358
358
359
- /// Is the character after the 'e' in a number valid for an exponent?
360
- ///
361
- /// If not the number will be passed to the parser with a suffix beginning with 'e' rather
362
- /// than an exponent (and will be rejected there).
363
- ///
364
- /// The way this function is written means that `1e_` is considered an invalid exponent
365
- /// rather than a number with suffix.
366
- fn is_exponent_second ( ch : char ) -> bool {
367
- matches ! ( ch, '0' ..='9' | '_' | '+' | '-' )
368
- }
369
-
370
359
impl Cursor < ' _ > {
371
360
/// Parses a token from the input string.
372
361
pub fn advance_token ( & mut self ) -> Token {
@@ -420,9 +409,7 @@ impl Cursor<'_> {
420
409
421
410
// Numeric literal.
422
411
c @ '0' ..='9' => {
423
- let literal_kind = self . number ( c) ;
424
- let suffix_start = self . pos_within_token ( ) ;
425
- self . eat_literal_suffix ( ) ;
412
+ let ( literal_kind, suffix_start) = self . number ( c) ;
426
413
TokenKind :: Literal { kind : literal_kind, suffix_start }
427
414
}
428
415
@@ -617,7 +604,7 @@ impl Cursor<'_> {
617
604
}
618
605
}
619
606
620
- fn number ( & mut self , first_digit : char ) -> LiteralKind {
607
+ fn number ( & mut self , first_digit : char ) -> ( LiteralKind , u32 ) {
621
608
debug_assert ! ( '0' <= self . prev( ) && self . prev( ) <= '9' ) ;
622
609
let mut base = Base :: Decimal ;
623
610
if first_digit == '0' {
@@ -627,21 +614,27 @@ impl Cursor<'_> {
627
614
base = Base :: Binary ;
628
615
self . bump ( ) ;
629
616
if !self . eat_decimal_digits ( ) {
630
- return Int { base, empty_int : true } ;
617
+ let suffix_start = self . pos_within_token ( ) ;
618
+ self . eat_literal_suffix ( ) ;
619
+ return ( Int { base, empty_int : true } , suffix_start) ;
631
620
}
632
621
}
633
622
'o' => {
634
623
base = Base :: Octal ;
635
624
self . bump ( ) ;
636
625
if !self . eat_decimal_digits ( ) {
637
- return Int { base, empty_int : true } ;
626
+ let suffix_start = self . pos_within_token ( ) ;
627
+ self . eat_literal_suffix ( ) ;
628
+ return ( Int { base, empty_int : true } , suffix_start) ;
638
629
}
639
630
}
640
631
'x' => {
641
632
base = Base :: Hexadecimal ;
642
633
self . bump ( ) ;
643
634
if !self . eat_hexadecimal_digits ( ) {
644
- return Int { base, empty_int : true } ;
635
+ let suffix_start = self . pos_within_token ( ) ;
636
+ self . eat_literal_suffix ( ) ;
637
+ return ( Int { base, empty_int : true } , suffix_start) ;
645
638
}
646
639
}
647
640
// Not a base prefix; consume additional digits.
@@ -653,40 +646,88 @@ impl Cursor<'_> {
653
646
'.' | 'e' | 'E' => { }
654
647
655
648
// Just a 0.
656
- _ => return Int { base, empty_int : false } ,
649
+ _ => {
650
+ let suffix_start = self . pos_within_token ( ) ;
651
+ self . eat_literal_suffix ( ) ;
652
+ return ( Int { base, empty_int : false } , suffix_start) ;
653
+ }
657
654
}
658
655
} else {
659
656
// No base prefix, parse number in the usual way.
660
657
self . eat_decimal_digits ( ) ;
661
658
} ;
662
659
663
- match self . first ( ) {
660
+ match ( self . first ( ) , self . second ( ) ) {
664
661
// Don't be greedy if this is actually an
665
662
// integer literal followed by field/method access or a range pattern
666
663
// (`0..2` and `12.foo()`)
667
- '.' if self . second ( ) != '.' && !is_id_start ( self . second ( ) ) => {
664
+ ( '.' , second ) if second != '.' && !is_id_start ( second) => {
668
665
// might have stuff after the ., and if it does, it needs to start
669
666
// with a number
670
667
self . bump ( ) ;
671
668
let mut empty_exponent = false ;
669
+ let mut suffix_start = self . pos_within_token ( ) ;
672
670
if self . first ( ) . is_ascii_digit ( ) {
673
671
self . eat_decimal_digits ( ) ;
674
- match self . first ( ) {
675
- 'e' | 'E' if is_exponent_second ( self . second ( ) ) => {
672
+ // This will be the start of the suffix if there is no exponent
673
+ suffix_start = self . pos_within_token ( ) ;
674
+ match ( self . first ( ) , self . second ( ) ) {
675
+ ( 'e' | 'E' , '_' ) => {
676
+ // check if series of `_` is ended by a digit. If yes
677
+ // include it in the number as exponent. If no include
678
+ // it in suffix.
679
+ self . bump ( ) ;
680
+ while matches ! ( self . first( ) , '_' ) {
681
+ self . bump ( ) ;
682
+ }
683
+ if self . first ( ) . is_ascii_digit ( ) {
684
+ self . eat_decimal_digits ( ) ;
685
+ suffix_start = self . pos_within_token ( ) ;
686
+ }
687
+ }
688
+ ( 'e' | 'E' , '0' ..'9' | '+' | '-' ) => {
689
+ // definitely an exponent
676
690
self . bump ( ) ;
677
691
empty_exponent = !self . eat_float_exponent ( ) ;
692
+ suffix_start = self . pos_within_token ( ) ;
678
693
}
679
694
_ => ( ) ,
680
695
}
681
696
}
682
- Float { base, empty_exponent }
697
+ self . eat_literal_suffix ( ) ;
698
+ ( Float { base, empty_exponent } , suffix_start)
699
+ }
700
+ ( 'e' | 'E' , '_' ) => {
701
+ // see above bock for similar apporach
702
+ let non_exponent_suffix_start = self . pos_within_token ( ) ;
703
+ self . bump ( ) ;
704
+ while matches ! ( self . first( ) , '_' ) {
705
+ self . bump ( ) ;
706
+ }
707
+ if self . first ( ) . is_ascii_digit ( ) {
708
+ self . eat_decimal_digits ( ) ;
709
+ let suffix_start = self . pos_within_token ( ) ;
710
+ self . eat_literal_suffix ( ) ;
711
+ ( Float { base, empty_exponent : false } , suffix_start)
712
+ } else {
713
+ // No digit means suffix, and therefore int
714
+ self . eat_literal_suffix ( ) ;
715
+ ( Int { base, empty_int : false } , non_exponent_suffix_start)
716
+ }
683
717
}
684
- 'e' | 'E' if is_exponent_second ( self . second ( ) ) => {
718
+ ( 'e' | 'E' , '0' ..='9' | '+' | '-' ) => {
719
+ // definitely an exponent
685
720
self . bump ( ) ;
686
721
let empty_exponent = !self . eat_float_exponent ( ) ;
687
- Float { base, empty_exponent }
722
+ let suffix_start = self . pos_within_token ( ) ;
723
+ self . eat_literal_suffix ( ) ;
724
+ ( Float { base, empty_exponent } , suffix_start)
725
+ }
726
+ _ => {
727
+ let suffix_start = self . pos_within_token ( ) ;
728
+ self . eat_literal_suffix ( ) ;
729
+ ( Int { base, empty_int : false } , suffix_start)
688
730
}
689
- _ => Int { base, empty_int : false } ,
690
731
}
691
732
}
692
733
@@ -935,6 +976,7 @@ impl Cursor<'_> {
935
976
}
936
977
}
937
978
979
+ /// Returns `true` if a digit was consumed (rather than just '_')
938
980
fn eat_decimal_digits ( & mut self ) -> bool {
939
981
let mut has_digits = false ;
940
982
loop {
@@ -972,7 +1014,7 @@ impl Cursor<'_> {
972
1014
/// Eats the float exponent. Returns true if at least one digit was met,
973
1015
/// and returns false otherwise.
974
1016
fn eat_float_exponent ( & mut self ) -> bool {
975
- debug_assert ! ( self . prev( ) == 'e' || self . prev ( ) == 'E' ) ;
1017
+ debug_assert ! ( matches! ( self . prev( ) , 'e' | 'E' ) ) ;
976
1018
if self . first ( ) == '-' || self . first ( ) == '+' {
977
1019
self . bump ( ) ;
978
1020
}
0 commit comments