scanner: finalize float scanning

This commit is contained in:
Fatih Arslan 2015-10-05 12:59:55 +03:00
parent c7955d276f
commit 00e06fb432
2 changed files with 46 additions and 41 deletions

View File

@ -162,15 +162,17 @@ func (s *Scanner) scanNumber(ch rune) token.Token {
ch = s.next() ch = s.next()
if ch == '8' || ch == '9' { if ch == '8' || ch == '9' {
// this is just a possibility. For example 0159 is illegal, but // this is just a possibility. For example 0159 is illegal, but
// 159.23 is valid. So we mark a possible illegal octal. If the // 0159.23 is valid. So we mark a possible illegal octal. If
// next character is not a period, we'll print the error // the next character is not a period, we'll print the error.
illegalOctal = true illegalOctal = true
} }
} }
s.unread() s.unread()
if ch == '.' || ch == 'e' || ch == 'E' { if ch == '.' || ch == 'e' || ch == 'E' {
ch = s.next()
ch = s.scanFraction(ch) ch = s.scanFraction(ch)
ch = s.scanExponent(ch) ch = s.scanExponent(ch)
return token.FLOAT return token.FLOAT
@ -184,8 +186,8 @@ func (s *Scanner) scanNumber(ch rune) token.Token {
} }
ch = s.scanMantissa(ch) ch = s.scanMantissa(ch)
fmt.Printf("ch = %q\n", ch)
if ch == '.' || ch == 'e' || ch == 'E' { if ch == '.' || ch == 'e' || ch == 'E' {
ch = s.next() // seek forward
ch = s.scanFraction(ch) ch = s.scanFraction(ch)
ch = s.scanExponent(ch) ch = s.scanExponent(ch)
return token.FLOAT return token.FLOAT
@ -193,25 +195,6 @@ func (s *Scanner) scanNumber(ch rune) token.Token {
return token.NUMBER 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 // 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. // non decimal rune. It's used to determine wheter it's a fraction or exponent.
func (s *Scanner) scanMantissa(ch rune) rune { func (s *Scanner) scanMantissa(ch rune) rune {
@ -227,6 +210,28 @@ func (s *Scanner) scanMantissa(ch rune) rune {
return ch 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 // scanString scans a quoted string
func (s *Scanner) scanString() { func (s *Scanner) scanString() {
for { for {

View File

@ -132,25 +132,25 @@ func TestNumber(t *testing.T) {
{token.FLOAT, ".42"}, {token.FLOAT, ".42"},
{token.FLOAT, ".0123456789"}, {token.FLOAT, ".0123456789"},
{token.FLOAT, "0.0"}, {token.FLOAT, "0.0"},
// {token.FLOAT, "1.0"}, {token.FLOAT, "1.0"},
// {token.FLOAT, "42.0"}, {token.FLOAT, "42.0"},
// {token.FLOAT, "01234567890.0"}, {token.FLOAT, "01234567890.0"},
// {token.FLOAT, "0e0"}, {token.FLOAT, "0e0"},
// {token.FLOAT, "1e0"}, {token.FLOAT, "1e0"},
// {token.FLOAT, "42e0"}, {token.FLOAT, "42e0"},
// {token.FLOAT, "01234567890e0"}, {token.FLOAT, "01234567890e0"},
// {token.FLOAT, "0E0"}, {token.FLOAT, "0E0"},
// {token.FLOAT, "1E0"}, {token.FLOAT, "1E0"},
// {token.FLOAT, "42E0"}, {token.FLOAT, "42E0"},
// {token.FLOAT, "01234567890E0"}, {token.FLOAT, "01234567890E0"},
// {token.FLOAT, "0e+10"}, {token.FLOAT, "0e+10"},
// {token.FLOAT, "1e-10"}, {token.FLOAT, "1e-10"},
// {token.FLOAT, "42e+10"}, {token.FLOAT, "42e+10"},
// {token.FLOAT, "01234567890e-10"}, {token.FLOAT, "01234567890e-10"},
// {token.FLOAT, "0E+10"}, {token.FLOAT, "0E+10"},
// {token.FLOAT, "1E-10"}, {token.FLOAT, "1E-10"},
// {token.FLOAT, "42E+10"}, {token.FLOAT, "42E+10"},
// {token.FLOAT, "01234567890E-10"}, {token.FLOAT, "01234567890E-10"},
} }
testTokenList(t, tokenList) testTokenList(t, tokenList)