Skip to content

Instantly share code, notes, and snippets.

@arrdem
Created May 1, 2023 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arrdem/2e768d6feeb66ec3ae75ff64d8980c64 to your computer and use it in GitHub Desktop.
Save arrdem/2e768d6feeb66ec3ae75ff64d8980c64 to your computer and use it in GitHub Desktop.
// A mostly complete implementation of the PromQL parse grammar
?start: expr+
// PromQL defines a bunch of suffix modifiers which we have to support
expr: simple_expr vector_range? vector_offset? vector_at?
?simple_expr: parenthetical | binary | invocation | vector_expr | literal
parenthetical: "(" expr ")"
// https://prometheus.io/docs/prometheus/latest/querying/operators/#binary-operator-precedence
// Note left-recursion at same precedence level, order inversion for priority
?binary: bin_or
bin_or: [bin_or or_op] bin_lconj
or_op: "or" | "OR" // Why is upcase allowed? Silly
bin_lconj: [bin_lconj lconj_op] bin_comp
lconj_op: "and" | "unless"
bin_comp: [bin_comp comp_op "bool"?] bin_arith
comp_op: "==" | "!=" | "<=" | "<" | ">=" | ">"
bin_arith: [bin_arith arith_op] bin_mul
arith_op: "+" | "-"
bin_mul: [bin_mul mul_op] bin_expt
mul_op: "*" | "/" | "%" | "atan2"
bin_expt: [bin_expt "^"] bin_match
bin_match: match_on? bin_agg
bin_agg: aggregation | expr
namelist: "(" [ NAME ("," NAME)* ","? ] ")"
match_on: m namelist grouping?
m: "ignoring" | "on"
grouping: grp namelist?
grp: "group_left" | "group_right"
?aggregation: aggr_cp
| aggr_pc
arglist: "(" [ expr ("," expr)* ","? ] ")"
aggr_cp: AGGREGATOR arglist aggr_clause?
aggr_pc: AGGREGATOR aggr_clause? arglist
aggr_clause: agg namelist
agg: "by" | "without"
invocation: FUNCTION arglist
vector_expr: NAME ("{" [ label_filter ("," label_filter)* ","? ] "}")?
vector_at: "@" literal
vector_range: "[" literal (":" literal?)? "]"
vector_offset: "offset" literal
label_filter: (NAME|VAR) MATCHER (STRING|VAR)
literal: DURATION
| FLOAT
| STRING
| VAR
STRING: /"([^"]|\\")*?"/ | /'([^']|\\')*?'/ | /`([^`]|\\`)*?`/
FLOAT: /[-+]?([0-9]+(\.?[0-9]+)?([eE][-+]?[0-9]+)?|0[xX][0-9a-fA-F]+|[nN][aA][nN]|[iI][nN][fF])/
AGGREGATOR: /sum/
| /min/
| /max/
| /avg/
| /group/
| /stddev/
| /stdvar/
| /count/
| /count_values/
| /bottomk/
| /topk/
| /quantile/
FUNCTION: /abs/
| /absent/
| /absent_over_time/
| /ceil/
| /changes/
| /clamp/
| /clamp_max/
| /clamp_min/
| /count/
| /day_of_month/
| /day_of_week/
| /day_of_year/
| /days_in_month/
| /delta/
| /deriv/
| /exp/
| /floor/
| /histogram_count/
| /histogram_sum/
| /histogram_fraction/
| /histogram_quantile/
| /holt_winters/
| /hour/
| /idelta/
| /increase/
| /irate/
| /label_join/
| /label_replace/
| /ln/
| /log2/
| /log10/
| /minute/
| /month/
| /predict_linear/
| /rate/
| /resets/
| /round/
| /scalar/
| /sgn/
| /sort/
| /sort_desc/
| /sqrt/
| /time/
| /timestamp/
| /vector/
| /year/
| /avg_over_time/
| /min_over_time/
| /max_over_time/
| /sum_over_time/
| /count_over_time/
| /quantile_over_time/
| /stddev_over_time/
| /stdvar_over_time/
| /last_over_time/
| /present_over_time/
| /acos/
| /acosh/
| /asin/
| /asinh/
| /atan/
| /atanh/
| /cos/
| /cosh/
| /sin/
| /sinh/
| /tan/
| /tanh/
| /deg/
| /pi/
| /rad/
| /average/
NAME: /[a-zA-Z_:][a-zA-Z_:\d]+/
VAR: "$" NAME | "${" NAME "}"
MATCHER: /!=|=~|!~|=/
MATHOP: /[\+\-\*\/%]/
COMPAREOP: /==|(>|<)=?/
DURATION: /\d+[YMwdhms]/
WHITESPACE: /[\s\r\n]+/
%ignore WHITESPACE
COMMENT: "//" /.*?\n/
%ignore COMMENT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment