| 577 | } |
| 578 | |
| 579 | func (s *scanner) scanNumber(lval *sqlSymType, ch int) { |
| 580 | start := s.pos - 1 |
| 581 | isHex := false |
| 582 | hasDecimal := ch == '.' |
| 583 | hasExponent := false |
| 584 | |
| 585 | for { |
| 586 | ch := s.peek() |
| 587 | if (isHex && lex.IsHexDigit(ch)) || lex.IsDigit(ch) { |
| 588 | s.pos++ |
| 589 | continue |
| 590 | } |
| 591 | if ch == 'x' || ch == 'X' { |
| 592 | if isHex || s.in[start] != '0' || s.pos != start+1 { |
| 593 | lval.id = ERROR |
| 594 | lval.str = errInvalidHexNumeric |
| 595 | return |
| 596 | } |
| 597 | s.pos++ |
| 598 | isHex = true |
| 599 | continue |
| 600 | } |
| 601 | if isHex { |
| 602 | break |
| 603 | } |
| 604 | if ch == '.' { |
| 605 | if hasDecimal || hasExponent { |
| 606 | break |
| 607 | } |
| 608 | s.pos++ |
| 609 | if s.peek() == '.' { |
| 610 | // Found ".." while scanning a number: back up to the end of the |
| 611 | // integer. |
| 612 | s.pos-- |
| 613 | break |
| 614 | } |
| 615 | hasDecimal = true |
| 616 | continue |
| 617 | } |
| 618 | if ch == 'e' || ch == 'E' { |
| 619 | if hasExponent { |
| 620 | break |
| 621 | } |
| 622 | hasExponent = true |
| 623 | s.pos++ |
| 624 | ch = s.peek() |
| 625 | if ch == '-' || ch == '+' { |
| 626 | s.pos++ |
| 627 | } |
| 628 | ch = s.peek() |
| 629 | if !lex.IsDigit(ch) { |
| 630 | lval.id = ERROR |
| 631 | lval.str = "invalid floating point literal" |
| 632 | return |
| 633 | } |
| 634 | continue |
| 635 | } |
| 636 | break |