@halleyassist/rule-parser 1.0.18 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/rule-parser.browser.js +3610 -0
- package/package.json +1 -1
- package/src/RuleParser.ebnf.js +44 -22
- package/src/RuleParser.js +73 -26
- package/src/RuleParser.production.ebnf.js +1 -1
- package/src/RuleParser.production.js +73 -26
- package/src/errors/ErrorAnalyzer.js +1 -1
- package/src/errors/RuleParseError.js +1 -1
package/package.json
CHANGED
package/src/RuleParser.ebnf.js
CHANGED
|
@@ -5,10 +5,10 @@ statement_main ::= statement EOF
|
|
|
5
5
|
logical_operator ||= AND | OR
|
|
6
6
|
statement ::= expression (logical_operator expression)*
|
|
7
7
|
expression ::= not_expression | standard_expression | parenthesis_expression
|
|
8
|
-
parenthesis_expression::= BEGIN_PARENTHESIS WS* statement WS* END_PARENTHESIS
|
|
8
|
+
parenthesis_expression ::= BEGIN_PARENTHESIS WS* statement WS* END_PARENTHESIS
|
|
9
9
|
not_expression ||= NOT (result | parenthesis_expression)
|
|
10
10
|
standard_expression ||= result ((WS* eq_approx) | (WS* basic_rhs) | ((WS+ IS)? WS+ between) | (WS+ in_expr))?
|
|
11
|
-
basic_rhs ::= operator WS*
|
|
11
|
+
basic_rhs ::= operator WS* result
|
|
12
12
|
eq_approx ::= eq_operator WS* "~" WS* result
|
|
13
13
|
|
|
14
14
|
PLUS ::= "+"
|
|
@@ -18,44 +18,63 @@ DIVIDE ::= "/"
|
|
|
18
18
|
MODULUS ::= "%"
|
|
19
19
|
DEFAULT_VAL ::= "??"
|
|
20
20
|
arithmetic_operator ::= PLUS | MINUS | MULTIPLY | DIVIDE | MODULUS | DEFAULT_VAL
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
|
|
22
|
+
number_atom ::= number
|
|
23
|
+
number_time_atom ::= number_time
|
|
24
|
+
tod_atom ::= number_tod
|
|
25
|
+
dow_atom ::= dow
|
|
26
|
+
|
|
27
|
+
arithmetic_operand ::= fcall | number_time_atom | number_atom
|
|
28
|
+
arithmetic_result ::= arithmetic_operand WS* arithmetic_operator WS* (arithmetic_result | arithmetic_operand)
|
|
23
29
|
|
|
24
30
|
simple_result ::= fcall | value
|
|
25
31
|
result ::= arithmetic_result | simple_result
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
|
|
33
|
+
value_atom ::= false | true | array | time_period | number_time_atom | number_atom | tod_atom | string
|
|
34
|
+
value ::= value_atom
|
|
35
|
+
|
|
36
|
+
BEGIN_ARRAY ::= WS* #x5B WS* /* [ */
|
|
37
|
+
BEGIN_OBJECT ::= WS* #x7B WS* /* { */
|
|
38
|
+
END_ARRAY ::= WS* #x5D WS* /* ] */
|
|
39
|
+
END_OBJECT ::= WS* #x7D WS* /* } */
|
|
40
|
+
NAME_SEPARATOR ::= WS* #x3A WS* /* : */
|
|
41
|
+
VALUE_SEPARATOR ::= WS* #x2C WS* /* , */
|
|
42
|
+
WS ::= [#x20#x09#x0A#x0D]
|
|
34
43
|
|
|
35
44
|
operator ::= GTE | LTE | GT | LT | EQ | NEQ
|
|
36
45
|
eq_operator ::= EQ | NEQ
|
|
37
46
|
|
|
38
47
|
BEGIN_ARGUMENT ::= "("
|
|
39
48
|
END_ARGUMENT ::= ")"
|
|
40
|
-
|
|
41
49
|
BEGIN_PARENTHESIS ::= "("
|
|
42
50
|
END_PARENTHESIS ::= ")"
|
|
43
51
|
|
|
44
52
|
BEGIN_IN ||= "IN"
|
|
45
|
-
|
|
46
53
|
in_expr ::= BEGIN_IN WS* BEGIN_PARENTHESIS WS* arguments END_PARENTHESIS
|
|
47
54
|
|
|
48
55
|
argument ::= statement WS*
|
|
49
56
|
arguments ::= argument (WS* "," WS* argument)*
|
|
50
|
-
fname ::= [
|
|
57
|
+
fname ::= [A-Za-z0-9]+
|
|
51
58
|
fcall ::= fname WS* BEGIN_ARGUMENT WS* arguments? END_ARGUMENT
|
|
52
59
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
between_dash_or_and ||= (WS+ "AND" WS+) | (WS* "-" WS*)
|
|
61
|
+
|
|
62
|
+
between_number_inner ::= number_atom | number_time_atom
|
|
63
|
+
between_number ||= between_number_inner between_dash_or_and between_number_inner
|
|
64
|
+
|
|
65
|
+
between_number_time_inner ::= number_time_atom
|
|
66
|
+
between_number_time ||= between_number_time_inner between_dash_or_and between_number_time_inner (WS+ dow_range)?
|
|
67
|
+
|
|
68
|
+
between_tod_inner ::= tod_atom
|
|
69
|
+
between_tod ||= between_tod_inner (WS+ "AND" WS+) between_tod_inner (WS+ dow_range)?
|
|
70
|
+
|
|
56
71
|
between ||= "BETWEEN" WS+ (between_number | between_tod)
|
|
72
|
+
|
|
57
73
|
dow ||= "MONDAY" | "MON" | "TUESDAY" | "TUE" | "WEDNESDAY" | "WED" | "THURSDAY" | "THU" | "THUR" | "FRIDAY" | "FRI" | "SATURDAY" | "SAT" | "SUNDAY" | "SUN"
|
|
58
|
-
|
|
74
|
+
|
|
75
|
+
dow_range_inner ::= dow_atom
|
|
76
|
+
dow_range ||= "ON" WS+ dow_range_inner (WS+ "TO" WS+ dow_range_inner)?
|
|
77
|
+
|
|
59
78
|
between_time_only ||= "BETWEEN" WS+ between_number_time
|
|
60
79
|
between_tod_only ||= "BETWEEN" WS+ between_tod
|
|
61
80
|
|
|
@@ -70,18 +89,21 @@ IS ||= "is"
|
|
|
70
89
|
EQ ::= "==" | "="
|
|
71
90
|
NEQ ::= "!="
|
|
72
91
|
NOT ||= ("!" WS*) | ("not" WS+)
|
|
92
|
+
|
|
73
93
|
false ||= "FALSE"
|
|
74
94
|
null ||= "null"
|
|
75
95
|
true ||= "TRUE"
|
|
96
|
+
|
|
76
97
|
array ::= BEGIN_ARRAY (value (VALUE_SEPARATOR value)*)? END_ARRAY
|
|
77
98
|
|
|
78
99
|
unit ||= "seconds" | "minutes" | "hours" | "weeks" | "days" | "second" | "minute" | "week" | "hour" | "day" | "mins" | "min"
|
|
79
|
-
|
|
100
|
+
|
|
101
|
+
number ::= "-"? ([0-9]+) ("." [0-9]+)? ("e" ("-" | "+")? ("0" | [1-9] [0-9]*))?
|
|
80
102
|
number_time ::= number WS+ unit
|
|
81
103
|
number_tod ::= ([0-9]+) ":" ([0-9]+)
|
|
82
104
|
|
|
83
|
-
time_period_ago ||=
|
|
84
|
-
time_period_ago_between ||=
|
|
105
|
+
time_period_ago ||= number_time_atom (WS+ number_time_atom)* WS+ AGO
|
|
106
|
+
time_period_ago_between ||= number_time_atom (WS+ number_time_atom)* WS+ AGO WS+ between_tod_only
|
|
85
107
|
time_period_const ||= "today" | time_period_ago
|
|
86
108
|
time_period ::= time_period_ago_between | time_period_const | between_tod_only | between_time_only
|
|
87
109
|
|
package/src/RuleParser.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const {Parser} = require('ebnf/dist/Parser.js'),
|
|
2
2
|
{ParsingError} = require('ebnf'),
|
|
3
|
-
assert = require('assert')
|
|
3
|
+
assert = require('assert'),
|
|
4
|
+
RuleParseError = require('./errors/RuleParseError')
|
|
4
5
|
|
|
5
6
|
let ParserRules = require('./RuleParser.ebnf.js')
|
|
6
7
|
let ParserCache;
|
|
@@ -108,10 +109,14 @@ class RuleParser {
|
|
|
108
109
|
// dow_range can have 1 or 2 children (single day or range)
|
|
109
110
|
if (dowRange.children.length === 1) {
|
|
110
111
|
// Single day: ON MONDAY - return just the day string
|
|
111
|
-
|
|
112
|
+
// New structure: dow_range -> dow_range_inner -> dow_atom -> dow
|
|
113
|
+
const dayText = RuleParser.__parseValue(dowRange.children[0])
|
|
114
|
+
return { start: dayText, end: dayText };
|
|
112
115
|
} else if (dowRange.children.length === 2) {
|
|
113
116
|
// Range: ON MONDAY TO FRIDAY - return both start and end days
|
|
114
|
-
|
|
117
|
+
const startDay = RuleParser.__parseValue(dowRange.children[0])
|
|
118
|
+
const endDay = RuleParser.__parseValue(dowRange.children[1])
|
|
119
|
+
return { start: startDay, end: endDay };
|
|
115
120
|
} else {
|
|
116
121
|
throw new Error(`Invalid dow_range with ${dowRange.children.length} children`);
|
|
117
122
|
}
|
|
@@ -133,12 +138,14 @@ class RuleParser {
|
|
|
133
138
|
let totalSeconds = 0
|
|
134
139
|
const components = []
|
|
135
140
|
for (const child of timePeriodAgo.children) {
|
|
136
|
-
if (child.type === '
|
|
137
|
-
|
|
138
|
-
const
|
|
141
|
+
if (child.type === 'number_time_atom') {
|
|
142
|
+
// New structure: number_time_atom -> number_time -> number, unit
|
|
143
|
+
const numberTime = child.children[0]
|
|
144
|
+
const number = parseFloat(numberTime.children[0].text)
|
|
145
|
+
const unit = numberTime.children[1].text.toUpperCase()
|
|
139
146
|
components.push([number, unit])
|
|
140
147
|
// Parse the value to get seconds
|
|
141
|
-
totalSeconds += RuleParser.__parseValue(
|
|
148
|
+
totalSeconds += RuleParser.__parseValue(numberTime)
|
|
142
149
|
}
|
|
143
150
|
}
|
|
144
151
|
// If there's only one component, use its number and unit
|
|
@@ -151,15 +158,16 @@ class RuleParser {
|
|
|
151
158
|
}
|
|
152
159
|
return ["TimePeriodConst", tp.text]
|
|
153
160
|
case 'time_period_ago_between': {
|
|
154
|
-
// time_period_ago_between has:
|
|
161
|
+
// time_period_ago_between has: number_time_atom (WS+ number_time_atom)* WS+ AGO WS+ between_tod_only
|
|
155
162
|
// We need to extract all number_time children and sum them up, then return TimePeriodBetweenAgo
|
|
156
163
|
let totalSeconds = 0
|
|
157
164
|
let betweenTodOnly = null
|
|
158
165
|
|
|
159
|
-
// Find all
|
|
166
|
+
// Find all number_time_atom children and the between_tod_only child
|
|
160
167
|
for (let i = 0; i < tp.children.length; i++) {
|
|
161
|
-
if (tp.children[i].type === '
|
|
162
|
-
|
|
168
|
+
if (tp.children[i].type === 'number_time_atom') {
|
|
169
|
+
// New structure: number_time_atom -> number_time
|
|
170
|
+
totalSeconds += RuleParser.__parseValue(tp.children[i].children[0])
|
|
163
171
|
} else if (tp.children[i].type === 'between_tod_only') {
|
|
164
172
|
betweenTodOnly = tp.children[i]
|
|
165
173
|
}
|
|
@@ -171,6 +179,7 @@ class RuleParser {
|
|
|
171
179
|
}
|
|
172
180
|
|
|
173
181
|
const betweenTod = betweenTodOnly.children[0]
|
|
182
|
+
// between_tod has inline separator, so: children[0] = first tod_inner, children[1] = second tod_inner, children[2] = optional dow_range
|
|
174
183
|
let startTod = RuleParser.__parseValue(betweenTod.children[0])
|
|
175
184
|
let endTod = RuleParser.__parseValue(betweenTod.children[1])
|
|
176
185
|
|
|
@@ -185,6 +194,7 @@ class RuleParser {
|
|
|
185
194
|
case 'between_tod_only': {
|
|
186
195
|
// between_tod_only has children[0] = between_tod node
|
|
187
196
|
const betweenTod = tp.children[0]
|
|
197
|
+
// between_tod has inline separator, so: children[0] = first tod_inner, children[1] = second tod_inner, children[2] = optional dow_range
|
|
188
198
|
let startTod = RuleParser.__parseValue(betweenTod.children[0])
|
|
189
199
|
let endTod = RuleParser.__parseValue(betweenTod.children[1])
|
|
190
200
|
|
|
@@ -200,13 +210,14 @@ class RuleParser {
|
|
|
200
210
|
case 'between_time_only': {
|
|
201
211
|
// between_time_only has children[0] = between_number_time node
|
|
202
212
|
const betweenNumberTime = tp.children[0]
|
|
213
|
+
// between_number_time has: children[0] = first time_inner, children[1] = separator, children[2] = second time_inner, children[3] = optional dow_range
|
|
203
214
|
const startValue = RuleParser.__parseValue(betweenNumberTime.children[0])
|
|
204
|
-
const endValue = RuleParser.__parseValue(betweenNumberTime.children[
|
|
215
|
+
const endValue = RuleParser.__parseValue(betweenNumberTime.children[2])
|
|
205
216
|
|
|
206
|
-
// Check if there's a dow_range at betweenNumberTime.children[
|
|
217
|
+
// Check if there's a dow_range at betweenNumberTime.children[3]
|
|
207
218
|
// If DOW filters are provided, append them as additional parameters
|
|
208
|
-
if (betweenNumberTime.children.length >
|
|
209
|
-
const dow = RuleParser._parseDowRange(betweenNumberTime.children[
|
|
219
|
+
if (betweenNumberTime.children.length > 3 && betweenNumberTime.children[3].type === 'dow_range') {
|
|
220
|
+
const dow = RuleParser._parseDowRange(betweenNumberTime.children[3])
|
|
210
221
|
if (dow.start === dow.end) {
|
|
211
222
|
// Single day: ["TimePeriodBetween", start, end, "MONDAY"]
|
|
212
223
|
return ["TimePeriodBetween", startValue, endValue, dow.start]
|
|
@@ -223,6 +234,25 @@ class RuleParser {
|
|
|
223
234
|
static __parseValue(child){
|
|
224
235
|
const type = child.type
|
|
225
236
|
switch(type){
|
|
237
|
+
case 'value': {
|
|
238
|
+
// Arrays have value nodes as children - unwrap to get value_atom
|
|
239
|
+
return RuleParser.__parseValue(child.children[0])
|
|
240
|
+
}
|
|
241
|
+
case 'value_atom': {
|
|
242
|
+
// New layer: unwrap value_atom to get the actual atomic type
|
|
243
|
+
return RuleParser.__parseValue(child.children[0])
|
|
244
|
+
}
|
|
245
|
+
case 'number_atom':
|
|
246
|
+
case 'number_time_atom':
|
|
247
|
+
case 'tod_atom':
|
|
248
|
+
case 'dow_atom':
|
|
249
|
+
case 'between_tod_inner':
|
|
250
|
+
case 'between_number_inner':
|
|
251
|
+
case 'between_number_time_inner':
|
|
252
|
+
case 'dow_range_inner': {
|
|
253
|
+
// New layer: unwrap atom wrappers to get the actual leaf nodes
|
|
254
|
+
return RuleParser.__parseValue(child.children[0])
|
|
255
|
+
}
|
|
226
256
|
case 'string': {
|
|
227
257
|
const str = child.text
|
|
228
258
|
return str.slice(1, -1)
|
|
@@ -274,10 +304,13 @@ class RuleParser {
|
|
|
274
304
|
case 'array': {
|
|
275
305
|
const ret = []
|
|
276
306
|
for(const c of child.children){
|
|
277
|
-
ret.push(RuleParser.__parseValue(c
|
|
307
|
+
ret.push(RuleParser.__parseValue(c))
|
|
278
308
|
}
|
|
279
309
|
return ret;
|
|
280
310
|
}
|
|
311
|
+
case 'dow': {
|
|
312
|
+
return normalizeDow(child.text)
|
|
313
|
+
}
|
|
281
314
|
default:
|
|
282
315
|
throw new Error(`Unknown value type ${type}`)
|
|
283
316
|
}
|
|
@@ -287,7 +320,17 @@ class RuleParser {
|
|
|
287
320
|
|
|
288
321
|
const type = child.type
|
|
289
322
|
switch(type){
|
|
323
|
+
case 'value_atom': {
|
|
324
|
+
// New layer: unwrap value_atom to get the actual atomic type
|
|
325
|
+
const atomChild = child.children[0]
|
|
326
|
+
if (atomChild.type === 'time_period') {
|
|
327
|
+
const tp = atomChild.children[0]
|
|
328
|
+
return RuleParser._parseTimePeriod(tp)
|
|
329
|
+
}
|
|
330
|
+
return ['Value', RuleParser.__parseValue(atomChild)]
|
|
331
|
+
}
|
|
290
332
|
case 'time_period': {
|
|
333
|
+
// Old structure (shouldn't happen with new EBNF)
|
|
291
334
|
const tp = child.children[0]
|
|
292
335
|
return RuleParser._parseTimePeriod(tp)
|
|
293
336
|
}
|
|
@@ -314,6 +357,11 @@ class RuleParser {
|
|
|
314
357
|
switch(type){
|
|
315
358
|
case 'fcall':
|
|
316
359
|
return RuleParser._parseFcall(child)
|
|
360
|
+
case 'number_atom':
|
|
361
|
+
case 'number_time_atom': {
|
|
362
|
+
// New layer: unwrap atom wrappers to get the actual leaf nodes
|
|
363
|
+
return ['Value', RuleParser.__parseValue(child.children[0])]
|
|
364
|
+
}
|
|
317
365
|
case 'number':
|
|
318
366
|
return ['Value', parseFloat(child.text)]
|
|
319
367
|
case 'number_time':
|
|
@@ -406,7 +454,7 @@ class RuleParser {
|
|
|
406
454
|
switch(rhs.type){
|
|
407
455
|
case 'between_tod': {
|
|
408
456
|
// Direct between_tod (without wrapping between node)
|
|
409
|
-
// between_tod has: children[0] = first
|
|
457
|
+
// between_tod has inline separator, so: children[0] = first tod_inner, children[1] = second tod_inner, children[2] = optional dow_range
|
|
410
458
|
const startTod = RuleParser.__parseValue(rhs.children[0])
|
|
411
459
|
const endTod = RuleParser.__parseValue(rhs.children[1])
|
|
412
460
|
|
|
@@ -421,7 +469,7 @@ class RuleParser {
|
|
|
421
469
|
// between wraps either between_number or between_tod
|
|
422
470
|
const betweenChild = rhs.children[0]
|
|
423
471
|
if (betweenChild.type === 'between_tod') {
|
|
424
|
-
// between_tod has: children[0] = first
|
|
472
|
+
// between_tod has inline separator, so: children[0] = first tod_inner, children[1] = second tod_inner, children[2] = optional dow_range
|
|
425
473
|
const startTod = RuleParser.__parseValue(betweenChild.children[0])
|
|
426
474
|
const endTod = RuleParser.__parseValue(betweenChild.children[1])
|
|
427
475
|
|
|
@@ -432,12 +480,13 @@ class RuleParser {
|
|
|
432
480
|
|
|
433
481
|
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', startTod], ['Value', endTod]]
|
|
434
482
|
} else {
|
|
435
|
-
// between_number
|
|
436
|
-
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', RuleParser.__parseValue(betweenChild.children[0])], ['Value', RuleParser.__parseValue(betweenChild.children[
|
|
483
|
+
// between_number has: children[0] = first number_inner, children[1] = separator, children[2] = second number_inner
|
|
484
|
+
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', RuleParser.__parseValue(betweenChild.children[0])], ['Value', RuleParser.__parseValue(betweenChild.children[2])]]
|
|
437
485
|
}
|
|
438
486
|
}
|
|
439
487
|
case 'between_number':
|
|
440
|
-
|
|
488
|
+
// between_number has: children[0] = first number_inner, children[1] = separator, children[2] = second number_inner
|
|
489
|
+
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', RuleParser.__parseValue(rhs.children[0].children[0])], ['Value', RuleParser.__parseValue(rhs.children[0].children[2])]]
|
|
441
490
|
case 'basic_rhs':
|
|
442
491
|
return [OperatorFn[rhs.children[0].text], RuleParser._parseResult(expr.children[0]), RuleParser._parseResult(rhs.children[1])]
|
|
443
492
|
case 'eq_approx': {
|
|
@@ -559,8 +608,6 @@ class RuleParser {
|
|
|
559
608
|
// Extract the invalid time from the error message
|
|
560
609
|
const match = e.message.match(/Invalid time of day[,:]?\s*([0-9:]+)/);
|
|
561
610
|
const badTod = match ? match[1] : 'invalid';
|
|
562
|
-
const { ParsingError } = require('ebnf');
|
|
563
|
-
const { RuleParseError } = require('./errors/RuleParseError');
|
|
564
611
|
|
|
565
612
|
// Calculate position (simplified - at end of input)
|
|
566
613
|
const lines = txt.trim().split('\n');
|
|
@@ -585,7 +632,6 @@ class RuleParser {
|
|
|
585
632
|
if (e.message && e.message.includes('Invalid day of week')) {
|
|
586
633
|
const match = e.message.match(/Invalid day of week[,:]?\s*(\w+)/);
|
|
587
634
|
const badDow = match ? match[1] : 'invalid';
|
|
588
|
-
const { RuleParseError } = require('./errors/RuleParseError');
|
|
589
635
|
|
|
590
636
|
const lines = txt.trim().split('\n');
|
|
591
637
|
const position = {
|
|
@@ -611,5 +657,6 @@ class RuleParser {
|
|
|
611
657
|
}
|
|
612
658
|
}
|
|
613
659
|
module.exports = RuleParser
|
|
614
|
-
module.exports.
|
|
615
|
-
module.exports.
|
|
660
|
+
module.exports.ParserRules = ParserRules
|
|
661
|
+
module.exports.ParsingError = ParsingError
|
|
662
|
+
module.exports.RuleParseError = RuleParseError
|
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports=[{"name":"statement_main","bnf":[["statement","EOF"]]},{"name":"logical_operator","bnf":[["AND"],["OR"]]},{"name":"%statement[2]","bnf":[["logical_operator","expression"]],"fragment":true},{"name":"statement","bnf":[["expression","%statement[2]*"]]},{"name":"expression","bnf":[["not_expression"],["standard_expression"],["parenthesis_expression"]]},{"name":"parenthesis_expression","bnf":[["BEGIN_PARENTHESIS","WS*","statement","WS*","END_PARENTHESIS"]]},{"name":"%not_expression[2]","bnf":[["result"],["parenthesis_expression"]],"fragment":true},{"name":"not_expression","bnf":[["NOT","%not_expression[2]"]]},{"name":"%standard_expression[2][1]","bnf":[["WS*","eq_approx"]],"fragment":true},{"name":"%standard_expression[2][2]","bnf":[["WS*","basic_rhs"]],"fragment":true},{"name":"%standard_expression[2][3][1]","bnf":[["WS+","IS"]],"fragment":true},{"name":"%standard_expression[2][3]","bnf":[["%standard_expression[2][3][1]?","WS+","between"]],"fragment":true},{"name":"%standard_expression[2][4]","bnf":[["WS+","in_expr"]],"fragment":true},{"name":"%standard_expression[2]","bnf":[["%standard_expression[2][1]"],["%standard_expression[2][2]"],["%standard_expression[2][3]"],["%standard_expression[2][4]"]],"fragment":true},{"name":"standard_expression","bnf":[["result","%standard_expression[2]?"]]},{"name":"basic_rhs","bnf":[["operator","WS*","result"]]},{"name":"eq_approx","bnf":[["eq_operator","WS*","\"~\"","WS*","result"]]},{"name":"PLUS","bnf":[["\"+\""]]},{"name":"MINUS","bnf":[["\"-\""]]},{"name":"MULTIPLY","bnf":[["\"*\""]]},{"name":"DIVIDE","bnf":[["\"/\""]]},{"name":"MODULUS","bnf":[["\"%\""]]},{"name":"DEFAULT_VAL","bnf":[["\"??\""]]},{"name":"arithmetic_operator","bnf":[["PLUS"],["MINUS"],["MULTIPLY"],["DIVIDE"],["MODULUS"],["DEFAULT_VAL"]]},{"name":"arithmetic_operand","bnf":[["fcall"],["
|
|
1
|
+
module.exports=[{"name":"statement_main","bnf":[["statement","EOF"]]},{"name":"logical_operator","bnf":[["AND"],["OR"]]},{"name":"%statement[2]","bnf":[["logical_operator","expression"]],"fragment":true},{"name":"statement","bnf":[["expression","%statement[2]*"]]},{"name":"expression","bnf":[["not_expression"],["standard_expression"],["parenthesis_expression"]]},{"name":"parenthesis_expression","bnf":[["BEGIN_PARENTHESIS","WS*","statement","WS*","END_PARENTHESIS"]]},{"name":"%not_expression[2]","bnf":[["result"],["parenthesis_expression"]],"fragment":true},{"name":"not_expression","bnf":[["NOT","%not_expression[2]"]]},{"name":"%standard_expression[2][1]","bnf":[["WS*","eq_approx"]],"fragment":true},{"name":"%standard_expression[2][2]","bnf":[["WS*","basic_rhs"]],"fragment":true},{"name":"%standard_expression[2][3][1]","bnf":[["WS+","IS"]],"fragment":true},{"name":"%standard_expression[2][3]","bnf":[["%standard_expression[2][3][1]?","WS+","between"]],"fragment":true},{"name":"%standard_expression[2][4]","bnf":[["WS+","in_expr"]],"fragment":true},{"name":"%standard_expression[2]","bnf":[["%standard_expression[2][1]"],["%standard_expression[2][2]"],["%standard_expression[2][3]"],["%standard_expression[2][4]"]],"fragment":true},{"name":"standard_expression","bnf":[["result","%standard_expression[2]?"]]},{"name":"basic_rhs","bnf":[["operator","WS*","result"]]},{"name":"eq_approx","bnf":[["eq_operator","WS*","\"~\"","WS*","result"]]},{"name":"PLUS","bnf":[["\"+\""]]},{"name":"MINUS","bnf":[["\"-\""]]},{"name":"MULTIPLY","bnf":[["\"*\""]]},{"name":"DIVIDE","bnf":[["\"/\""]]},{"name":"MODULUS","bnf":[["\"%\""]]},{"name":"DEFAULT_VAL","bnf":[["\"??\""]]},{"name":"arithmetic_operator","bnf":[["PLUS"],["MINUS"],["MULTIPLY"],["DIVIDE"],["MODULUS"],["DEFAULT_VAL"]]},{"name":"number_atom","bnf":[["number"]]},{"name":"number_time_atom","bnf":[["number_time"]]},{"name":"tod_atom","bnf":[["number_tod"]]},{"name":"dow_atom","bnf":[["dow"]]},{"name":"arithmetic_operand","bnf":[["fcall"],["number_time_atom"],["number_atom"]]},{"name":"%arithmetic_result[5]","bnf":[["arithmetic_result"],["arithmetic_operand"]],"fragment":true},{"name":"arithmetic_result","bnf":[["arithmetic_operand","WS*","arithmetic_operator","WS*","%arithmetic_result[5]"]]},{"name":"simple_result","bnf":[["fcall"],["value"]]},{"name":"result","bnf":[["arithmetic_result"],["simple_result"]]},{"name":"value_atom","bnf":[["false"],["true"],["array"],["time_period"],["number_time_atom"],["number_atom"],["tod_atom"],["string"]]},{"name":"value","bnf":[["value_atom"]]},{"name":"BEGIN_ARRAY","bnf":[["WS*",/\x5B/,"WS*"]]},{"name":"BEGIN_OBJECT","bnf":[["WS*",/\x7B/,"WS*"]]},{"name":"END_ARRAY","bnf":[["WS*",/\x5D/,"WS*"]]},{"name":"END_OBJECT","bnf":[["WS*",/\x7D/,"WS*"]]},{"name":"NAME_SEPARATOR","bnf":[["WS*",/\x3A/,"WS*"]]},{"name":"VALUE_SEPARATOR","bnf":[["WS*",/\x2C/,"WS*"]]},{"name":"WS","bnf":[[/[\x20\x09\x0A\x0D]/]]},{"name":"operator","bnf":[["GTE"],["LTE"],["GT"],["LT"],["EQ"],["NEQ"]]},{"name":"eq_operator","bnf":[["EQ"],["NEQ"]]},{"name":"BEGIN_ARGUMENT","bnf":[["\"(\""]]},{"name":"END_ARGUMENT","bnf":[["\")\""]]},{"name":"BEGIN_PARENTHESIS","bnf":[["\"(\""]]},{"name":"END_PARENTHESIS","bnf":[["\")\""]]},{"name":"BEGIN_IN","bnf":[[/[Ii]/,/[Nn]/]]},{"name":"in_expr","bnf":[["BEGIN_IN","WS*","BEGIN_PARENTHESIS","WS*","arguments","END_PARENTHESIS"]]},{"name":"argument","bnf":[["statement","WS*"]]},{"name":"%arguments[2]","bnf":[["WS*","\",\"","WS*","argument"]],"fragment":true},{"name":"arguments","bnf":[["argument","%arguments[2]*"]]},{"name":"%fname[1]","bnf":[[/[A-Za-z0-9]/]]},{"name":"fname","bnf":[["%fname[1]+"]]},{"name":"fcall","bnf":[["fname","WS*","BEGIN_ARGUMENT","WS*","arguments?","END_ARGUMENT"]]},{"name":"%between_dash_or_and[1]","bnf":[["WS+",/[Aa]/,/[Nn]/,/[Dd]/,"WS+"]],"fragment":true},{"name":"%between_dash_or_and[2]","bnf":[["WS*",/\-/,"WS*"]],"fragment":true},{"name":"between_dash_or_and","bnf":[["%between_dash_or_and[1]"],["%between_dash_or_and[2]"]]},{"name":"between_number_inner","bnf":[["number_atom"],["number_time_atom"]]},{"name":"between_number","bnf":[["between_number_inner","between_dash_or_and","between_number_inner"]]},{"name":"between_number_time_inner","bnf":[["number_time_atom"]]},{"name":"%between_number_time[4]","bnf":[["WS+","dow_range"]],"fragment":true},{"name":"between_number_time","bnf":[["between_number_time_inner","between_dash_or_and","between_number_time_inner","%between_number_time[4]?"]]},{"name":"between_tod_inner","bnf":[["tod_atom"]]},{"name":"%between_tod[2]","bnf":[["WS+",/[Aa]/,/[Nn]/,/[Dd]/,"WS+"]],"fragment":true},{"name":"%between_tod[4]","bnf":[["WS+","dow_range"]],"fragment":true},{"name":"between_tod","bnf":[["between_tod_inner","%between_tod[2]","between_tod_inner","%between_tod[4]?"]]},{"name":"%between[3]","bnf":[["between_number"],["between_tod"]],"fragment":true},{"name":"between","bnf":[[/[Bb]/,/[Ee]/,/[Tt]/,/[Ww]/,/[Ee]/,/[Ee]/,/[Nn]/,"WS+","%between[3]"]]},{"name":"dow","bnf":[[/[Mm]/,/[Oo]/,/[Nn]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Mm]/,/[Oo]/,/[Nn]/],[/[Tt]/,/[Uu]/,/[Ee]/,/[Ss]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Tt]/,/[Uu]/,/[Ee]/],[/[Ww]/,/[Ee]/,/[Dd]/,/[Nn]/,/[Ee]/,/[Ss]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Ww]/,/[Ee]/,/[Dd]/],[/[Tt]/,/[Hh]/,/[Uu]/,/[Rr]/,/[Ss]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Tt]/,/[Hh]/,/[Uu]/],[/[Tt]/,/[Hh]/,/[Uu]/,/[Rr]/],[/[Ff]/,/[Rr]/,/[Ii]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Ff]/,/[Rr]/,/[Ii]/],[/[Ss]/,/[Aa]/,/[Tt]/,/[Uu]/,/[Rr]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Ss]/,/[Aa]/,/[Tt]/],[/[Ss]/,/[Uu]/,/[Nn]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Ss]/,/[Uu]/,/[Nn]/]]},{"name":"dow_range_inner","bnf":[["dow_atom"]]},{"name":"%dow_range[4]","bnf":[["WS+",/[Tt]/,/[Oo]/,"WS+","dow_range_inner"]],"fragment":true},{"name":"dow_range","bnf":[[/[Oo]/,/[Nn]/,"WS+","dow_range_inner","%dow_range[4]?"]]},{"name":"between_time_only","bnf":[[/[Bb]/,/[Ee]/,/[Tt]/,/[Ww]/,/[Ee]/,/[Ee]/,/[Nn]/,"WS+","between_number_time"]]},{"name":"between_tod_only","bnf":[[/[Bb]/,/[Ee]/,/[Tt]/,/[Ww]/,/[Ee]/,/[Ee]/,/[Nn]/,"WS+","between_tod"]]},{"name":"%AND[1]","bnf":[["WS*",/&/,/&/,"WS*"]],"fragment":true},{"name":"%AND[2]","bnf":[["WS+",/[Aa]/,/[Nn]/,/[Dd]/,"WS+"]],"fragment":true},{"name":"AND","bnf":[["%AND[1]"],["%AND[2]"]]},{"name":"%OR[1]","bnf":[["WS*",/\|/,/\|/,"WS*"]],"fragment":true},{"name":"%OR[2]","bnf":[["WS+",/[Oo]/,/[Rr]/,"WS+"]],"fragment":true},{"name":"OR","bnf":[["%OR[1]"],["%OR[2]"]]},{"name":"AGO","bnf":[[/[Aa]/,/[Gg]/,/[Oo]/]]},{"name":"GT","bnf":[["\">\""]]},{"name":"LT","bnf":[["\"<\""]]},{"name":"GTE","bnf":[["\">=\""]]},{"name":"LTE","bnf":[["\"<=\""]]},{"name":"IS","bnf":[[/[Ii]/,/[Ss]/]]},{"name":"EQ","bnf":[["\"==\""],["\"=\""]]},{"name":"NEQ","bnf":[["\"!=\""]]},{"name":"%NOT[1]","bnf":[[/!/,"WS*"]],"fragment":true},{"name":"%NOT[2]","bnf":[[/[Nn]/,/[Oo]/,/[Tt]/,"WS+"]],"fragment":true},{"name":"NOT","bnf":[["%NOT[1]"],["%NOT[2]"]]},{"name":"false","bnf":[[/[Ff]/,/[Aa]/,/[Ll]/,/[Ss]/,/[Ee]/]]},{"name":"null","bnf":[[/[Nn]/,/[Uu]/,/[Ll]/,/[Ll]/]]},{"name":"true","bnf":[[/[Tt]/,/[Rr]/,/[Uu]/,/[Ee]/]]},{"name":"%array[2][2]","bnf":[["VALUE_SEPARATOR","value"]],"fragment":true},{"name":"%array[2]","bnf":[["value","%array[2][2]*"]],"fragment":true},{"name":"array","bnf":[["BEGIN_ARRAY","%array[2]?","END_ARRAY"]]},{"name":"unit","bnf":[[/[Ss]/,/[Ee]/,/[Cc]/,/[Oo]/,/[Nn]/,/[Dd]/,/[Ss]/],[/[Mm]/,/[Ii]/,/[Nn]/,/[Uu]/,/[Tt]/,/[Ee]/,/[Ss]/],[/[Hh]/,/[Oo]/,/[Uu]/,/[Rr]/,/[Ss]/],[/[Ww]/,/[Ee]/,/[Ee]/,/[Kk]/,/[Ss]/],[/[Dd]/,/[Aa]/,/[Yy]/,/[Ss]/],[/[Ss]/,/[Ee]/,/[Cc]/,/[Oo]/,/[Nn]/,/[Dd]/],[/[Mm]/,/[Ii]/,/[Nn]/,/[Uu]/,/[Tt]/,/[Ee]/],[/[Ww]/,/[Ee]/,/[Ee]/,/[Kk]/],[/[Hh]/,/[Oo]/,/[Uu]/,/[Rr]/],[/[Dd]/,/[Aa]/,/[Yy]/],[/[Mm]/,/[Ii]/,/[Nn]/,/[Ss]/],[/[Mm]/,/[Ii]/,/[Nn]/]]},{"name":"%number[2][1]","bnf":[[/[0-9]/]]},{"name":"%number[2]","bnf":[["%number[2][1]+"]],"fragment":true},{"name":"%number[3][2]","bnf":[[/[0-9]/]]},{"name":"%number[3]","bnf":[["\".\"","%number[3][2]+"]],"fragment":true},{"name":"%number[4][2]","bnf":[["\"-\""],["\"+\""]],"fragment":true},{"name":"%number[4][3][2]","bnf":[[/[0-9]/]]},{"name":"%number[4][3]","bnf":[["\"0\""],[/[1-9]/,"%number[4][3][2]*"]],"fragment":true},{"name":"%number[4]","bnf":[["\"e\"","%number[4][2]?","%number[4][3]"]],"fragment":true},{"name":"number","bnf":[["\"-\"?","%number[2]","%number[3]?","%number[4]?"]]},{"name":"number_time","bnf":[["number","WS+","unit"]]},{"name":"%number_tod[1][1]","bnf":[[/[0-9]/]]},{"name":"%number_tod[1]","bnf":[["%number_tod[1][1]+"]],"fragment":true},{"name":"%number_tod[3][1]","bnf":[[/[0-9]/]]},{"name":"%number_tod[3]","bnf":[["%number_tod[3][1]+"]],"fragment":true},{"name":"number_tod","bnf":[["%number_tod[1]","\":\"","%number_tod[3]"]]},{"name":"%time_period_ago[2]","bnf":[["WS+","number_time_atom"]],"fragment":true},{"name":"time_period_ago","bnf":[["number_time_atom","%time_period_ago[2]*","WS+","AGO"]]},{"name":"%time_period_ago_between[2]","bnf":[["WS+","number_time_atom"]],"fragment":true},{"name":"time_period_ago_between","bnf":[["number_time_atom","%time_period_ago_between[2]*","WS+","AGO","WS+","between_tod_only"]]},{"name":"time_period_const","bnf":[[/[Tt]/,/[Oo]/,/[Dd]/,/[Aa]/,/[Yy]/],["time_period_ago"]]},{"name":"time_period","bnf":[["time_period_ago_between"],["time_period_const"],["between_tod_only"],["between_time_only"]]},{"name":"%string[2][1]","bnf":[[/[\x20-\x21]/],[/[\x23-\x5B]/],[/[\x5D-\uFFFF]/]],"fragment":true},{"name":"%string[2][2]","bnf":[[/\x22/],[/\x5C/],[/\x2F/],[/\x62/],[/\x66/],[/\x6E/],[/\x72/],[/\x74/],[/\x75/,"HEXDIG","HEXDIG","HEXDIG","HEXDIG"]],"fragment":true},{"name":"%string[2]","bnf":[["%string[2][1]"],[/\x5C/,"%string[2][2]"]],"fragment":true},{"name":"string","bnf":[["'\"'","%string[2]*","'\"'"]]},{"name":"HEXDIG","bnf":[[/[a-fA-F0-9]/]]}]
|