-
Notifications
You must be signed in to change notification settings - Fork 42
/
search.peg
68 lines (55 loc) · 1.87 KB
/
search.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
64
65
66
67
68
{
function last(arr) {
return arr[arr.length - 1];
}
function concat(arr, arr2) {
return arr.concat(arr2);
}
}
start = Cross
CrossBreak
= ';' {
// return break positions, for UI
return location().start.offset;
}
Cross
= left: Expression tail:(_ CrossBreak _ Cross)* {
var rest = tail[0]; // there's only ever one
var crossbreak = 1, cross = 3; // parser objects
var exps = 1, pos = 2; // cross variant args: ['cross', exps, pos]
return rest ? ['cross', concat([left], rest[cross][exps]), concat([rest[crossbreak]], rest[cross][pos])] : ['cross', [left], []];
}
Expression
= left:Term tail:(_ 'OR' _ Term)* {
return tail.length ? concat(['or', left], tail.map(last)) : left;
}
Term
= left:Factor tail:(_ ('AND' _)? Factor)* {
return tail.length ? concat(['and', left], tail.map(last)) : left;
}
Factor
= Grouping / Field / Value / Not
Not
= 'NOT' _ factor:Factor { return ['ne', factor]; }
Grouping
= '(' exp:Expression ')' { return ['group', exp]; }
Field
= left:FieldName ":" _ right: Value {
return ['field', left, right];
}
Value = NeValue / LeValue / GeValue / LtValue / GtValue / EqValue / QuotedValue / PlainValue
PlainValue = ! 'OR' ! 'NOT' [^ \t();]+ { return ['value', text()]; }
QuotedValue = '"' [^"]* '"' {
var val = text();
return ['quoted-value', val.slice(1, val.length - 1)];
}
EqValue = '=' value:(QuotedValue / PlainValue) { return value; }
NeValue = '!=' value:(QuotedValue / PlainValue) { return ['ne', value]; }
GtValue = '>' value:PlainValue { return ['gt', value[1]]; }
LtValue = '<' value:PlainValue { return ['lt', value[1]]; }
GeValue = '>=' value:PlainValue { return ['ge', value[1]]; }
LeValue = '<=' value:PlainValue { return ['le', value[1]]; }
FieldName
= ! 'OR' ! 'NOT' [a-zA-Z][^ \t:=]* { return text(); }
_ "whitespace"
= [ \t\n\r]* {return text(); }