@precedence { logic @left } @top Program { Query } Query { Name ( WhereClause | OrderClause | LimitClause | SelectClause | RenderClause )* } commaSep { content ("," content)* } WhereClause { "where" LogicalExpr } OrderClause { "order" "by" Name Order? } LimitClause { "limit" Number } SelectClause { "select" commaSep } RenderClause { "render" (PageRef | String) } Order { "desc" | "asc" } Value { Number | String | Bool | Regex | Null | List } LogicalExpr { AndExpr | FilterExpr } AndExpr { FilterExpr !logic "and" FilterExpr } FilterExpr { Name "<" Value | Name "<=" Value | Name "=" Value | Name "!=" Value | Name ">=" Value | Name ">" Value | Name "=~" Value | Name "!=~" Value | Name "in" Value } List { "[" commaSep "]" } @skip { space } Bool { "true" | "false" } Null { "null" } @tokens { space { std.whitespace+ } Name { (std.asciiLetter | "-" | "_")+ } String { ("\"" | "“" | "”") ![\"”“]* ("\"" | "“" | "”") } PageRef { "[" "[" ![\]]* "]" "]" } Regex { "/" ( ![/\\\n\r] | "\\" _ )* "/"? } Number { std.digit+ } }