@top Query { expression } @skip { whitespace | LineComment } @precedence { exp @right, mul @left, add @left, compare @left, not @left, and @left, or @left, arrow @right, pipe @left } expression { assignExpression (!pipe Pipe assignExpression)* } assignExpression { orExpression (!arrow Arrow orExpression)* } orExpression { andExpression (!or Or andExpression)* } andExpression { notExpression (!and And notExpression)* } notExpression { Not notExpression | UnaryExpression | compareExpression } UnaryExpression { AddOp postfixExpression } compareExpression { addExpression | addExpression EqualityOp addExpression | addExpression CompareOp addExpression | addExpression In addExpression | addExpression Match addExpression } addExpression { mulExpression (!add AddOp mulExpression)* } mulExpression { expExpression (!mul (MulOp | MulOp { "*" }) expExpression)* } expExpression { postfixExpression (!exp Exp postfixExpression)* } postfixExpression { primaryExpression postfixOp* } postfixOp { Filter | Projection | DotAccess | Dereference | DerefAccess | Asc | Desc } Filter { "[" filterContent "]" } filterContent { expression rangeOp expression | expression } rangeOp { InclusiveRange | Ellipsis } Projection { "{" projectionBody "}" } projectionBody { projectionEntry ("," projectionEntry)* ","? } projectionEntry { Ellipsis | PropertyPair | expression } PropertyPair { String ":" expression | Identifier ":" expression } DotAccess { "." Identifier } Dereference { Deref } DerefAccess { Deref Identifier } primaryExpression { Everything { "*" } | This | Parent | Parameter | String | Number | kw<"true", True> | kw<"false", False> | kw<"null", Null> | In | Match | Asc | Desc | NamespacedCall | FunctionCall | Identifier | ArrayLiteral | ObjectLiteral | ParenExpression } FunctionCall { FunctionName { Identifier } !exp "(" commaSep? ")" } NamespacedCall { Namespace { Identifier } NamespaceSep FunctionName { Identifier } "(" commaSep? ")" } ArrayLiteral { "[" commaSep? "]" } ObjectLiteral { "{" objectBody "}" } objectBody { objectEntry ("," objectEntry)* ","? } objectEntry { Ellipsis | String ":" expression | Identifier ":" expression } ParenExpression { "(" expression ")" } commaSep { x ("," x)* ","? } kw { @specialize[@name={name}] } @skip {} { DoubleString { doubleQuote (doubleStringContent | StringEscape)* doubleStringEnd } SingleString { singleQuote (singleStringContent | SingleStringEscape)* singleStringEnd } } String { DoubleString | SingleString } @local tokens { doubleStringEnd[@name='"'] { '"' } StringEscape { "\\" ("u{" $[0-9a-fA-F]+ "}" | "u" $[0-9a-fA-F] $[0-9a-fA-F] $[0-9a-fA-F] $[0-9a-fA-F] | _) } @else doubleStringContent } @local tokens { singleStringEnd[@name="'"] { "'" } SingleStringEscape[@name=StringEscape] { "\\" ("u{" $[0-9a-fA-F]+ "}" | "u" $[0-9a-fA-F] $[0-9a-fA-F] $[0-9a-fA-F] $[0-9a-fA-F] | _) } @else singleStringContent } @tokens { whitespace { @whitespace+ } LineComment { "//" ![\n]* } identifierChar { @asciiLetter | "_" } Identifier { identifierChar (identifierChar | @digit)* } NamespaceSep { "::" } Parameter { "$" identifierChar (identifierChar | @digit)* } doubleQuote { '"' } singleQuote { "'" } digit { @digit } Number { digit+ ("." digit+)? ($[eE] $[+\-]? digit+)? } @precedence { Number, "." } This { "@" } Parent { "^"+ } EqualityOp { "==" | "!=" } CompareOp { "<=" | ">=" | "<" | ">" } AddOp { "+" | "-" } MulOp { "/" | "%" } @precedence { LineComment, MulOp } Exp { "**" } @precedence { Exp, "*" } And { "&&" } Or { "||" } Not { "!" } @precedence { EqualityOp, Not } Pipe { "|" } @precedence { Or, Pipe } Arrow { "=>" } @precedence { Arrow, EqualityOp } Deref { "->" } Ellipsis { "..." } InclusiveRange { ".." } @precedence { Ellipsis, InclusiveRange, "." } @precedence { NamespaceSep, ":" } "(" ")" "[" "]" "{" "}" "," ":" "." } In { @specialize[@name=In] } Match { @specialize[@name=Match] } Asc { @specialize[@name=Asc] } Desc { @specialize[@name=Desc] } @external propSource groqHighlighting from "./highlight" @detectDelim