influxdb/query/promql/promql.peg

310 lines
8.9 KiB
Plaintext

{
// Package promql implements a promql parser to build flux query specifications from promql.
package promql
// DO NOT EDIT: This file is auto generated by the pigeon PEG parser generator.
var reservedWords = map[string]bool{}
}
Grammar = grammar:( Comment / AggregateExpression / VectorSelector ) EOF {
return grammar, nil
}
SourceChar = .
Comment = "#" ( !EOL SourceChar )* {
return &Comment{string(c.text)}, nil
}
Identifier = ident:IdentifierName {
i := string(c.text)
if reservedWords[i] {
return nil, errors.New("identifier is a reserved word")
}
return &Identifier{ident.(string)}, nil
}
IdentifierName = IdentifierStart IdentifierPart* {
return string(c.text), nil
}
IdentifierStart = [\pL_]
IdentifierPart = IdentifierStart / [\p{Nd}]
StringLiteral = ( '"' DoubleStringChar* '"' / "'" SingleStringChar "'" / '`' RawStringChar* '`' ) {
str, err := strconv.Unquote(string(c.text))
if err != nil {
return nil, err
}
return &StringLiteral{str}, nil
} / ( ( '"' DoubleStringChar* ( EOL / EOF ) ) / ( "'" SingleStringChar? ( EOL / EOF ) ) / '`' RawStringChar* EOF ) {
return nil, errors.New("string literal not terminated")
}
DoubleStringChar = !( '"' / "\\" / EOL ) SourceChar / "\\" DoubleStringEscape
SingleStringChar = !( "'" / "\\" / EOL ) SourceChar / "\\" SingleStringEscape
RawStringChar = !'`' SourceChar
DoubleStringEscape = ( '"' / CommonEscapeSequence )
/ ( SourceChar / EOL / EOF ) {
return nil, errors.New("invalid escape character")
}
SingleStringEscape = ( "'" / CommonEscapeSequence )
/ ( SourceChar / EOL / EOF ) {
return nil, errors.New("invalid escape character")
}
CommonEscapeSequence = SingleCharEscape / OctalEscape / HexEscape / LongUnicodeEscape / ShortUnicodeEscape
SingleCharEscape = 'a' / 'b' / 'n' / 'f' / 'r' / 't' / 'v' / '\\'
OctalEscape = OctalDigit OctalDigit OctalDigit
/ OctalDigit ( SourceChar / EOL / EOF ) {
return nil, errors.New("invalid octal escape")
}
HexEscape = 'x' HexDigit HexDigit
/ 'x' ( SourceChar / EOL / EOF ) {
return nil, errors.New("invalid hexadecimal escape")
}
LongUnicodeEscape =
'U' HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit {
return validateUnicodeEscape(string(c.text), "invalid Unicode escape")
}
/ 'U' ( SourceChar / EOL / EOF ) {
return nil, errors.New("invalid Unicode escape")
}
ShortUnicodeEscape =
'u' HexDigit HexDigit HexDigit HexDigit {
return validateUnicodeEscape(string(c.text), "invalid Unicode escape")
}
/ 'u' ( SourceChar / EOL / EOF ) {
return nil, errors.New("invalid Unicode escape")
}
OctalDigit = [0-7]
DecimalDigit = [0-9]
HexDigit = [0-9a-f]i
CharClassMatcher = '[' ( ClassCharRange / ClassChar / "\\" UnicodeClassEscape )* ']' 'i'? {
return string(c.text), nil
} / '[' ( !( EOL ) SourceChar )* ( EOL / EOF ) {
return nil, errors.New("character class not terminated")
}
ClassCharRange = ClassChar '-' ClassChar
ClassChar = !( "]" / "\\" / EOL ) SourceChar / "\\" CharClassEscape
CharClassEscape = ( ']' / CommonEscapeSequence )
/ !'p' ( SourceChar / EOL / EOF ) {
return nil, errors.New("invalid escape character")
}
UnicodeClassEscape = 'p' (
SingleCharUnicodeClass
/ !'{' ( SourceChar / EOL / EOF ) { return nil, errors.New("invalid Unicode class escape") }
/ '{' ident:IdentifierName '}' {
if !unicodeClasses[ident.(string)] {
return nil, errors.New("invalid Unicode class escape")
}
return nil, nil
}
/ '{' IdentifierName ( ']' / EOL / EOF ) {
return nil, errors.New("unicode class not terminated")
}
)
SingleCharUnicodeClass = [LMNCPZS]
Number = '-'? Integer ( '.' Digit+ )? {
return NewNumber(string(c.text))
}
Integer = '0' / NonZeroDigit Digit* {
return strconv.ParseInt(string(c.text), 10, 64)
}
NonZeroDigit = [1-9]
Digit = [0-9]
LabelBlock = '{' block:LabelMatches '}' {
return block, nil
} / '{' LabelMatches EOF {
return nil, errors.New("code block not terminated")
}
NanoSecondUnits = "ns"{
// Prometheus doesn't support nanoseconds, but, influx does
return time.Nanosecond, nil
}
MicroSecondUnits = ("us" / "µs" / "μs") {
// Prometheus doesn't support nanoseconds, but, influx does
return time.Microsecond, nil
}
MilliSecondUnits = "ms" {
// Prometheus doesn't support nanoseconds, but, influx does
return time.Millisecond, nil
}
SecondUnits = "s" {
return time.Second, nil
}
MinuteUnits = "m" {
return time.Minute, nil
}
HourUnits = "h" {
return time.Hour, nil
}
DayUnits = "d" {
// Prometheus always assumes exactly 24 hours in a day
// https://github.com/prometheus/common/blob/61f87aac8082fa8c3c5655c7608d7478d46ac2ad/model/time.go#L180
return time.Hour * 24, nil
}
WeekUnits = "w" {
// Prometheus always assumes exactly 7 days in a week
// https://github.com/prometheus/common/blob/61f87aac8082fa8c3c5655c7608d7478d46ac2ad/model/time.go#L180
return time.Hour * 24 * 7, nil
}
YearUnits = "y" {
// Prometheus always assumes 365 days
// https://github.com/prometheus/common/blob/61f87aac8082fa8c3c5655c7608d7478d46ac2ad/model/time.go#L180
return time.Hour * 24 * 365, nil
}
DurationUnits = (NanoSecondUnits / MicroSecondUnits / MilliSecondUnits / SecondUnits / MinuteUnits / HourUnits / DayUnits / WeekUnits / YearUnits)
Duration = dur:Integer units:DurationUnits {
nanos := time.Duration(dur.(int64))
conversion := units.(time.Duration)
return time.Duration(nanos) * conversion, nil
}
Operators = "-" / "+" / "*" / "%" / "/" / "==" / "!=" / "<=" / "<" / ">=" / ">" / "=~" / "!~" / "^" / "="
LabelOperators = "!=" {
return NotEqual, nil
} / "=~" {
return RegexMatch, nil
} / "!~" {
return RegexNoMatch, nil
} / "=" {
return Equal, nil
}
Label = Identifier
LabelMatch = label:Label __ op:LabelOperators __ match:( StringLiteral / Number ) {
return NewLabelMatcher(label.(*Identifier), op.(MatchKind), match.(Arg))
}
LabelMatches = first:LabelMatch __ rest:LabelMatchesRest* {
return NewLabelMatches(first.(*LabelMatcher), rest)
}
LabelMatchesRest = "," __ match:LabelMatch {
return match, nil
}
LabelList = ("(" __ ")") {
return nil, nil
} / ("(" __ label:Label __ rest:LabelListRest* __ ")" {
return NewIdentifierList(label.(*Identifier), rest)
})
LabelListRest = "," __ label:Label {
return label, nil
}
VectorSelector = metric:Identifier __ block:LabelBlock? __ rng:Range? __ offset:Offset? {
return NewSelector(metric.(*Identifier), block, rng, offset)
}
Range = "[" __ dur:Duration __ "]" {
return dur, nil
}
Offset = "offset"i __ dur:Duration {
return dur, nil
}
CountValueOperator = "count_values"i {
return &Operator{
Kind: CountValuesKind,
}, nil
}
BinaryAggregateOperators = op:("topk"i / "bottomk"i / "quantile"i) {
return &Operator{
Kind: ToOperatorKind(string(op.([]byte))),
}, nil
}
UnaryAggregateOperators = op:("sum"i / "min"i / "max"i / "avg"i / "stddev"i / "stdvar"i / "count"i) {
return &Operator{
Kind: ToOperatorKind(string(op.([]byte))),
}, nil
}
AggregateOperators = CountValueOperator / BinaryAggregateOperators / UnaryAggregateOperators
AggregateBy = "by"i __ labels:LabelList __ keep:"keep_common"i? {
return &Aggregate{
By: true,
Labels: labels.([]*Identifier),
}, nil
}
AggregateWithout = "without"i __ labels:LabelList {
return &Aggregate{
Without: true,
Labels: labels.([]*Identifier),
}, nil
}
AggregateGroup = AggregateBy / AggregateWithout
AggregateExpression =
op:CountValueOperator __ "(" __ param:StringLiteral __ "," __ vector:VectorSelector __ ")" __ group:AggregateGroup? {
oper := op.(*Operator)
oper.Arg = param.(*StringLiteral)
return NewAggregateExpr(oper, vector.(*Selector), group)
}
/
op:CountValueOperator __ group:AggregateGroup? __ "(" __ param:StringLiteral __ "," __ vector:VectorSelector __ ")" {
oper := op.(*Operator)
oper.Arg = param.(*StringLiteral)
return NewAggregateExpr(oper, vector.(*Selector), group)
}
/
op:BinaryAggregateOperators __ "(" __ param:Number __ "," __ vector:VectorSelector __ ")" __ group:AggregateGroup? {
oper := op.(*Operator)
oper.Arg = param.(*Number)
return NewAggregateExpr(oper, vector.(*Selector), group)
}
/
op:BinaryAggregateOperators __ group:AggregateGroup? __ "(" __ param:Number __ "," __ vector:VectorSelector __ ")" {
oper := op.(*Operator)
oper.Arg = param.(*Number)
return NewAggregateExpr(oper, vector.(*Selector), group)
}
/
op:UnaryAggregateOperators __ "(" __ vector:VectorSelector __ ")" __ group:AggregateGroup? {
return NewAggregateExpr(op.(*Operator), vector.(*Selector), group)
}
/
op:UnaryAggregateOperators __ group:AggregateGroup? __ "(" __ vector:VectorSelector __ ")" {
return NewAggregateExpr(op.(*Operator), vector.(*Selector), group)
}
__ = ( Whitespace / EOL / Comment )*
_ = Whitespace*
Whitespace = [ \t\r]
EOL = '\n'
EOS = __ ';' / _ SingleLineComment? EOL / __ EOF
EOF = !.