Improving parsing of time durations.

Previously, the number 0 was parsed as 0ns.

In addition, it is now not possible to have duration values defined as strings (inside “” or ‘’).

However, now values are explicitly marked as a duration only if they have a valid DURATION suffix. Anlything else is either a NUMBER of an IDENT.
This commit is contained in:
Tobie Morgan Hitchcock 2016-11-09 15:15:09 +00:00
parent fdbf38f833
commit b0f8ed6b56

View file

@ -578,8 +578,24 @@ func (s *scanner) scanNumber(chp ...rune) (tok Token, lit string, val interface{
} else if isNumber(ch) {
buf.WriteRune(ch)
} else if isLetter(ch) {
tok = IDENT
buf.WriteRune(ch)
if tok == NUMBER || tok == DOUBLE {
tok = IDENT
buf.WriteRune(ch)
switch ch {
case 's', 'h', 'd', 'w':
tok = DURATION
case 'n', 'u', 'µ', 'm':
if chn := s.next(); chn == 's' {
tok = DURATION
buf.WriteRune(chn)
} else {
s.undo()
}
}
} else {
tok = IDENT
buf.WriteRune(ch)
}
} else if ch == '.' {
if tok == DOUBLE {
tok = IDENT
@ -594,10 +610,6 @@ func (s *scanner) scanNumber(chp ...rune) (tok Token, lit string, val interface{
}
}
if val, err := time.ParseDuration(buf.String()); err == nil {
return DURATION, buf.String(), val
}
return tok, buf.String(), nil
}
@ -663,10 +675,6 @@ func (s *scanner) scanString(chp ...rune) (tok Token, lit string, val interface{
}
}
if val, err := time.ParseDuration(buf.String()); err == nil {
return DURATION, buf.String(), val
}
if val, err := time.Parse(RFCDate, buf.String()); err == nil {
return DATE, buf.String(), val.UTC()
}
@ -826,7 +834,7 @@ func isNumber(ch rune) bool {
// isLetter returns true if the rune is a letter.
func isLetter(ch rune) bool {
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == 'µ'
}
// isIdentChar returns true if the rune is allowed in a IDENT.