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:
parent
fdbf38f833
commit
b0f8ed6b56
1 changed files with 19 additions and 11 deletions
|
@ -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) {
|
||||
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.
|
||||
|
|
Loading…
Reference in a new issue