@halleyassist/rule-parser 0.1.1 → 0.1.3

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.
@@ -40,13 +40,17 @@ jobs:
40
40
  - name: Install modules
41
41
  run: |
42
42
  npm install
43
- - name: Test
43
+ - name: Test (Development)
44
+ run: npm test
45
+ - name: Build
46
+ run: node bin/package.js
47
+ - name: Test (Production)
44
48
  run: npm test
45
49
  - run: |
46
50
  VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,' | sed -e 's/^v//')
47
- jq '.version="'"$VERSION"'"' package.json > /tmp/a
51
+ jq '.version="'"$VERSION"'" | .main="./src/RuleParser.production.js"' package.json > /tmp/a
52
+
48
53
  mv /tmp/a package.json
49
- if: "startsWith(github.ref, 'refs/tags/v')"
50
54
  - run: |
51
55
  # npm login --scope=@halleyassist --registry=https://registry.npmjs.org/
52
56
  npm whoami
package/bin/package.js ADDED
@@ -0,0 +1,11 @@
1
+ const fs = require('fs')
2
+
3
+ const ParserRules = require('../src/RuleParser.ebnf.js')
4
+ const rules = JSON.stringify(ParserRules)
5
+
6
+ fs.writeFileSync('src/RuleParser.ebnf.json', rules)
7
+
8
+ const ruleParserJs = fs.readFileSync('src/RuleParser.js', 'utf8')
9
+ const ruleParserJsFixed = ruleParserJs.replace("require('./RuleParser.ebnf.js')", 'require(\'./RuleParser.ebnf.json\')')
10
+
11
+ fs.writeFileSync('src/RuleParser.production.js', ruleParserJsFixed)
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@halleyassist/rule-parser",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "The grammar for HalleyAssist rules",
5
- "main": "index.js",
5
+ "main": "./src/RuleParser.production.js",
6
6
  "scripts": {
7
7
  "test": "mocha"
8
8
  },
@@ -20,7 +20,7 @@
20
20
  "ebnf": "^1.9.1"
21
21
  },
22
22
  "devDependencies": {
23
- "chai": "^4.4.1",
23
+ "chai": "^4",
24
24
  "mocha": "^10.4.0"
25
25
  },
