influxdb/query/parser/ifql.peg

484 lines
8.6 KiB
Plaintext

{
package parser
// DO NOT EDIT: This file is auto generated by the pigeon PEG parser generator.
}
Start
= __ program:Program __ EOF {
return program, nil
}
Program
= body:SourceElements {
return program(body, c.text, c.pos)
}
SourceElements
= head:SourceElement tail:(__ SourceElement __)* {
return srcElems(head, tail)
}
SourceElement
= Statement
Statement
= VariableStatement
/ ReturnStatement
/ ExpressionStatement
/ BlockStatement
VariableStatement
= declaration:VariableDeclaration {
return varstmt(declaration, c.text, c.pos)
}
ReturnStatement
= "return" __ argument:Expr {
return returnstmt(argument, c.text, c.pos)
}
ExpressionStatement
= expr:Expr {
return exprstmt(expr, c.text, c.pos)
}
BlockStatement
= "{" __ body:( __ Statement __ )* __ "}" {
return blockstmt(body, c.text, c.pos)
}
VariableDeclaration
= id:Identifier __ "=" __ init:Expr {
return vardecl(id, init, c.text, c.pos)
}
MemberExpressions
= head:Identifier // TODO: should be primary
tail:(
__ property:MemberExpressionProperty {
return property, nil
}
)*
{
return memberexprs(head, tail, c.text, c.pos)
}
MemberExpressionProperty
= "." __ property:Identifier {
return property, nil
}
/ "[" __ property:Primary __ "]" __ {
return property, nil
}
CallExpression
= head:(
callee:MemberExpressions __ args:Arguments {
return callexpr(callee, args, c.text, c.pos)
}
)
tail:(
__ args:Arguments {
return callexpr(nil, args, c.text, c.pos)
}
/ __ property:MemberExpressionProperty {
return memberexpr(nil, property, c.text, c.pos)
}
)*
{
return callexprs(head, tail, c.text, c.pos)
}
PipeExpression
= head:PipeExpressionHead __ tail:(__ PipeExpressionPipe __)+ {
return pipeExprs(head, tail, c.text, c.pos)
}
PipeExpressionHead
= CallExpression // TODO(nathanielc): Allow for more expressions as pipe heads. Cannot use Expr because it causes infinite left recursion.
/ Literal
/ Array
/ MemberExpressions
/ Identifier
/ ObjectExpression
/ ArrowFunctionExpression
/ Parens
PipeExpressionPipe
= "|>" __ call:CallExpression {
return incompletePipeExpr(call, c.text, c.pos)
}
Arguments
= "(" __ args:(ObjectProperties)? __ ")" {
return args, nil
}
ArrowFunctionExpression
= "(" __ params:ArrowFunctionParams? __ ")" __ "=>" __ body:ArrowFunctionBody __ {
return arrowfunc(params, body, c.text, c.pos), nil
}
ArrowFunctionParams
= first:ArrowFunctionParam __ rest:ArrowFunctionParamsRest* ","? {
return append([]interface{}{first}, toIfaceSlice(rest)...), nil
}
ArrowFunctionParamsRest
= "," __ arg:ArrowFunctionParam __ {
return arg, nil
}
ArrowFunctionParam
= key:Identifier __ "=" __ value:Primary __ {
return property(key, value, c.text, c.pos)
}
/ key:Identifier __ {
return property(key, nil, c.text, c.pos)
}
ArrowFunctionBody
= body:Expr {
return body, nil
}
/ body:BlockStatement {
return body, nil
}
ObjectExpression
= "{" __ object:(ObjectProperties)? __ "}" {
return object, nil
}
ObjectProperties
= first:Property __ rest:PropertiesRest* __ ","? {
return objectexpr(first, rest, c.text, c.pos)
}
PropertiesRest
= "," __ arg:Property {
return arg, nil
}
Property
= key:Identifier __ ":" __ value:Expr {
return property(key, value, c.text, c.pos)
}
// + -
// <= < >= > startsWith IN NOT EMPTY EMPTY
// == !=
// and or
// Lowest to Highest Priority.
// Highest Priority includes the valid primary
// primary contains the Lowest Priority
Expr
= LogicalExpression
LogicalOperators
= ("or"i / "and"i) {
return logicalOp(c.text)
}
LogicalExpression
= head:Equality tail:( __ LogicalOperators __ Equality )* {
return logicalExpression(head, tail, c.text, c.pos)
}
EqualityOperators
= ("==" / "!=" / "=~" / "!~") {
return operator(c.text)
}
Equality
= head:Relational tail:( __ EqualityOperators __ Relational )* {
return binaryExpression(head, tail, c.text, c.pos)
}
RelationalOperators
= ( "<="
/ "<"
/ ">="
/ ">"
/ "startswith"i
/ "in"i
/ "not empty"i
/ "empty"i
) {
return operator(c.text)
}
Relational
= head:Additive tail:( __ RelationalOperators __ Additive )* {
return binaryExpression(head, tail, c.text, c.pos)
}
AdditiveOperator
= ("+" / "-") {
return operator(c.text)
}
Additive
= head:Multiplicative tail:( __ AdditiveOperator __ Multiplicative )* {
return binaryExpression(head, tail, c.text, c.pos)
}
MultiplicativeOperator
= ("*" / "/") {
return operator(c.text)
}
Multiplicative
= head:UnaryExpression tail:( __ MultiplicativeOperator __ UnaryExpression )* {
return binaryExpression(head, tail, c.text, c.pos)
}
UnaryOperator
= ("-" / "not") {
return operator(c.text)
}
UnaryExpression
= __ op:UnaryOperator __ argument:Primary __ {
return unaryExpression(op, argument, c.text, c.pos)
}
/ Primary
Primary
= PipeExpression
/ Array
/ Literal
/ CallExpression
/ MemberExpressions
/ Identifier
/ ObjectExpression
/ ArrowFunctionExpression
/ Parens
Literal
= StringLiteral
/ BooleanLiteral
/ RegexpLiteral
/ PipeLiteral
/ DurationLiteral
/ DateTimeLiteral
/ NumberLiteral
/ IntegerLiteral
Parens
= "(" __ expr:Expr __ ")" {
return expr, nil
}
Array
= "[" __ elements:ArrayElements? __ "]" {
return elements, nil
}
ArrayElements
= first:Primary __ rest:ArrayRest* {
return array(first, rest, c.text, c.pos), nil
}
ArrayRest
= "," __ element:Primary {
return element, nil
}
DateFullYear
= Digit Digit Digit Digit
DateMonth
// 01-12
= Digit Digit
DateMDay
// 01-28, 01-29, 01-30, 01-31 based on
// month/year
= Digit Digit
TimeHour
// 00-23
= Digit Digit
TimeMinute
// 00-59
= Digit Digit
TimeSecond
// 00-58, 00-59, 00-60 based on leap second
// rules
= Digit Digit
TimeSecFrac
= "." Digit+
TimeNumOffset
= ("+" / "-") TimeHour ":" TimeMinute
TimeOffset
= ("Z" / TimeNumOffset)
PartialTime
= TimeHour ":" TimeMinute ":" TimeSecond TimeSecFrac?
FullDate
= DateFullYear "-" DateMonth "-" DateMDay
FullTime
= PartialTime TimeOffset
DateTimeLiteral
= FullDate "T" FullTime {
return datetime(c.text, c.pos)
}
NanoSecondUnits
= "ns"
MicroSecondUnits
= ("us" / "µs" / "μs")
MilliSecondUnits
= "ms"
SecondUnits
= "s"
MinuteUnits
= "m"
HourUnits
= "h"
DurationUnits
= (
NanoSecondUnits
/ MicroSecondUnits
/ MilliSecondUnits
/ SecondUnits
/ MinuteUnits
/ HourUnits
)
SingleDuration
= Integer DurationUnits
DurationLiteral
= SingleDuration+ {
return durationLiteral(c.text, c.pos)
}
StringLiteral
= ( '"' DoubleStringChar* '"' ) {
return stringLiteral(c.text, c.pos)
}
/ ( '"' DoubleStringChar* ( EOL / EOF ) ) {
return "", errors.New("string literal not terminated")
}
DoubleStringChar
= !( '"' / "\\" / EOL ) SourceChar
/ "\\" DoubleStringEscape
DoubleStringEscape
= '"'
/ ( SourceChar / EOL / EOF ) {
return nil, errors.New("invalid escape character")
}
RegexpLiteral
= "/" pattern:RegexpBody "/" {
return pattern, nil
}
RegexpBody
= chars:RegexpChar+ {
return regexLiteral(chars, c.text, c.pos)
}
RegexpChar
= ![\\/] re:RegexpNonTerminator {
return re, nil
}
/ RegexpBackslashSequence
RegexpBackslashSequence
= "\\/" {
return []byte{'/'}, nil
}
/ "\\" RegexpNonTerminator {
return c.text, nil
}
RegexpNonTerminator
= !LineTerminator SourceChar {
return c.text, nil
}
BooleanLiteral
= __ "true" __ {
return booleanLiteral(true, c.text, c.pos)
}
/ __ "false" __ {
return booleanLiteral(false, c.text, c.pos)
}
NumberLiteral
= Integer "." Digit+ {
return numberLiteral(c.text, c.pos)
}
Integer
= ("0" / NonZeroDigit Digit*)
IntegerLiteral
= Integer {
return integerLiteral(c.text, c.pos)
}
NonZeroDigit
= [1-9]
Digit
= [0-9]
PipeLiteral
= "<-" {
return pipeLiteral(c.text, c.pos), nil
}
Identifier
// Allow any unicode letter possibly followed by any number of unicode letters, underscores and numbers.
= [_\pL][_0-9\pL]* {
return identifier(c.text, c.pos)
}
SourceChar
= .
__
= ( ws / EOL / Comment )*
Comment
= "//" [^\r\n]* EOL
ws
= [ \t\r\n]
LineTerminator
= [\n\r]
EOL
= "\n"
EOF
= !.