mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-26 06:04:05 -08:00
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
|
fallthrough
|
||||||
case isAlphaNumeric(r) || r == ':':
|
case isAlpha(r) || r == ':':
|
||||||
l.backup()
|
l.backup()
|
||||||
return lexKeywordOrIdentifier
|
return lexKeywordOrIdentifier
|
||||||
case r == '(':
|
case r == '(':
|
||||||
|
@ -515,7 +515,7 @@ func lexInsideBraces(l *lexer) stateFn {
|
||||||
return l.errorf("unexpected end of input inside braces")
|
return l.errorf("unexpected end of input inside braces")
|
||||||
case isSpace(r):
|
case isSpace(r):
|
||||||
return lexSpace
|
return lexSpace
|
||||||
case unicode.IsLetter(r) || r == '_':
|
case isAlpha(r):
|
||||||
l.backup()
|
l.backup()
|
||||||
return lexIdentifier
|
return lexIdentifier
|
||||||
case r == ',':
|
case r == ',':
|
||||||
|
@ -703,5 +703,10 @@ func isEndOfLine(r rune) bool {
|
||||||
|
|
||||||
// isAlphaNumeric reports whether r is an alphabetic, digit, or underscore.
|
// isAlphaNumeric reports whether r is an alphabetic, digit, or underscore.
|
||||||
func isAlphaNumeric(r rune) bool {
|
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",
|
input: "abc d",
|
||||||
expected: []item{{itemIdentifier, 0, "abc"}, {itemIdentifier, 4, "d"}},
|
expected: []item{{itemIdentifier, 0, "abc"}, {itemIdentifier, 4, "d"}},
|
||||||
|
}, {
|
||||||
|
input: ":bc",
|
||||||
|
expected: []item{{itemMetricIdentifier, 0, ":bc"}},
|
||||||
|
}, {
|
||||||
|
input: "0a:bc",
|
||||||
|
fail: true,
|
||||||
},
|
},
|
||||||
// Test comments.
|
// Test comments.
|
||||||
{
|
{
|
||||||
|
@ -247,6 +253,12 @@ var tests = []struct {
|
||||||
{
|
{
|
||||||
input: `台北`,
|
input: `台北`,
|
||||||
fail: true,
|
fail: true,
|
||||||
|
}, {
|
||||||
|
input: `{台北='a'}`,
|
||||||
|
fail: true,
|
||||||
|
}, {
|
||||||
|
input: `{0a='a'}`,
|
||||||
|
fail: true,
|
||||||
}, {
|
}, {
|
||||||
input: `{foo='bar'}`,
|
input: `{foo='bar'}`,
|
||||||
expected: []item{
|
expected: []item{
|
||||||
|
|
|
@ -453,6 +453,19 @@ func (p *parser) rangeSelector(vs *VectorSelector) *MatrixSelector {
|
||||||
return e
|
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.
|
// primaryExpr parses a primary expression.
|
||||||
//
|
//
|
||||||
// <metric_name> | <function_call> | <vector_aggregation> | <literal>
|
// <metric_name> | <function_call> | <vector_aggregation> | <literal>
|
||||||
|
@ -460,14 +473,7 @@ func (p *parser) rangeSelector(vs *VectorSelector) *MatrixSelector {
|
||||||
func (p *parser) primaryExpr() Expr {
|
func (p *parser) primaryExpr() Expr {
|
||||||
switch t := p.next(); {
|
switch t := p.next(); {
|
||||||
case t.typ == itemNumber:
|
case t.typ == itemNumber:
|
||||||
n, err := strconv.ParseInt(t.val, 0, 64)
|
f := p.number(t.val)
|
||||||
f := float64(n)
|
|
||||||
if err != nil {
|
|
||||||
f, err = strconv.ParseFloat(t.val, 64)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
p.errorf("error parsing number: %s", err)
|
|
||||||
}
|
|
||||||
return &NumberLiteral{clientmodel.SampleValue(f)}
|
return &NumberLiteral{clientmodel.SampleValue(f)}
|
||||||
|
|
||||||
case t.typ == itemString:
|
case t.typ == itemString:
|
||||||
|
|
Loading…
Reference in a new issue