@halleyassist/rule-parser 1.0.8 → 1.0.9
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/package.json
CHANGED
package/src/RuleParser.ebnf.js
CHANGED
|
@@ -45,9 +45,12 @@ arguments ::= argument*
|
|
|
45
45
|
fname ::= [a-zA-z0-9]+
|
|
46
46
|
fcall ::= fname WS* BEGIN_ARGUMENT WS* arguments? END_ARGUMENT
|
|
47
47
|
|
|
48
|
-
between_number ||= number ((WS+ "AND" WS+) | (WS* "-" WS*)) number
|
|
49
|
-
between_tod ||= number_tod ((WS+ "AND" WS+)) number_tod
|
|
48
|
+
between_number ||= (number_time | number) ((WS+ "AND" WS+) | (WS* "-" WS*)) (number_time | number)
|
|
49
|
+
between_tod ||= number_tod ((WS+ "AND" WS+)) number_tod (WS+ dow_range)?
|
|
50
50
|
between ||= "BETWEEN" WS+ (between_number | between_tod)
|
|
51
|
+
dow ||= "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY"
|
|
52
|
+
dow_range ||= "ON" WS+ dow (WS+ "TO" WS+ dow)?
|
|
53
|
+
between_number_only ||= "BETWEEN" WS+ between_number
|
|
51
54
|
between_tod_only ||= "BETWEEN" WS+ between_tod
|
|
52
55
|
|
|
53
56
|
AND ||= (WS* "&&" WS*) | (WS+ "AND" WS+)
|
|
@@ -71,7 +74,7 @@ number_time ::= number WS+ unit
|
|
|
71
74
|
number_tod ::= ([0-9]+) ":" ([0-9]+)
|
|
72
75
|
|
|
73
76
|
time_period_const ||= "today"
|
|
74
|
-
time_period ::= time_period_const | between_tod_only
|
|
77
|
+
time_period ::= time_period_const | between_tod_only | between_number_only
|
|
75
78
|
|
|
76
79
|
string ::= '"' (([#x20-#x21] | [#x23-#x5B] | [#x5D-#xFFFF]) | #x5C (#x22 | #x5C | #x2F | #x62 | #x66 | #x6E | #x72 | #x74 | #x75 HEXDIG HEXDIG HEXDIG HEXDIG))* '"'
|
|
77
80
|
HEXDIG ::= [a-fA-F0-9]
|
package/src/RuleParser.js
CHANGED
|
@@ -62,12 +62,55 @@ class RuleParser {
|
|
|
62
62
|
}
|
|
63
63
|
return ret
|
|
64
64
|
}
|
|
65
|
+
static _parseDowRange(dowRange) {
|
|
66
|
+
const dow = []
|
|
67
|
+
|
|
68
|
+
// dow_range can have 1 or 2 children (single day or range)
|
|
69
|
+
if (dowRange.children.length === 1) {
|
|
70
|
+
// Single day: ON MONDAY
|
|
71
|
+
dow.push(dowRange.children[0].text.toLowerCase())
|
|
72
|
+
} else if (dowRange.children.length === 2) {
|
|
73
|
+
// Range: ON MONDAY TO WEDNESDAY
|
|
74
|
+
dow.push(dowRange.children[0].text.toLowerCase())
|
|
75
|
+
dow.push(dowRange.children[1].text.toLowerCase())
|
|
76
|
+
} else {
|
|
77
|
+
throw new Error(`Invalid dow_range with ${dowRange.children.length} children`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return dow
|
|
81
|
+
}
|
|
82
|
+
static _addDowToTods(startTod, endTod, dowRange) {
|
|
83
|
+
if (dowRange && dowRange.type === 'dow_range') {
|
|
84
|
+
const dow = RuleParser._parseDowRange(dowRange)
|
|
85
|
+
startTod.dow = dow
|
|
86
|
+
endTod.dow = dow
|
|
87
|
+
}
|
|
88
|
+
}
|
|
65
89
|
static _parseTimePeriod(tp){
|
|
66
90
|
switch(tp.type){
|
|
67
91
|
case 'time_period_const':
|
|
68
92
|
return ["TimePeriodConst", tp.text]
|
|
69
|
-
case 'between_tod_only':
|
|
70
|
-
|
|
93
|
+
case 'between_tod_only': {
|
|
94
|
+
// between_tod_only has children[0] = between_tod node
|
|
95
|
+
const betweenTod = tp.children[0]
|
|
96
|
+
const startTod = RuleParser.__parseValue(betweenTod.children[0])
|
|
97
|
+
const endTod = RuleParser.__parseValue(betweenTod.children[1])
|
|
98
|
+
|
|
99
|
+
// Check if there's a dow_range at betweenTod.children[2]
|
|
100
|
+
if (betweenTod.children.length > 2) {
|
|
101
|
+
RuleParser._addDowToTods(startTod, endTod, betweenTod.children[2])
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return ["TimePeriodBetween", startTod, endTod]
|
|
105
|
+
}
|
|
106
|
+
case 'between_number_only': {
|
|
107
|
+
// between_number_only has children[0] = between_number node
|
|
108
|
+
const betweenNumber = tp.children[0]
|
|
109
|
+
const startValue = RuleParser.__parseValue(betweenNumber.children[0])
|
|
110
|
+
const endValue = RuleParser.__parseValue(betweenNumber.children[1])
|
|
111
|
+
|
|
112
|
+
return ["TimePeriodBetween", startValue, endValue]
|
|
113
|
+
}
|
|
71
114
|
}
|
|
72
115
|
}
|
|
73
116
|
static __parseValue(child){
|
|
@@ -191,9 +234,39 @@ class RuleParser {
|
|
|
191
234
|
case 2: {
|
|
192
235
|
const rhs = expr.children[1]
|
|
193
236
|
switch(rhs.type){
|
|
194
|
-
case 'between_tod':
|
|
237
|
+
case 'between_tod': {
|
|
238
|
+
// Direct between_tod (without wrapping between node)
|
|
239
|
+
// between_tod has: children[0] = first tod, children[1] = second tod, children[2] = optional dow_range
|
|
240
|
+
const startTod = RuleParser.__parseValue(rhs.children[0])
|
|
241
|
+
const endTod = RuleParser.__parseValue(rhs.children[1])
|
|
242
|
+
|
|
243
|
+
// Check if there's a dow_range (children[2])
|
|
244
|
+
if (rhs.children.length > 2) {
|
|
245
|
+
RuleParser._addDowToTods(startTod, endTod, rhs.children[2])
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', startTod], ['Value', endTod]]
|
|
249
|
+
}
|
|
250
|
+
case 'between': {
|
|
251
|
+
// between wraps either between_number or between_tod
|
|
252
|
+
const betweenChild = rhs.children[0]
|
|
253
|
+
if (betweenChild.type === 'between_tod') {
|
|
254
|
+
// between_tod has: children[0] = first tod, children[1] = second tod, children[2] = optional dow_range
|
|
255
|
+
const startTod = RuleParser.__parseValue(betweenChild.children[0])
|
|
256
|
+
const endTod = RuleParser.__parseValue(betweenChild.children[1])
|
|
257
|
+
|
|
258
|
+
// Check if there's a dow_range (children[2])
|
|
259
|
+
if (betweenChild.children.length > 2) {
|
|
260
|
+
RuleParser._addDowToTods(startTod, endTod, betweenChild.children[2])
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', startTod], ['Value', endTod]]
|
|
264
|
+
} else {
|
|
265
|
+
// between_number - no dow support
|
|
266
|
+
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', RuleParser.__parseValue(betweenChild.children[0])], ['Value', RuleParser.__parseValue(betweenChild.children[1])]]
|
|
267
|
+
}
|
|
268
|
+
}
|
|
195
269
|
case 'between_number':
|
|
196
|
-
case 'between':
|
|
197
270
|
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', RuleParser.__parseValue(rhs.children[0].children[0])], ['Value', RuleParser.__parseValue(rhs.children[0].children[1])]]
|
|
198
271
|
case 'basic_rhs':
|
|
199
272
|
return [OperatorFn[rhs.children[0].text], RuleParser._parseResult(expr.children[0]), RuleParser._parseResult(rhs.children[1])]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports=[{"name":"statement_main","bnf":[["statement","EOF"]]},{"name":"logical_operator","bnf":[["AND"],["OR"]]},{"name":"%statement0","bnf":[["logical_operator","expression"]],"fragment":true},{"name":"statement","bnf":[["expression","%statement0*"]]},{"name":"expression","bnf":[["not_expression"],["standard_expression"],["parenthesis_expression"]]},{"name":"parenthesis_expression","bnf":[["BEGIN_PARENTHESIS","WS*","statement","WS*","END_PARENTHESIS"]]},{"name":"%not_expression1","bnf":[["result"],["parenthesis_expression"]],"fragment":true},{"name":"not_expression","bnf":[["NOT","%not_expression1"]]},{"name":"%%standard_expression23","bnf":[["WS*","eq_approx"]],"fragment":true},{"name":"%%standard_expression24","bnf":[["WS*","basic_rhs"]],"fragment":true},{"name":"%%%standard_expression256","bnf":[["WS+","IS"]],"fragment":true},{"name":"%%standard_expression25","bnf":[["%%%standard_expression256?","WS+","between"]],"fragment":true},{"name":"%standard_expression2","bnf":[["%%standard_expression23"],["%%standard_expression24"],["%%standard_expression25"]],"fragment":true},{"name":"standard_expression","bnf":[["result","%standard_expression2?"]]},{"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_result7","bnf":[["arithmetic_result"],["simple_result"]],"fragment":true},{"name":"arithmetic_result","bnf":[["simple_result","WS*","arithmetic_operator","WS*","%arithmetic_result7"]]},{"name":"simple_result","bnf":[["fcall"],["value"]]},{"name":"result","bnf":[["arithmetic_result"],["simple_result"]]},{"name":"value","bnf":[["false"],["true"],["array"],["number_time"],["number"],["number_tod"],["time_period"],["string"]]},{"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":"%WS8","bnf":[[/[\x20\x09\x0A\x0D]/]]},{"name":"WS","bnf":[["%WS8+"]]},{"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":"%argument9","bnf":[["\",\"","WS*"]],"fragment":true},{"name":"argument","bnf":[["statement","WS*","%argument9?"]]},{"name":"arguments","bnf":[["argument*"]]},{"name":"%fname10","bnf":[[/[a-zA-z0-9]/]]},{"name":"fname","bnf":[["%fname10+"]]},{"name":"fcall","bnf":[["fname","WS*","BEGIN_ARGUMENT","WS*","arguments?","END_ARGUMENT"]]},{"name":"%%
|
|
1
|
+
module.exports=[{"name":"statement_main","bnf":[["statement","EOF"]]},{"name":"logical_operator","bnf":[["AND"],["OR"]]},{"name":"%statement0","bnf":[["logical_operator","expression"]],"fragment":true},{"name":"statement","bnf":[["expression","%statement0*"]]},{"name":"expression","bnf":[["not_expression"],["standard_expression"],["parenthesis_expression"]]},{"name":"parenthesis_expression","bnf":[["BEGIN_PARENTHESIS","WS*","statement","WS*","END_PARENTHESIS"]]},{"name":"%not_expression1","bnf":[["result"],["parenthesis_expression"]],"fragment":true},{"name":"not_expression","bnf":[["NOT","%not_expression1"]]},{"name":"%%standard_expression23","bnf":[["WS*","eq_approx"]],"fragment":true},{"name":"%%standard_expression24","bnf":[["WS*","basic_rhs"]],"fragment":true},{"name":"%%%standard_expression256","bnf":[["WS+","IS"]],"fragment":true},{"name":"%%standard_expression25","bnf":[["%%%standard_expression256?","WS+","between"]],"fragment":true},{"name":"%standard_expression2","bnf":[["%%standard_expression23"],["%%standard_expression24"],["%%standard_expression25"]],"fragment":true},{"name":"standard_expression","bnf":[["result","%standard_expression2?"]]},{"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_result7","bnf":[["arithmetic_result"],["simple_result"]],"fragment":true},{"name":"arithmetic_result","bnf":[["simple_result","WS*","arithmetic_operator","WS*","%arithmetic_result7"]]},{"name":"simple_result","bnf":[["fcall"],["value"]]},{"name":"result","bnf":[["arithmetic_result"],["simple_result"]]},{"name":"value","bnf":[["false"],["true"],["array"],["number_time"],["number"],["number_tod"],["time_period"],["string"]]},{"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":"%WS8","bnf":[[/[\x20\x09\x0A\x0D]/]]},{"name":"WS","bnf":[["%WS8+"]]},{"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":"%argument9","bnf":[["\",\"","WS*"]],"fragment":true},{"name":"argument","bnf":[["statement","WS*","%argument9?"]]},{"name":"arguments","bnf":[["argument*"]]},{"name":"%fname10","bnf":[[/[a-zA-z0-9]/]]},{"name":"fname","bnf":[["%fname10+"]]},{"name":"fcall","bnf":[["fname","WS*","BEGIN_ARGUMENT","WS*","arguments?","END_ARGUMENT"]]},{"name":"%between_number11","bnf":[["number_time"],["number"]],"fragment":true},{"name":"%%between_number1213","bnf":[["WS+",/[Aa]/,/[Nn]/,/[Dd]/,"WS+"]],"fragment":true},{"name":"%%between_number1214","bnf":[["WS*",/\-/,"WS*"]],"fragment":true},{"name":"%between_number12","bnf":[["%%between_number1213"],["%%between_number1214"]],"fragment":true},{"name":"%between_number15","bnf":[["number_time"],["number"]],"fragment":true},{"name":"between_number","bnf":[["%between_number11","%between_number12","%between_number15"]]},{"name":"%%between_tod1617","bnf":[["WS+",/[Aa]/,/[Nn]/,/[Dd]/,"WS+"]],"fragment":true},{"name":"%between_tod16","bnf":[["%%between_tod1617"]],"fragment":true},{"name":"%between_tod18","bnf":[["WS+","dow_range"]],"fragment":true},{"name":"between_tod","bnf":[["number_tod","%between_tod16","number_tod","%between_tod18?"]]},{"name":"%between19","bnf":[["between_number"],["between_tod"]],"fragment":true},{"name":"between","bnf":[[/[Bb]/,/[Ee]/,/[Tt]/,/[Ww]/,/[Ee]/,/[Ee]/,/[Nn]/,"WS+","%between19"]]},{"name":"dow","bnf":[[/[Mm]/,/[Oo]/,/[Nn]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Tt]/,/[Uu]/,/[Ee]/,/[Ss]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Ww]/,/[Ee]/,/[Dd]/,/[Nn]/,/[Ee]/,/[Ss]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Tt]/,/[Hh]/,/[Uu]/,/[Rr]/,/[Ss]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Ff]/,/[Rr]/,/[Ii]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Ss]/,/[Aa]/,/[Tt]/,/[Uu]/,/[Rr]/,/[Dd]/,/[Aa]/,/[Yy]/],[/[Ss]/,/[Uu]/,/[Nn]/,/[Dd]/,/[Aa]/,/[Yy]/]]},{"name":"%dow_range20","bnf":[["WS+",/[Tt]/,/[Oo]/,"WS+","dow"]],"fragment":true},{"name":"dow_range","bnf":[[/[Oo]/,/[Nn]/,"WS+","dow","%dow_range20?"]]},{"name":"between_number_only","bnf":[[/[Bb]/,/[Ee]/,/[Tt]/,/[Ww]/,/[Ee]/,/[Ee]/,/[Nn]/,"WS+","between_number"]]},{"name":"between_tod_only","bnf":[[/[Bb]/,/[Ee]/,/[Tt]/,/[Ww]/,/[Ee]/,/[Ee]/,/[Nn]/,"WS+","between_tod"]]},{"name":"%AND21","bnf":[["WS*",/&/,/&/,"WS*"]],"fragment":true},{"name":"%AND22","bnf":[["WS+",/[Aa]/,/[Nn]/,/[Dd]/,"WS+"]],"fragment":true},{"name":"AND","bnf":[["%AND21"],["%AND22"]]},{"name":"%OR23","bnf":[["WS*",/\|/,/\|/,"WS*"]],"fragment":true},{"name":"%OR24","bnf":[["WS+",/[Oo]/,/[Rr]/,"WS+"]],"fragment":true},{"name":"OR","bnf":[["%OR23"],["%OR24"]]},{"name":"GT","bnf":[["\">\""]]},{"name":"LT","bnf":[["\"<\""]]},{"name":"GTE","bnf":[["\">=\""]]},{"name":"LTE","bnf":[["\"<=\""]]},{"name":"IS","bnf":[[/[Ii]/,/[Ss]/]]},{"name":"EQ","bnf":[["\"==\""],["\"=\""]]},{"name":"NEQ","bnf":[["\"!=\""]]},{"name":"%NOT25","bnf":[[/!/,"WS*"]],"fragment":true},{"name":"%NOT26","bnf":[[/[Nn]/,/[Oo]/,/[Tt]/,"WS+"]],"fragment":true},{"name":"NOT","bnf":[["%NOT25"],["%NOT26"]]},{"name":"false","bnf":[[/[Ff]/,/[Aa]/,/[Ll]/,/[Ss]/,/[Ee]/]]},{"name":"null","bnf":[[/[Nn]/,/[Uu]/,/[Ll]/,/[Ll]/]]},{"name":"true","bnf":[[/[Tt]/,/[Rr]/,/[Uu]/,/[Ee]/]]},{"name":"%%array2728","bnf":[["VALUE_SEPARATOR","value"]],"fragment":true},{"name":"%array27","bnf":[["value","%%array2728*"]],"fragment":true},{"name":"array","bnf":[["BEGIN_ARRAY","%array27?","END_ARRAY"]]},{"name":"unit","bnf":[[/[Ss]/,/[Ee]/,/[Cc]/,/[Oo]/,/[Nn]/,/[Dd]/,/[Ss]/],[/[Ss]/,/[Ee]/,/[Cc]/,/[Oo]/,/[Nn]/,/[Dd]/],[/[Mm]/,/[Ii]/,/[Nn]/,/[Uu]/,/[Tt]/,/[Ee]/,/[Ss]/],[/[Mm]/,/[Ii]/,/[Nn]/,/[Uu]/,/[Tt]/,/[Ee]/],[/[Mm]/,/[Ii]/,/[Nn]/],[/[Mm]/,/[Ii]/,/[Nn]/,/[Ss]/],[/[Mm]/,/[Ii]/,/[Nn]/],[/[Hh]/,/[Oo]/,/[Uu]/,/[Rr]/,/[Ss]/],[/[Hh]/,/[Oo]/,/[Uu]/,/[Rr]/],[/[Dd]/,/[Aa]/,/[Yy]/,/[Ss]/],[/[Dd]/,/[Aa]/,/[Yy]/],[/[Ww]/,/[Ee]/,/[Ee]/,/[Kk]/,/[Ss]/],[/[Ww]/,/[Ee]/,/[Ee]/,/[Kk]/]]},{"name":"%%number2930","bnf":[[/[0-9]/]]},{"name":"%number29","bnf":[["%%number2930+"]],"fragment":true},{"name":"%%number3132","bnf":[[/[0-9]/]]},{"name":"%number31","bnf":[["\".\"","%%number3132+"]],"fragment":true},{"name":"%%number3334","bnf":[["\"-\""],["\"+\""]],"fragment":true},{"name":"%%%number333536","bnf":[[/[0-9]/]]},{"name":"%%number3335","bnf":[["\"0\""],[/[1-9]/,"%%%number333536*"]],"fragment":true},{"name":"%number33","bnf":[["\"e\"","%%number3334?","%%number3335"]],"fragment":true},{"name":"number","bnf":[["\"-\"?","%number29","%number31?","%number33?"]]},{"name":"number_time","bnf":[["number","WS+","unit"]]},{"name":"%%number_tod3738","bnf":[[/[0-9]/]]},{"name":"%number_tod37","bnf":[["%%number_tod3738+"]],"fragment":true},{"name":"%%number_tod3940","bnf":[[/[0-9]/]]},{"name":"%number_tod39","bnf":[["%%number_tod3940+"]],"fragment":true},{"name":"number_tod","bnf":[["%number_tod37","\":\"","%number_tod39"]]},{"name":"time_period_const","bnf":[[/[Tt]/,/[Oo]/,/[Dd]/,/[Aa]/,/[Yy]/]]},{"name":"time_period","bnf":[["time_period_const"],["between_tod_only"],["between_number_only"]]},{"name":"%%string4142","bnf":[[/[\x20-\x21]/],[/[\x23-\x5B]/],[/[\x5D-\uFFFF]/]],"fragment":true},{"name":"%%string4143","bnf":[[/\x22/],[/\x5C/],[/\x2F/],[/\x62/],[/\x66/],[/\x6E/],[/\x72/],[/\x74/],[/\x75/,"HEXDIG","HEXDIG","HEXDIG","HEXDIG"]],"fragment":true},{"name":"%string41","bnf":[["%%string4142"],[/\x5C/,"%%string4143"]],"fragment":true},{"name":"string","bnf":[["'\"'","%string41*","'\"'"]]},{"name":"HEXDIG","bnf":[[/[a-fA-F0-9]/]]}]
|
|
@@ -62,12 +62,55 @@ class RuleParser {
|
|
|
62
62
|
}
|
|
63
63
|
return ret
|
|
64
64
|
}
|
|
65
|
+
static _parseDowRange(dowRange) {
|
|
66
|
+
const dow = []
|
|
67
|
+
|
|
68
|
+
// dow_range can have 1 or 2 children (single day or range)
|
|
69
|
+
if (dowRange.children.length === 1) {
|
|
70
|
+
// Single day: ON MONDAY
|
|
71
|
+
dow.push(dowRange.children[0].text.toLowerCase())
|
|
72
|
+
} else if (dowRange.children.length === 2) {
|
|
73
|
+
// Range: ON MONDAY TO WEDNESDAY
|
|
74
|
+
dow.push(dowRange.children[0].text.toLowerCase())
|
|
75
|
+
dow.push(dowRange.children[1].text.toLowerCase())
|
|
76
|
+
} else {
|
|
77
|
+
throw new Error(`Invalid dow_range with ${dowRange.children.length} children`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return dow
|
|
81
|
+
}
|
|
82
|
+
static _addDowToTods(startTod, endTod, dowRange) {
|
|
83
|
+
if (dowRange && dowRange.type === 'dow_range') {
|
|
84
|
+
const dow = RuleParser._parseDowRange(dowRange)
|
|
85
|
+
startTod.dow = dow
|
|
86
|
+
endTod.dow = dow
|
|
87
|
+
}
|
|
88
|
+
}
|
|
65
89
|
static _parseTimePeriod(tp){
|
|
66
90
|
switch(tp.type){
|
|
67
91
|
case 'time_period_const':
|
|
68
92
|
return ["TimePeriodConst", tp.text]
|
|
69
|
-
case 'between_tod_only':
|
|
70
|
-
|
|
93
|
+
case 'between_tod_only': {
|
|
94
|
+
// between_tod_only has children[0] = between_tod node
|
|
95
|
+
const betweenTod = tp.children[0]
|
|
96
|
+
const startTod = RuleParser.__parseValue(betweenTod.children[0])
|
|
97
|
+
const endTod = RuleParser.__parseValue(betweenTod.children[1])
|
|
98
|
+
|
|
99
|
+
// Check if there's a dow_range at betweenTod.children[2]
|
|
100
|
+
if (betweenTod.children.length > 2) {
|
|
101
|
+
RuleParser._addDowToTods(startTod, endTod, betweenTod.children[2])
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return ["TimePeriodBetween", startTod, endTod]
|
|
105
|
+
}
|
|
106
|
+
case 'between_number_only': {
|
|
107
|
+
// between_number_only has children[0] = between_number node
|
|
108
|
+
const betweenNumber = tp.children[0]
|
|
109
|
+
const startValue = RuleParser.__parseValue(betweenNumber.children[0])
|
|
110
|
+
const endValue = RuleParser.__parseValue(betweenNumber.children[1])
|
|
111
|
+
|
|
112
|
+
return ["TimePeriodBetween", startValue, endValue]
|
|
113
|
+
}
|
|
71
114
|
}
|
|
72
115
|
}
|
|
73
116
|
static __parseValue(child){
|
|
@@ -191,9 +234,39 @@ class RuleParser {
|
|
|
191
234
|
case 2: {
|
|
192
235
|
const rhs = expr.children[1]
|
|
193
236
|
switch(rhs.type){
|
|
194
|
-
case 'between_tod':
|
|
237
|
+
case 'between_tod': {
|
|
238
|
+
// Direct between_tod (without wrapping between node)
|
|
239
|
+
// between_tod has: children[0] = first tod, children[1] = second tod, children[2] = optional dow_range
|
|
240
|
+
const startTod = RuleParser.__parseValue(rhs.children[0])
|
|
241
|
+
const endTod = RuleParser.__parseValue(rhs.children[1])
|
|
242
|
+
|
|
243
|
+
// Check if there's a dow_range (children[2])
|
|
244
|
+
if (rhs.children.length > 2) {
|
|
245
|
+
RuleParser._addDowToTods(startTod, endTod, rhs.children[2])
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', startTod], ['Value', endTod]]
|
|
249
|
+
}
|
|
250
|
+
case 'between': {
|
|
251
|
+
// between wraps either between_number or between_tod
|
|
252
|
+
const betweenChild = rhs.children[0]
|
|
253
|
+
if (betweenChild.type === 'between_tod') {
|
|
254
|
+
// between_tod has: children[0] = first tod, children[1] = second tod, children[2] = optional dow_range
|
|
255
|
+
const startTod = RuleParser.__parseValue(betweenChild.children[0])
|
|
256
|
+
const endTod = RuleParser.__parseValue(betweenChild.children[1])
|
|
257
|
+
|
|
258
|
+
// Check if there's a dow_range (children[2])
|
|
259
|
+
if (betweenChild.children.length > 2) {
|
|
260
|
+
RuleParser._addDowToTods(startTod, endTod, betweenChild.children[2])
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', startTod], ['Value', endTod]]
|
|
264
|
+
} else {
|
|
265
|
+
// between_number - no dow support
|
|
266
|
+
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', RuleParser.__parseValue(betweenChild.children[0])], ['Value', RuleParser.__parseValue(betweenChild.children[1])]]
|
|
267
|
+
}
|
|
268
|
+
}
|
|
195
269
|
case 'between_number':
|
|
196
|
-
case 'between':
|
|
197
270
|
return ['Between', RuleParser._parseResult(expr.children[0]), ['Value', RuleParser.__parseValue(rhs.children[0].children[0])], ['Value', RuleParser.__parseValue(rhs.children[0].children[1])]]
|
|
198
271
|
case 'basic_rhs':
|
|
199
272
|
return [OperatorFn[rhs.children[0].text], RuleParser._parseResult(expr.children[0]), RuleParser._parseResult(rhs.children[1])]
|