prometheus/pkg/textparse/lex.l

130 lines
4.2 KiB
Plaintext
Raw Normal View History

2017-01-14 15:39:04 +00:00
%{
// Copyright 2017 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2017-01-14 15:39:04 +00:00
package textparse
import (
"fmt"
"math"
"strconv"
"unicode/utf8"
"github.com/prometheus/prometheus/pkg/value"
2017-01-14 15:39:04 +00:00
)
const (
lstateInit = iota
lstateName
lstateValue
lstateTimestamp
lstateLabels
lstateLName
2018-02-04 16:37:46 +00:00
lstateLEq
lstateLValue
lstateLValueIn
)
2017-01-14 15:39:04 +00:00
// Lex is called by the parser generated by "go tool yacc" to obtain each
// token. The method is opened before the matching rules block and closed at
// the end of the file.
func (l *lexer) Lex() int {
l.state = lstateInit
2017-01-14 15:39:04 +00:00
if l.i >= len(l.b) {
return eof
}
c := l.b[l.i]
l.ts = nil
l.mstart = l.nextMstart
l.offsets = l.offsets[:0]
2017-01-14 15:39:04 +00:00
%}
D [0-9]
L [a-zA-Z_]
M [a-zA-Z_:]
2018-02-04 16:37:46 +00:00
%x lstateName lstateValue lstateTimestamp lstateLabels lstateLName lstateLEq lstateLValue lstateLValueIn
2017-01-14 15:39:04 +00:00
%yyc c
%yyn c = l.next()
%yyt l.state
2017-01-14 15:39:04 +00:00
%%
\0 return eof
#[^\r\n]*\n l.mstart = l.i
[\r\n \t]+ l.mstart = l.i
2017-01-14 15:39:04 +00:00
{M}({M}|{D})* l.state = lstateName
l.offsets = append(l.offsets, l.i)
l.mend = l.i
<lstateName>([ \t]*)\{ l.state = lstateLabels
<lstateName>[ \t]+ l.state = lstateValue
l.vstart = l.i
2017-01-14 15:39:04 +00:00
<lstateLabels>[ \t]+
<lstateLabels>,?\} l.state = lstateValue
l.mend = l.i
<lstateLabels>(,?[ \t]*) l.state = lstateLName
l.offsets = append(l.offsets, l.i)
2017-01-14 15:39:04 +00:00
2018-02-04 16:37:46 +00:00
<lstateLName>{L}({L}|{D})* l.state = lstateLEq
l.offsets = append(l.offsets, l.i)
<lstateLEq>[ \t]*= l.state = lstateLValue
2017-01-14 15:39:04 +00:00
<lstateLValue>[ \t]+
<lstateLValue>\" l.state = lstateLValueIn
l.offsets = append(l.offsets, l.i)
<lstateLValueIn>(\\.|[^\\"])*\" l.state = lstateLabels
if !utf8.Valid(l.b[l.offsets[len(l.offsets)-1]:l.i-1]) {
l.err = fmt.Errorf("invalid UTF-8 label value")
return -1
}
l.offsets = append(l.offsets, l.i-1)
2017-01-14 15:39:04 +00:00
<lstateValue>[ \t]+ l.vstart = l.i
<lstateValue>(NaN) l.val = math.Float64frombits(value.NormalNaN)
l.state = lstateTimestamp
<lstateValue>[^\n \t\r]+ // We don't parse strictly correct floats as the conversion
// repeats the effort anyway.
l.val, l.err = strconv.ParseFloat(yoloString(l.b[l.vstart:l.i]), 64)
if l.err != nil {
return -1
}
l.state = lstateTimestamp
<lstateTimestamp>[ \t]+ l.tstart = l.i
<lstateTimestamp>{D}+ ts, err := strconv.ParseInt(yoloString(l.b[l.tstart:l.i]), 10, 64)
if err != nil {
l.err = err
return -1
}
l.ts = &ts
<lstateTimestamp>[\r\n]+ l.nextMstart = l.i
return 1
<lstateTimestamp>\0 return 1
2017-01-14 15:39:04 +00:00
%%
l.err = fmt.Errorf("no token found")
2017-01-14 15:39:04 +00:00
return -1
}