Make parser more strict about identifiers, extract number parsing
This commit is contained in:
parent
1b3d3b4d5c
commit
969c231191
|
@ -465,7 +465,7 @@ func lexStatements(l *lexer) stateFn {
|
|||
}
|
||||
}
|
||||
fallthrough
|
||||
case isAlphaNumeric(r) || r == ':':
|
||||
case isAlpha(r) || r == ':':
|
||||
l.backup()
|
||||
return lexKeywordOrIdentifier
|
||||
case r == '(':
|
||||
|
@ -515,7 +515,7 @@ func lexInsideBraces(l *lexer) stateFn {
|
|||
return l.errorf("unexpected end of input inside braces")
|
||||
case isSpace(r):
|
||||
return lexSpace
|
||||
case unicode.IsLetter(r) || r == '_':
|
||||
case isAlpha(r):
|
||||
l.backup()
|
||||
return lexIdentifier
|
||||
case r == ',':
|
||||
|
@ -703,5 +703,10 @@ func isEndOfLine(r rune) bool {
|
|||
|
||||
// isAlphaNumeric reports whether r is an alphabetic, digit, or underscore.
|
||||
func isAlphaNumeric(r rune) bool {
|
||||
return r == '_' || ('a' <= r && r <= 'z') || ('A' <= r && r <= 'Z') || unicode.IsDigit(r)
|
||||
return isAlpha(r) || unicode.IsDigit(r)
|
||||
}
|
||||
|
||||
// isAlpha reports whether r is an alphabetic or underscore.
|
||||
func isAlpha(r rune) bool {
|
||||
return r == '_' || ('a' <= r && r <= 'z') || ('A' <= r && r <= 'Z')
|
||||
}
|
||||
|
|
|
@ -121,6 +121,12 @@ var tests = []struct {
|
|||
}, {
|
||||
input: "abc d",
|
||||
expected: []item{{itemIdentifier, 0, "abc"}, {itemIdentifier, 4, "d"}},
|
||||
}, {
|
||||
input: ":bc",
|
||||
expected: []item{{itemMetricIdentifier, 0, ":bc"}},
|
||||
}, {
|
||||
input: "0a:bc",
|
||||
fail: true,
|
||||
},
|
||||
// Test comments.
|
||||
{
|
||||
|
@ -247,6 +253,12 @@ var tests = []struct {
|
|||
{
|
||||
input: `台北`,
|
||||
fail: true,
|
||||
}, {
|
||||
input: `{台北='a'}`,
|
||||
fail: true,
|
||||
}, {
|
||||
input: `{0a='a'}`,
|
||||
fail: true,
|
||||
}, {
|
||||
input: `{foo='bar'}`,
|
||||
expected: []item{
|
||||
|
|
|
@ -453,6 +453,19 @@ func (p *parser) rangeSelector(vs *VectorSelector) *MatrixSelector {
|
|||
return e
|
||||
}
|
||||
|
||||
// parseNumber parses a number.
|
||||
func (p *parser) number(val string) float64 {
|
||||
n, err := strconv.ParseInt(val, 0, 64)
|
||||
f := float64(n)
|
||||
if err != nil {
|
||||
f, err = strconv.ParseFloat(val, 64)
|
||||
}
|
||||
if err != nil {
|
||||
p.errorf("error parsing number: %s", err)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// primaryExpr parses a primary expression.
|
||||
//
|
||||
// <metric_name> | <function_call> | <vector_aggregation> | <literal>
|
||||
|
@ -460,14 +473,7 @@ func (p *parser) rangeSelector(vs *VectorSelector) *MatrixSelector {
|
|||
func (p *parser) primaryExpr() Expr {
|
||||
switch t := p.next(); {
|
||||
case t.typ == itemNumber:
|
||||
n, err := strconv.ParseInt(t.val, 0, 64)
|
||||
f := float64(n)
|
||||
if err != nil {
|
||||
f, err = strconv.ParseFloat(t.val, 64)
|
||||
}
|
||||
if err != nil {
|
||||
p.errorf("error parsing number: %s", err)
|
||||
}
|
||||
f := p.number(t.val)
|
||||
return &NumberLiteral{clientmodel.SampleValue(f)}
|
||||
|
||||
case t.typ == itemString:
|
||||
|
|
Loading…
Reference in New Issue