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