26
26
  "publishConfig": {
@@ -0,0 +1,78 @@
1
+ const {Grammars} = require('ebnf');
2
+
3
+ const grammar = `
4
+ statement_main ::= statement EOF
5
+ logical_operator ::= AND | OR
6
+ statement ::= expression (logical_operator expression)*
7
+ expression ::= not_expression | standard_expression | parenthesis_expression
8
+ parenthesis_expression::= BEGIN_PARENTHESIS WS* statement WS* END_PARENTHESIS
9
+ not_expression ::= NOT (result | parenthesis_expression)
10
+ standard_expression ::= result ((WS* eq_approx) | (WS* basic_rhs) | ((WS+ IS)? WS+ between))?
11
+ basic_rhs ::= operator WS* result
12
+ eq_approx ::= eq_operator WS* "~" WS* result
13
+
14
+ PLUS ::= "+"
15
+ MINUS ::= "-"
16
+ MULTIPLY ::= "*"
17
+ DIVIDE ::= "/"
18
+ MODULUS ::= "%"
19
+ DEFAULT_VAL ::= "??"
20
+ arithmetic_operator ::= PLUS | MINUS | MULTIPLY | DIVIDE | MODULUS | DEFAULT_VAL
21
+ arithmetic_result ::= simple_result WS* arithmetic_operator WS* ( arithmetic_result | simple_result )
22
+
23
+ simple_result ::= fcall | value
24
+ result ::= arithmetic_result | simple_result
25
+ value ::= false | true | array | number_time | number | number_tod | time_period | string
26
+ BEGIN_ARRAY ::= WS* #x5B WS* /* [ left square bracket */
27
+ BEGIN_OBJECT ::= WS* #x7B WS* /* { left curly bracket */
28
+ END_ARRAY ::= WS* #x5D WS* /* ] right square bracket */
29
+ END_OBJECT ::= WS* #x7D WS* /* } right curly bracket */
30
+ NAME_SEPARATOR ::= WS* #x3A WS* /* : colon */
31
+ VALUE_SEPARATOR ::= WS* #x2C WS* /* , comma */
32
+ WS ::= [#x20#x09#x0A#x0D]+ /* Space | Tab | \n | \r */
33
+
34
+ operator ::= GTE | LTE | GT | LT | EQ | NEQ
35
+ eq_operator ::= EQ | NEQ
36
+
37
+ BEGIN_ARGUMENT ::= "("
38
+ END_ARGUMENT ::= ")"
39
+
40
+ BEGIN_PARENTHESIS ::= "("
41
+ END_PARENTHESIS ::= ")"
42
+
43
+ argument ::= statement WS* ("," WS*)?
44
+ arguments ::= argument*
45
+ fname ::= [a-zA-z0-9]+
46
+ fcall ::= fname WS* BEGIN_ARGUMENT arguments? END_ARGUMENT
47
+
48
+ between_number ::= number ((WS+ ("and" | "AND") WS+) | (WS* "-" WS*)) number
49
+ between_tod ::= number_tod ((WS+ ("and" | "AND") WS+)) number_tod
50
+ between ::= ("between" | "BETWEEN") WS+ (between_number | between_tod)
51
+
52
+ AND ::= (WS* "&&" WS*) | (WS+ ("AND"|"and") WS+)
53
+ OR ::= (WS* "||" WS*) | (WS+ ("OR"|"or") WS+)
54
+ GT ::= ">"
55
+ LT ::= "<"
56
+ GTE ::= ">="
57
+ LTE ::= "<="
58
+ IS ::= "is" | "IS"
59
+ EQ ::= "==" | "="
60
+ NEQ ::= "!="
61
+ NOT ::= ("!" WS*) | ("not" WS+)
62
+ false ::= "false" | "FALSE"
63
+ null ::= "null" | "NULL"
64
+ true ::= "true" | "TRUE"
65
+ array ::= BEGIN_ARRAY (value (VALUE_SEPARATOR value)*)? END_ARRAY
66
+
67
+ unit ::= "seconds" | "second" | "minutes" | "minute" | "min" | "mins" | "min" | "hours" | "hour" | "days" | "day" | "weeks" | "week"
68
+ number ::= "-"? ([0-9]+) ("." [0-9]+)? (("e" | "E") ( "-" | "+" )? ("0" | [1-9] [0-9]*))?
69
+ number_time ::= number WS+ unit
70
+ number_tod ::= ([0-9]+) ":" ([0-9]+)
71
+
72
+ time_period_const ::= "today"
73
+ time_period ::= time_period_const | between
74
+
75
+ string ::= '"' (([#x20-#x21] | [#x23-#x5B] | [#x5D-#xFFFF]) | #x5C (#x22 | #x5C | #x2F | #x62 | #x66 | #x6E | #x72 | #x74 | #x75 HEXDIG HEXDIG HEXDIG HEXDIG))* '"'
76
+ HEXDIG ::= [a-fA-F0-9]
77
+ `
78
+ module.exports = Grammars.W3C.getRules(grammar);
@@ -0,0 +1 @@
1
+ [{"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*",{},"WS*"]]},{"name":"BEGIN_OBJECT","bnf":[["WS*",{},"WS*"]]},{"name":"END_ARRAY","bnf":[["WS*",{},"WS*"]]},{"name":"END_OBJECT","bnf":[["WS*",{},"WS*"]]},{"name":"NAME_SEPARATOR","bnf":[["WS*",{},"WS*"]]},{"name":"VALUE_SEPARATOR","bnf":[["WS*",{},"WS*"]]},{"name":"%WS8","bnf":[[{}]]},{"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":[[{}]]},{"name":"fname","bnf":[["%fname10+"]]},{"name":"fcall","bnf":[["fname","WS*","BEGIN_ARGUMENT","arguments?","END_ARGUMENT"]]},{"name":"%%%between_number111213","bnf":[["\"and\""],["\"AND\""]],"fragment":true},{"name":"%%between_number1112","bnf":[["WS+","%%%between_number111213","WS+"]],"fragment":true},{"name":"%%between_number1114","bnf":[["WS*","\"-\"","WS*"]],"fragment":true},{"name":"%between_number11","bnf":[["%%between_number1112"],["%%between_number1114"]],"fragment":true},{"name":"between_number","bnf":[["number","%between_number11","number"]]},{"name":"%%%between_tod151617","bnf":[["\"and\""],["\"AND\""]],"fragment":true},{"name":"%%between_tod1516","bnf":[["WS+","%%%between_tod151617","WS+"]],"fragment":true},{"name":"%between_tod15","bnf":[["%%between_tod1516"]],"fragment":true},{"name":"between_tod","bnf":[["number_tod","%between_tod15","number_tod"]]},{"name":"%between18","bnf":[["\"between\""],["\"BETWEEN\""]],"fragment":true},{"name":"%between19","bnf":[["between_number"],["between_tod"]],"fragment":true},{"name":"between","bnf":[["%between18","WS+","%between19"]]},{"name":"%AND20","bnf":[["WS*","\"&&\"","WS*"]],"fragment":true},{"name":"%%AND2122","bnf":[["\"AND\""],["\"and\""]],"fragment":true},{"name":"%AND21","bnf":[["WS+","%%AND2122","WS+"]],"fragment":true},{"name":"AND","bnf":[["%AND20"],["%AND21"]]},{"name":"%OR23","bnf":[["WS*","\"||\"","WS*"]],"fragment":true},{"name":"%%OR2425","bnf":[["\"OR\""],["\"or\""]],"fragment":true},{"name":"%OR24","bnf":[["WS+","%%OR2425","WS+"]],"fragment":true},{"name":"OR","bnf":[["%OR23"],["%OR24"]]},{"name":"GT","bnf":[["\">\""]]},{"name":"LT","bnf":[["\"<\""]]},{"name":"GTE","bnf":[["\">=\""]]},{"name":"LTE","bnf":[["\"<=\""]]},{"name":"IS","bnf":[["\"is\""],["\"IS\""]]},{"name":"EQ","bnf":[["\"==\""],["\"=\""]]},{"name":"NEQ","bnf":[["\"!=\""]]},{"name":"%NOT26","bnf":[["\"!\"","WS*"]],"fragment":true},{"name":"%NOT27","bnf":[["\"not\"","WS+"]],"fragment":true},{"name":"NOT","bnf":[["%NOT26"],["%NOT27"]]},{"name":"false","bnf":[["\"false\""],["\"FALSE\""]]},{"name":"null","bnf":[["\"null\""],["\"NULL\""]]},{"name":"true","bnf":[["\"true\""],["\"TRUE\""]]},{"name":"%%array2829","bnf":[["VALUE_SEPARATOR","value"]],"fragment":true},{"name":"%array28","bnf":[["value","%%array2829*"]],"fragment":true},{"name":"array","bnf":[["BEGIN_ARRAY","%array28?","END_ARRAY"]]},{"name":"unit","bnf":[["\"seconds\""],["\"second\""],["\"minutes\""],["\"minute\""],["\"min\""],["\"mins\""],["\"min\""],["\"hours\""],["\"hour\""],["\"days\""],["\"day\""],["\"weeks\""],["\"week\""]]},{"name":"%%number3031","bnf":[[{}]]},{"name":"%number30","bnf":[["%%number3031+"]],"fragment":true},{"name":"%%number3233","bnf":[[{}]]},{"name":"%number32","bnf":[["\".\"","%%number3233+"]],"fragment":true},{"name":"%%number3435","bnf":[["\"e\""],["\"E\""]],"fragment":true},{"name":"%%number3436","bnf":[["\"-\""],["\"+\""]],"fragment":true},{"name":"%%%number343738","bnf":[[{}]]},{"name":"%%number3437","bnf":[["\"0\""],[{},"%%%number343738*"]],"fragment":true},{"name":"%number34","bnf":[["%%number3435","%%number3436?","%%number3437"]],"fragment":true},{"name":"number","bnf":[["\"-\"?","%number30","%number32?","%number34?"]]},{"name":"number_time","bnf":[["number","WS+","unit"]]},{"name":"%%number_tod3940","bnf":[[{}]]},{"name":"%number_tod39","bnf":[["%%number_tod3940+"]],"fragment":true},{"name":"%%number_tod4142","bnf":[[{}]]},{"name":"%number_tod41","bnf":[["%%number_tod4142+"]],"fragment":true},{"name":"number_tod","bnf":[["%number_tod39","\":\"","%number_tod41"]]},{"name":"time_period_const","bnf":[["\"today\""]]},{"name":"time_period","bnf":[["time_period_const"],["between"]]},{"name":"%%string4344","bnf":[[{}],[{}],[{}]],"fragment":true},{"name":"%%string4345","bnf":[[{}],[{}],[{}],[{}],[{}],[{}],[{}],[{}],[{},"HEXDIG","HEXDIG","HEXDIG","HEXDIG"]],"fragment":true},{"name":"%string43","bnf":[["%%string4344"],[{},"%%string4345"]],"fragment":true},{"name":"string","bnf":[["'\"'","%string43*","'\"'"]]},{"name":"HEXDIG","bnf":[[{}]]}]
package/src/RuleParser.js CHANGED
@@ -1,85 +1,8 @@
1
- const { Grammars, Parser } = require('ebnf'),
1
+ const { Parser } = require('ebnf'),
2
2
  assert = require('assert')
