This repository has been archived by the owner on May 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 345
/
query.peg
63 lines (46 loc) · 2.04 KB
/
query.peg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package query
# We specify the name of the generated parse to be QueryParser then Expression is a struct type that we are expected
# to define to provide parse internal state when we run parser.Execute()
type QueryParser Peg {
Expression
}
# By recursing through OR then AND AND gets stronger precedent. PEG goes depth first so the hooks that are deeper
# in the AST get run first - this allows us to naturally form code for a stack machine (implemented in Expression)
e <- eor !.
eor <- eand ( or eand { p.Operator(OpOr) })*
eand <- enot ( and enot { p.Operator(OpAnd) })*
enot <- not condition { p.Operator(OpNot) } / condition
condition <- tag sp (le (number / time / date) { p.Operator(OpLessEqual) }
/ ge (number / time / date) { p.Operator(OpGreaterEqual) }
/ l (number / time / date) { p.Operator(OpLess) }
/ g (number / time / date) { p.Operator(OpGreater) }
/ equal (number / time / date / qvalue) { p.Operator(OpEqual) }
/ ne (number / time / date / qvalue) { p.Operator(OpNotEqual) }
/ contains qvalue { p.Operator(OpContains) }
) sp / open eor close
## Terminals
tag <- < (![ \t\n\r\\()"'=><] .)+ > sp { p.Tag(buffer[begin:end]) }
qvalue <- '\'' value '\'' sp
value <- < (!["'] .)* > { p.Value(buffer[begin:end]) }
number <- < ('0' / [1-9] digit* ('.' digit*)?) > { p.Number(buffer[begin:end]) }
digit <- [0-9]
time <- "TIME " < year '-' month '-' day 'T' digit digit ':' digit digit ':' digit digit (('-' / '+') digit digit ':' digit digit / 'Z') > { p.Time(buffer[begin:end]) }
date <- "DATE " < year '-' month '-' day > { p.Date(buffer[begin:end]) }
year <- ('1' / '2') digit digit digit
month <- ('0' / '1') digit
day <- ('0' / '1' / '2' / '3') digit
## Operators
and <- "AND" sp
or <- "OR" sp
not <- "NOT" sp
equal <- "=" sp
ne <- "!=" sp
contains <- "CONTAINS" sp
le <- "<=" sp
ge <- ">=" sp
l <- "<" sp
g <- ">" sp
# Whitespace and grouping
open <- '(' sp
close <- ')' sp
sp <- (' ' / '\t')*