From 00e06fb432f357467be5f87ae8db233aab11b741 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Mon, 5 Oct 2015 12:59:55 +0300 Subject: [PATCH] scanner: finalize float scanning --- scanner/scanner.go | 49 +++++++++++++++++++++++------------------ scanner/scanner_test.go | 38 ++++++++++++++++---------------- 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/scanner/scanner.go b/scanner/scanner.go index 63480ab..8fe0651 100644 --- a/scanner/scanner.go +++ b/scanner/scanner.go @@ -162,15 +162,17 @@ func (s *Scanner) scanNumber(ch rune) token.Token { ch = s.next() if ch == '8' || ch == '9' { // this is just a possibility. For example 0159 is illegal, but - // 159.23 is valid. So we mark a possible illegal octal. If the - // next character is not a period, we'll print the error + // 0159.23 is valid. So we mark a possible illegal octal. If + // the next character is not a period, we'll print the error. illegalOctal = true } + } s.unread() if ch == '.' || ch == 'e' || ch == 'E' { + ch = s.next() ch = s.scanFraction(ch) ch = s.scanExponent(ch) return token.FLOAT @@ -184,8 +186,8 @@ func (s *Scanner) scanNumber(ch rune) token.Token { } ch = s.scanMantissa(ch) - fmt.Printf("ch = %q\n", ch) if ch == '.' || ch == 'e' || ch == 'E' { + ch = s.next() // seek forward ch = s.scanFraction(ch) ch = s.scanExponent(ch) return token.FLOAT @@ -193,25 +195,6 @@ func (s *Scanner) scanNumber(ch rune) token.Token { return token.NUMBER } -func (s *Scanner) scanFraction(ch rune) rune { - if ch == '.' { - ch = s.next() - ch = s.scanMantissa(ch) - } - return ch -} - -func (s *Scanner) scanExponent(ch rune) rune { - if ch == 'e' || ch == 'E' { - ch = s.next() - if ch == '-' || ch == '+' { - ch = s.next() - } - ch = s.scanMantissa(ch) - } - return ch -} - // scanMantissa scans the mantissa begining from the rune. It returns the next // non decimal rune. It's used to determine wheter it's a fraction or exponent. func (s *Scanner) scanMantissa(ch rune) rune { @@ -227,6 +210,28 @@ func (s *Scanner) scanMantissa(ch rune) rune { return ch } +func (s *Scanner) scanFraction(ch rune) rune { + if ch == '.' { + ch = s.next() + msCh := s.scanMantissa(ch) + if msCh == ch { + s.unread() + } + } + return ch +} + +func (s *Scanner) scanExponent(ch rune) rune { + if ch == 'e' || ch == 'E' { + ch = s.next() + if ch == '-' || ch == '+' { + ch = s.next() + } + ch = s.scanMantissa(ch) + } + return ch +} + // scanString scans a quoted string func (s *Scanner) scanString() { for { diff --git a/scanner/scanner_test.go b/scanner/scanner_test.go index e4d75fb..4c7992f 100644 --- a/scanner/scanner_test.go +++ b/scanner/scanner_test.go @@ -132,25 +132,25 @@ func TestNumber(t *testing.T) { {token.FLOAT, ".42"}, {token.FLOAT, ".0123456789"}, {token.FLOAT, "0.0"}, - // {token.FLOAT, "1.0"}, - // {token.FLOAT, "42.0"}, - // {token.FLOAT, "01234567890.0"}, - // {token.FLOAT, "0e0"}, - // {token.FLOAT, "1e0"}, - // {token.FLOAT, "42e0"}, - // {token.FLOAT, "01234567890e0"}, - // {token.FLOAT, "0E0"}, - // {token.FLOAT, "1E0"}, - // {token.FLOAT, "42E0"}, - // {token.FLOAT, "01234567890E0"}, - // {token.FLOAT, "0e+10"}, - // {token.FLOAT, "1e-10"}, - // {token.FLOAT, "42e+10"}, - // {token.FLOAT, "01234567890e-10"}, - // {token.FLOAT, "0E+10"}, - // {token.FLOAT, "1E-10"}, - // {token.FLOAT, "42E+10"}, - // {token.FLOAT, "01234567890E-10"}, + {token.FLOAT, "1.0"}, + {token.FLOAT, "42.0"}, + {token.FLOAT, "01234567890.0"}, + {token.FLOAT, "0e0"}, + {token.FLOAT, "1e0"}, + {token.FLOAT, "42e0"}, + {token.FLOAT, "01234567890e0"}, + {token.FLOAT, "0E0"}, + {token.FLOAT, "1E0"}, + {token.FLOAT, "42E0"}, + {token.FLOAT, "01234567890E0"}, + {token.FLOAT, "0e+10"}, + {token.FLOAT, "1e-10"}, + {token.FLOAT, "42e+10"}, + {token.FLOAT, "01234567890e-10"}, + {token.FLOAT, "0E+10"}, + {token.FLOAT, "1E-10"}, + {token.FLOAT, "42E+10"}, + {token.FLOAT, "01234567890E-10"}, } testTokenList(t, tokenList)