3
3
 
4
-
5
- const grammar = `
6
- statement_main ::= statement EOF
7
- logical_operator ::= AND | OR
8
- statement ::= expression (logical_operator expression)*
9
- expression ::= not_expression | standard_expression | parenthesis_expression
10
- parenthesis_expression::= BEGIN_PARENTHESIS WS* statement WS* END_PARENTHESIS
11
- not_expression ::= NOT (result | parenthesis_expression)
12
- standard_expression ::= result ((WS* eq_approx) | (WS* basic_rhs) | ((WS+ IS)? WS+ between))?
13
- basic_rhs ::= operator WS* result
14
- eq_approx ::= eq_operator WS* "~" WS* result
15
-
16
- PLUS ::= "+"
17
- MINUS ::= "-"
18
- MULTIPLY ::= "*"
19
- DIVIDE ::= "/"
20
- MODULUS ::= "%"
21
- DEFAULT_VAL ::= "??"
22
- arithmetic_operator ::= PLUS | MINUS | MULTIPLY | DIVIDE | MODULUS | DEFAULT_VAL
23
- arithmetic_result ::= simple_result WS* arithmetic_operator WS* ( arithmetic_result | simple_result )
24
-
25
- simple_result ::= fcall | value
26
- result ::= arithmetic_result | simple_result
27
- value ::= false | true | array | number_time | number | number_tod | time_period | string
28
- BEGIN_ARRAY ::= WS* #x5B WS* /* [ left square bracket */
29
- BEGIN_OBJECT ::= WS* #x7B WS* /* { left curly bracket */
30
- END_ARRAY ::= WS* #x5D WS* /* ] right square bracket */
31
- END_OBJECT ::= WS* #x7D WS* /* } right curly bracket */
32
- NAME_SEPARATOR ::= WS* #x3A WS* /* : colon */
33
- VALUE_SEPARATOR ::= WS* #x2C WS* /* , comma */
34
- WS ::= [#x20#x09#x0A#x0D]+ /* Space | Tab | \n | \r */
35
-
36
- operator ::= GTE | LTE | GT | LT | EQ | NEQ
37
- eq_operator ::= EQ | NEQ
38
-
39
- BEGIN_ARGUMENT ::= "("
40
- END_ARGUMENT ::= ")"
41
-
42
- BEGIN_PARENTHESIS ::= "("
43
- END_PARENTHESIS ::= ")"
44
-
45
- argument ::= statement WS* ("," WS*)?
46
- arguments ::= argument*
47
- fname ::= [a-zA-z0-9]+
48
- fcall ::= fname WS* BEGIN_ARGUMENT arguments? END_ARGUMENT
49
-
50
- between_number ::= number ((WS+ ("and" | "AND") WS+) | (WS* "-" WS*)) number
51
- between_tod ::= number_tod ((WS+ ("and" | "AND") WS+)) number_tod
52
- between ::= ("between" | "BETWEEN") WS+ (between_number | between_tod)
53
-
54
- AND ::= (WS* "&&" WS*) | (WS+ ("AND"|"and") WS+)
55
- OR ::= (WS* "||" WS*) | (WS+ ("OR"|"or") WS+)
56
- GT ::= ">"
57
- LT ::= "<"
58
- GTE ::= ">="
59
- LTE ::= "<="
60
- IS ::= "is" | "IS"
61
- EQ ::= "==" | "="
62
- NEQ ::= "!="
63
- NOT ::= ("!" WS*) | ("not" WS+)
64
- false ::= "false" | "FALSE"
65
- null ::= "null" | "NULL"
66
- true ::= "true" | "TRUE"
67
- array ::= BEGIN_ARRAY (value (VALUE_SEPARATOR value)*)? END_ARRAY
68
-
69
- unit ::= "seconds" | "second" | "minutes" | "minute" | "min" | "mins" | "min" | "hours" | "hour" | "days" | "day" | "weeks" | "week"
70
- number ::= "-"? ([0-9]+) ("." [0-9]+)? (("e" | "E") ( "-" | "+" )? ("0" | [1-9] [0-9]*))?
71
- number_time ::= number WS+ unit
72
- number_tod ::= ([0-9]+) ":" ([0-9]+)
73
-
74
- time_period_const ::= "today"
75
- time_period ::= time_period_const | between
76
-
77
- string ::= '"' (([#x20-#x21] | [#x23-#x5B] | [#x5D-#xFFFF]) | #x5C (#x22 | #x5C | #x2F | #x62 | #x66 | #x6E | #x72 | #x74 | #x75 HEXDIG HEXDIG HEXDIG HEXDIG))* '"'
78
- HEXDIG ::= [a-fA-F0-9]
79
- `
80
- let RULES = Grammars.W3C.getRules(grammar);
81
- let parser = new Parser(RULES, {debug: false});
82
- const target = 'statement_main'
4
+ let ParserRules = require('./RuleParser.ebnf.js')
5
+ let ParserCache;
83
6
 
84
7
  const ArithmeticOperators = {
85
8
  "+": 'MathAdd',
@@ -114,10 +37,12 @@ const Epsilon = 0.01
114
37
  class RuleParser {
115
38
  static toAst(txt){
116
39
  let ret
117
- //if(process.env.NODE_ENV === 'test') {
118
- // parser.debug = true
119
- //}
120
- ret = parser.getAST(txt, target);
40
+
41
+ if(!ParserCache){
42
+ ParserCache = new Parser(ParserRules, {debug: false})
43
+ }
44
+
45
+ ret = ParserCache.getAST(txt, 'statement_main');
121
46
 
122
47
  if(ret){
123
48
  return ret.children[0]
@@ -1,5 +1,5 @@
1
1
  const
2
- RuleParser = require("../src/RuleParser"),
2
+ RuleParser = require("../"),
3
3
  { expect } = require('chai')
4
4
 
5
5
  describe("RuleParser", function () {