; Copyright Glen Knowles 2017 - 2018.
; Distributed under the Boost Software License, Version 1.0.
;
; query.abnf - tismet query
;
; rules to parse graphite queries
%root = query
%api.prefix = Query
%api.parser.file.h = qryparseint.h
%api.parser.file.cpp = qryparse.cpp
%api.base.file.h = qryparsebaseint.h

;----------------------------------------------------------------------------
; Root
;----------------------------------------------------------------------------
query = path / func { Function }

;----------------------------------------------------------------------------
; Path
;----------------------------------------------------------------------------
path = path-seg *("." path-seg) { Start, End }
path-seg = 1*(seg-literal / seg-blot / seg-char-list / seg-seg-list)
    { Start, End }

; *
seg-literal = 1*scl-char { Start+, End+ }
seg-blot = "*" { End }

; [] - allows '-' ranges, but not negation (leading '^')
seg-char-list = "[" [scl-dash] *(scl-single-nd ["-" scl-range-end])
    [scl-single] "]" { End }
scl-single = scl-char { Char+ }
scl-single-nd = scl-char-nd { Char+, As scl-single }
scl-dash = "-" { Char+, As scl-single }
scl-range-end = scl-char-nd { Char+ }

; {,,,}
seg-seg-list = "{" ssl-segs
ssl-segs = *WSP [path-seg] *WSP 1*(ssl-comma *WSP path-seg *WSP) "}"
    { Start, End, Function }
ssl-comma = "," { End }

scl-char-nd = ALPHA / DIGIT
    / "!" / DQUOTE / "#" / "$" / "%" / "&" / "'"
    / "+"
    / ":" / ";" / "<" / "=" / ">" / "?"
    / "@" / "\" / "^" / "_"
    / "`" / "~"
scl-char = scl-char-nd / "-"

;----------------------------------------------------------------------------
; Function arguments
;----------------------------------------------------------------------------
arg-func = *WSP func *WSP
arg-path = *WSP path *WSP
arg-path-or-func = *WSP query *WSP
arg-num = *WSP number *WSP { End }
arg-string = *WSP (DQUOTE string DQUOTE / "'" string-ns "'") *WSP
arg-aggfunc = *WSP (DQUOTE aggfunc DQUOTE / "'" aggfunc "'") *WSP

; String
string = *(%x20-21 / %x23-7E) { Start+, End+ }
string-ns = *(%x20-26 / %x28-7E) { As string, Start+, End+ }

; Timestamp
timestamp = 1*DIGIT { Char+ }

; Number
number = [minus] int [frac] [exp] ; { Function }
decimal-point = "."
digit1-9 = %x31-39 ; 1-9
e = "e" ; e E
exp = e [exp-minus / exp-plus] exp-num
exp-minus = "-" { End }
exp-plus = "+"
exp-num = 1*DIGIT { Char+ }
frac = decimal-point frac-num
frac-num = 1*DIGIT { Char+ }
int = zero / (digit1-9 *DIGIT) { Char+ }
minus = "-" { End }
zero = "0"

;----------------------------------------------------------------------------
; Functions
;----------------------------------------------------------------------------
%include =/ "queryfunc.abnf"
