@@ -50,16 +50,23 @@ func (s *scanner) init(src io.Reader, errh func(line, col uint, msg string), mod
50
50
51
51
// errorf reports an error at the most recently read character position.
52
52
func (s * scanner ) errorf (format string , args ... interface {}) {
53
- s .bad = true
54
53
s .error (fmt .Sprintf (format , args ... ))
55
54
}
56
55
57
56
// errorAtf reports an error at a byte column offset relative to the current token start.
58
57
func (s * scanner ) errorAtf (offset int , format string , args ... interface {}) {
59
- s .bad = true
60
58
s .errh (s .line , s .col + uint (offset ), fmt .Sprintf (format , args ... ))
61
59
}
62
60
61
+ // setLit sets the scanner state for a recognized _Literal token.
62
+ func (s * scanner ) setLit (kind LitKind , ok bool ) {
63
+ s .nlsemi = true
64
+ s .tok = _Literal
65
+ s .lit = string (s .segment ())
66
+ s .bad = ! ok
67
+ s .kind = kind
68
+ }
69
+
63
70
// next advances the scanner by reading the next token.
64
71
//
65
72
// If a read, source encoding, or lexical error occurs, next calls
@@ -461,16 +468,15 @@ func (s *scanner) digits(base int, invalid *int) (digsep int) {
461
468
}
462
469
463
470
func (s * scanner ) number (seenPoint bool ) {
464
- s . bad = false
465
-
471
+ ok := true
472
+ kind := IntLit
466
473
base := 10 // number base
467
474
prefix := rune (0 ) // one of 0 (decimal), '0' (0-octal), 'x', 'o', or 'b'
468
475
digsep := 0 // bit 0: digit present, bit 1: '_' present
469
476
invalid := - 1 // index of invalid digit in literal, or < 0
470
477
471
478
// integer part
472
479
if ! seenPoint {
473
- s .kind = IntLit
474
480
if s .ch == '0' {
475
481
s .nextch ()
476
482
switch lower (s .ch ) {
@@ -491,7 +497,8 @@ func (s *scanner) number(seenPoint bool) {
491
497
digsep |= s .digits (base , & invalid )
492
498
if s .ch == '.' {
493
499
if prefix == 'o' || prefix == 'b' {
494
- s .errorf ("invalid radix point in %s" , litname (prefix ))
500
+ s .errorf ("invalid radix point in %s literal" , baseName (base ))
501
+ ok = false
495
502
}
496
503
s .nextch ()
497
504
seenPoint = true
@@ -500,68 +507,77 @@ func (s *scanner) number(seenPoint bool) {
500
507
501
508
// fractional part
502
509
if seenPoint {
503
- s . kind = FloatLit
510
+ kind = FloatLit
504
511
digsep |= s .digits (base , & invalid )
505
512
}
506
513
507
- if digsep & 1 == 0 && ! s .bad {
508
- s .errorf ("%s has no digits" , litname (prefix ))
514
+ if digsep & 1 == 0 && ok {
515
+ s .errorf ("%s literal has no digits" , baseName (base ))
516
+ ok = false
509
517
}
510
518
511
519
// exponent
512
520
if e := lower (s .ch ); e == 'e' || e == 'p' {
513
- if ! s . bad {
521
+ if ok {
514
522
switch {
515
523
case e == 'e' && prefix != 0 && prefix != '0' :
516
524
s .errorf ("%q exponent requires decimal mantissa" , s .ch )
525
+ ok = false
517
526
case e == 'p' && prefix != 'x' :
518
527
s .errorf ("%q exponent requires hexadecimal mantissa" , s .ch )
528
+ ok = false
519
529
}
520
530
}
521
531
s .nextch ()
522
- s . kind = FloatLit
532
+ kind = FloatLit
523
533
if s .ch == '+' || s .ch == '-' {
524
534
s .nextch ()
525
535
}
526
536
digsep = s .digits (10 , nil ) | digsep & 2 // don't lose sep bit
527
- if digsep & 1 == 0 && ! s . bad {
537
+ if digsep & 1 == 0 && ok {
528
538
s .errorf ("exponent has no digits" )
539
+ ok = false
529
540
}
530
- } else if prefix == 'x' && s . kind == FloatLit && ! s . bad {
541
+ } else if prefix == 'x' && kind == FloatLit && ok {
531
542
s .errorf ("hexadecimal mantissa requires a 'p' exponent" )
543
+ ok = false
532
544
}
533
545
534
546
// suffix 'i'
535
547
if s .ch == 'i' {
536
- s . kind = ImagLit
548
+ kind = ImagLit
537
549
s .nextch ()
538
550
}
539
551
540
- s .nlsemi = true
541
- s .lit = string (s .segment ())
542
- s .tok = _Literal
552
+ s .setLit (kind , ok ) // do this now so we can use s.lit below
543
553
544
- if s .kind == IntLit && invalid >= 0 && ! s .bad {
545
- s .errorAtf (invalid , "invalid digit %q in %s" , s .lit [invalid ], litname (prefix ))
554
+ if kind == IntLit && invalid >= 0 && ok {
555
+ s .errorAtf (invalid , "invalid digit %q in %s literal" , s .lit [invalid ], baseName (base ))
556
+ ok = false
546
557
}
547
558
548
- if digsep & 2 != 0 && ! s . bad {
559
+ if digsep & 2 != 0 && ok {
549
560
if i := invalidSep (s .lit ); i >= 0 {
550
561
s .errorAtf (i , "'_' must separate successive digits" )
562
+ ok = false
551
563
}
552
564
}
565
+
566
+ s .bad = ! ok // correct s.bad
553
567
}
554
568
555
- func litname (prefix rune ) string {
556
- switch prefix {
557
- case 'x' :
558
- return "hexadecimal literal"
559
- case 'o' , '0' :
560
- return "octal literal"
561
- case 'b' :
562
- return "binary literal"
563
- }
564
- return "decimal literal"
569
+ func baseName (base int ) string {
570
+ switch base {
571
+ case 2 :
572
+ return "binary"
573
+ case 8 :
574
+ return "octal"
575
+ case 10 :
576
+ return "decimal"
577
+ case 16 :
578
+ return "hexadecimal"
579
+ }
580
+ panic ("invalid base" )
565
581
}
566
582
567
583
// invalidSep returns the index of the first invalid separator in x, or -1.
@@ -605,50 +621,53 @@ func invalidSep(x string) int {
605
621
}
606
622
607
623
func (s * scanner ) rune () {
608
- s . bad = false
624
+ ok := true
609
625
s .nextch ()
610
626
611
627
n := 0
612
628
for ; ; n ++ {
613
629
if s .ch == '\'' {
614
- if ! s . bad {
630
+ if ok {
615
631
if n == 0 {
616
632
s .errorf ("empty rune literal or unescaped '" )
633
+ ok = false
617
634
} else if n != 1 {
618
635
s .errorAtf (0 , "more than one character in rune literal" )
636
+ ok = false
619
637
}
620
638
}
621
639
s .nextch ()
622
640
break
623
641
}
624
642
if s .ch == '\\' {
625
643
s .nextch ()
626
- s .escape ('\'' )
644
+ if ! s .escape ('\'' ) {
645
+ ok = false
646
+ }
627
647
continue
628
648
}
629
649
if s .ch == '\n' {
630
- if ! s . bad {
650
+ if ok {
631
651
s .errorf ("newline in rune literal" )
652
+ ok = false
632
653
}
633
654
break
634
655
}
635
656
if s .ch < 0 {
636
- if ! s . bad {
657
+ if ok {
637
658
s .errorAtf (0 , "rune literal not terminated" )
659
+ ok = false
638
660
}
639
661
break
640
662
}
641
663
s .nextch ()
642
664
}
643
665
644
- s .nlsemi = true
645
- s .lit = string (s .segment ())
646
- s .kind = RuneLit
647
- s .tok = _Literal
666
+ s .setLit (RuneLit , ok )
648
667
}
649
668
650
669
func (s * scanner ) stdString () {
651
- s . bad = false
670
+ ok := true
652
671
s .nextch ()
653
672
654
673
for {
@@ -658,28 +677,29 @@ func (s *scanner) stdString() {
658
677
}
659
678
if s .ch == '\\' {
660
679
s .nextch ()
661
- s .escape ('"' )
680
+ if ! s .escape ('"' ) {
681
+ ok = false
682
+ }
662
683
continue
663
684
}
664
685
if s .ch == '\n' {
665
686
s .errorf ("newline in string" )
687
+ ok = false
666
688
break
667
689
}
668
690
if s .ch < 0 {
669
691
s .errorAtf (0 , "string not terminated" )
692
+ ok = false
670
693
break
671
694
}
672
695
s .nextch ()
673
696
}
674
697
675
- s .nlsemi = true
676
- s .lit = string (s .segment ())
677
- s .kind = StringLit
678
- s .tok = _Literal
698
+ s .setLit (StringLit , ok )
679
699
}
680
700
681
701
func (s * scanner ) rawString () {
682
- s . bad = false
702
+ ok := true
683
703
s .nextch ()
684
704
685
705
for {
@@ -689,6 +709,7 @@ func (s *scanner) rawString() {
689
709
}
690
710
if s .ch < 0 {
691
711
s .errorAtf (0 , "string not terminated" )
712
+ ok = false
692
713
break
693
714
}
694
715
s .nextch ()
@@ -697,10 +718,7 @@ func (s *scanner) rawString() {
697
718
// literal (even though they are not part of the literal
698
719
// value).
699
720
700
- s .nlsemi = true
701
- s .lit = string (s .segment ())
702
- s .kind = StringLit
703
- s .tok = _Literal
721
+ s .setLit (StringLit , ok )
704
722
}
705
723
706
724
func (s * scanner ) comment (text string ) {
@@ -797,14 +815,14 @@ func (s *scanner) fullComment() {
797
815
}
798
816
}
799
817
800
- func (s * scanner ) escape (quote rune ) {
818
+ func (s * scanner ) escape (quote rune ) bool {
801
819
var n int
802
820
var base , max uint32
803
821
804
822
switch s .ch {
805
823
case quote , 'a' , 'b' , 'f' , 'n' , 'r' , 't' , 'v' , '\\' :
806
824
s .nextch ()
807
- return
825
+ return true
808
826
case '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' :
809
827
n , base , max = 3 , 8 , 255
810
828
case 'x' :
@@ -818,16 +836,16 @@ func (s *scanner) escape(quote rune) {
818
836
n , base , max = 8 , 16 , unicode .MaxRune
819
837
default :
820
838
if s .ch < 0 {
821
- return // complain in caller about EOF
839
+ return true // complain in caller about EOF
822
840
}
823
841
s .errorf ("unknown escape" )
824
- return
842
+ return false
825
843
}
826
844
827
845
var x uint32
828
846
for i := n ; i > 0 ; i -- {
829
847
if s .ch < 0 {
830
- return // complain in caller about EOF
848
+ return true // complain in caller about EOF
831
849
}
832
850
d := base
833
851
if isDecimal (s .ch ) {
@@ -836,12 +854,8 @@ func (s *scanner) escape(quote rune) {
836
854
d = uint32 (lower (s .ch )) - 'a' + 10
837
855
}
838
856
if d >= base {
839
- kind := "hex"
840
- if base == 8 {
841
- kind = "octal"
842
- }
843
- s .errorf ("invalid character %q in %s escape" , s .ch , kind )
844
- return
857
+ s .errorf ("invalid character %q in %s escape" , s .ch , baseName (int (base )))
858
+ return false
845
859
}
846
860
// d < base
847
861
x = x * base + d
@@ -850,10 +864,13 @@ func (s *scanner) escape(quote rune) {
850
864
851
865
if x > max && base == 8 {
852
866
s .errorf ("octal escape value %d > 255" , x )
853
- return
867
+ return false
854
868
}
855
869
856
870
if x > max || 0xD800 <= x && x < 0xE000 /* surrogate range */ {
857
871
s .errorf ("escape is invalid Unicode code point %#U" , x )
872
+ return false
858
873
}
874
+
875
+ return true
859
876
}
0 commit comments