{ 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 = !.