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()
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 {

View File

@ -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)