-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfilter-dsl.pegjs
132 lines (108 loc) · 2.73 KB
/
filter-dsl.pegjs
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* Simple Filtering Grammar
* ==========================
*
* Accepts expressions like:
* - "foo"
* - "is:node & name:foo"
* - "foo & version:1.2.3"
* - "is:comp & bound:chan"
*/
Query
= head:Expr tail:(_ '|' _ Expr)* {
if (tail.length > 0) {
return {
type: 'or',
content: [head].concat(tail.map(function (e, i) {
return tail[i][3];
}))
};
}
return head;
}
Expr
= head:Term tail:(_ '&' _ Term)* {
if (tail.length > 0) {
return {
type: 'and',
content: [head].concat(tail.map(function (e, i) {
return tail[i][3];
}))
};
}
return head;
}
Term
= '(' _ query:Query _ ')' { return query; }
/ Filter
Filter
= Is
/ Version
/ Bound
/ Tag
/ Name
Name 'name:'
= 'name:' id:IdentifierOrRegex {
return { type: 'name', content: id };
}
Is 'is:'
= 'is:' id:Identifier {
return { type: 'is', content: id };
}
Version 'vers:'
= 'vers:' op:('>'/'<'/'>='/'<=')? id:IdentifierOrRegex {
var expr = { type: 'vers', content: id };
if (op === '>') { expr.operator = 'gt'; }
if (op === '<') { expr.operator = 'lt'; }
if (op === '>=') { expr.operator = 'ge'; }
if (op === '<=') { expr.operator = 'le'; }
return expr;
}
Tag 'tag:'
= 'tag:' id:IdentifierOrRegex {
return { type: 'tag', content: id };
}
Bound 'bound:'
= 'bound:' target:Identifier ':' id:IdentifierOrRegex {
return { type: 'bound', target: target, content: id };
}
IdentifierOrRegex 'identifier or regex'
= Identifier
/ RegularExpressionLiteral
Identifier 'identifier'
= [a-zA-Z0-9\.]+ { return text(); }
RegularExpressionLiteral "regular expression"
= "/" pattern:$RegularExpressionBody "/" flags:('g'/'m'/'i'/'') {
var value;
try {
value = new RegExp(pattern, flags);
} catch (e) {
error(e.message);
}
return { type: "regex", content: value };
}
RegularExpressionBody
= RegularExpressionFirstChar RegularExpressionChar*
RegularExpressionFirstChar
= ![*\\/[] RegularExpressionNonTerminator
/ RegularExpressionBackslashSequence
/ RegularExpressionClass
RegularExpressionChar
= ![\\/[] RegularExpressionNonTerminator
/ RegularExpressionBackslashSequence
/ RegularExpressionClass
RegularExpressionBackslashSequence
= "\\" RegularExpressionNonTerminator
RegularExpressionNonTerminator
= !LineTerminator SourceCharacter
RegularExpressionClass
= "[" RegularExpressionClassChar* "]"
RegularExpressionClassChar
= ![\]\\] RegularExpressionNonTerminator
/ RegularExpressionBackslashSequence
LineTerminator
= [\n\r\u2028\u2029]
SourceCharacter
= .
_ 'whitespace'
= [ \t]*