clarity-pattern-parser 10.3.7 → 11.0.0

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.
Files changed (51) hide show
  1. package/dist/ast/Node.d.ts +2 -2
  2. package/dist/ast/compact.d.ts +2 -0
  3. package/dist/ast/remove.d.ts +2 -0
  4. package/dist/index.browser.js +417 -487
  5. package/dist/index.browser.js.map +1 -1
  6. package/dist/index.d.ts +3 -1
  7. package/dist/index.esm.js +416 -488
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/index.js +417 -487
  10. package/dist/index.js.map +1 -1
  11. package/dist/patterns/ExpressionPattern.d.ts +27 -25
  12. package/dist/patterns/FiniteRepeat.d.ts +1 -2
  13. package/dist/patterns/InfiniteRepeat.d.ts +1 -2
  14. package/dist/patterns/Literal.d.ts +0 -1
  15. package/dist/patterns/Not.d.ts +1 -2
  16. package/dist/patterns/Optional.d.ts +0 -1
  17. package/dist/patterns/Options.d.ts +1 -2
  18. package/dist/patterns/Pattern.d.ts +0 -1
  19. package/dist/patterns/PrecedenceTree.d.ts +28 -0
  20. package/dist/patterns/Reference.d.ts +1 -2
  21. package/dist/patterns/Regex.d.ts +1 -2
  22. package/dist/patterns/Repeat.d.ts +0 -3
  23. package/dist/patterns/Sequence.d.ts +3 -6
  24. package/dist/patterns/execPattern.d.ts +3 -0
  25. package/dist/patterns/testPattern.d.ts +2 -0
  26. package/package.json +1 -1
  27. package/src/ast/Node.test.ts +17 -17
  28. package/src/ast/Node.ts +7 -5
  29. package/src/ast/compact.ts +11 -0
  30. package/src/ast/remove.ts +11 -0
  31. package/src/grammar/Grammar.test.ts +0 -50
  32. package/src/grammar/Grammar.ts +0 -20
  33. package/src/grammar/patterns/statement.ts +1 -6
  34. package/src/index.ts +4 -0
  35. package/src/patterns/ExpressionPattern.test.ts +1 -1
  36. package/src/patterns/ExpressionPattern.ts +235 -384
  37. package/src/patterns/FiniteRepeat.ts +5 -22
  38. package/src/patterns/InfiniteRepeat.ts +6 -21
  39. package/src/patterns/Literal.ts +5 -19
  40. package/src/patterns/Not.ts +5 -16
  41. package/src/patterns/Optional.ts +0 -7
  42. package/src/patterns/Options.ts +5 -21
  43. package/src/patterns/Pattern.ts +0 -1
  44. package/src/patterns/PrecedenceTree.test.ts +162 -0
  45. package/src/patterns/PrecedenceTree.ts +207 -0
  46. package/src/patterns/Reference.ts +5 -17
  47. package/src/patterns/Regex.ts +5 -17
  48. package/src/patterns/Repeat.ts +1 -13
  49. package/src/patterns/Sequence.ts +7 -22
  50. package/src/patterns/execPattern.ts +16 -0
  51. package/src/patterns/testPattern.ts +11 -0
@@ -3,6 +3,8 @@ import { Cursor } from "./Cursor";
3
3
  import { findPattern } from "./findPattern";
4
4
  import { ParseResult } from "./ParseResult";
5
5
  import { Pattern } from "./Pattern";
6
+ import { testPattern } from './testPattern';
7
+ import { execPattern } from "./execPattern";
6
8
 
7
9
  let idIndex = 0;
8
10
 
@@ -25,8 +27,6 @@ export class FiniteRepeat implements Pattern {
25
27
  private _trimDivider: boolean;
26
28
  private _firstIndex: number;
27
29
 
28
- shouldCompactAst = false;
29
-
30
30
  get id() {
31
31
  return this._id;
32
32
  }
@@ -152,30 +152,15 @@ export class FiniteRepeat implements Pattern {
152
152
 
153
153
  const node = new Node(this._type, this.name, firstIndex, lastIndex, nodes);
154
154
 
155
- if (this.shouldCompactAst) {
156
- node.compact();
157
- }
158
-
159
155
  return node;
160
156
  }
161
157
 
162
- test(text: string): boolean {
163
- const cursor = new Cursor(text);
164
- const ast = this.parse(cursor);
165
-
166
- return ast?.value === text;
158
+ test(text: string, record = false): boolean {
159
+ return testPattern(this, text, record);
167
160
  }
168
161
 
169
162
  exec(text: string, record = false): ParseResult {
170
- const cursor = new Cursor(text);
171
- record && cursor.startRecording();
172
-
173
- const ast = this.parse(cursor);
174
-
175
- return {
176
- ast: ast?.value === text ? ast : null,
177
- cursor
178
- };
163
+ return execPattern(this, text, record);
179
164
  }
180
165
 
181
166
  clone(name = this._name): Pattern {
@@ -194,8 +179,6 @@ export class FiniteRepeat implements Pattern {
194
179
  );
195
180
 
196
181
  clone._id = this._id;
197
- clone.shouldCompactAst = this.shouldCompactAst;
198
-
199
182
  return clone;
200
183
  }
201
184
 
@@ -1,9 +1,10 @@
1
1
  import { Node } from "../ast/Node";
2
2
  import { Cursor } from "./Cursor";
3
3
  import { Pattern } from "./Pattern";
4
- import { clonePatterns } from "./clonePatterns";
5
4
  import { findPattern } from "./findPattern";
6
5
  import { ParseResult } from "./ParseResult";
6
+ import { execPattern } from "./execPattern";
7
+ import { testPattern } from "./testPattern";
7
8
 
8
9
  let idIndex = 0;
9
10
 
@@ -26,8 +27,6 @@ export class InfiniteRepeat implements Pattern {
26
27
  private _min: number;
27
28
  private _trimDivider: boolean;
28
29
 
29
- shouldCompactAst = false;
30
-
31
30
  get id(): string {
32
31
  return this._id;
33
32
  }
@@ -56,7 +55,7 @@ export class InfiniteRepeat implements Pattern {
56
55
  return this._min;
57
56
  }
58
57
 
59
- get startedOnIndex(){
58
+ get startedOnIndex() {
60
59
  return this._firstIndex;
61
60
  }
62
61
 
@@ -92,23 +91,13 @@ export class InfiniteRepeat implements Pattern {
92
91
  }
93
92
  }
94
93
 
95
- test(text: string) {
96
- const cursor = new Cursor(text);
97
- const ast = this.parse(cursor);
98
94
 
99
- return ast?.value === text;
95
+ test(text: string, record = false): boolean {
96
+ return testPattern(this, text, record);
100
97
  }
101
98
 
102
99
  exec(text: string, record = false): ParseResult {
103
- const cursor = new Cursor(text);
104
- record && cursor.startRecording();
105
-
106
- const ast = this.parse(cursor);
107
-
108
- return {
109
- ast: ast?.value === text ? ast : null,
110
- cursor
111
- };
100
+ return execPattern(this, text, record);
112
101
  }
113
102
 
114
103
  parse(cursor: Cursor): Node | null {
@@ -125,9 +114,6 @@ export class InfiniteRepeat implements Pattern {
125
114
  cursor.moveTo(node.lastIndex);
126
115
  cursor.recordMatch(this, node);
127
116
 
128
- if (this.shouldCompactAst) {
129
- node.compact();
130
- }
131
117
  }
132
118
 
133
119
  return node;
@@ -362,7 +348,6 @@ export class InfiniteRepeat implements Pattern {
362
348
  );
363
349
 
364
350
  clone._id = this._id;
365
- clone.shouldCompactAst = this.shouldCompactAst;
366
351
 
367
352
  return clone;
368
353
  }
@@ -2,6 +2,8 @@ import { Node } from "../ast/Node";
2
2
  import { Cursor } from "./Cursor";
3
3
  import { ParseResult } from "./ParseResult";
4
4
  import { Pattern } from "./Pattern";
5
+ import { execPattern } from "./execPattern";
6
+ import { testPattern } from "./testPattern";
5
7
 
6
8
  let idIndex = 0;
7
9
 
@@ -16,8 +18,6 @@ export class Literal implements Pattern {
16
18
  private _lastIndex: number;
17
19
  private _endIndex: number;
18
20
 
19
- shouldCompactAst = false;
20
-
21
21
  get id(): string {
22
22
  return this._id;
23
23
  }
@@ -66,25 +66,12 @@ export class Literal implements Pattern {
66
66
  this._endIndex = 0;
67
67
  }
68
68
 
69
- test(text: string, record = false) {
70
- const cursor = new Cursor(text);
71
- record && cursor.startRecording();
72
-
73
- const ast = this.parse(cursor);
74
-
75
- return ast?.value === text;
69
+ test(text: string, record = false): boolean {
70
+ return testPattern(this, text, record);
76
71
  }
77
72
 
78
73
  exec(text: string, record = false): ParseResult {
79
- const cursor = new Cursor(text);
80
- record && cursor.startRecording();
81
-
82
- const ast = this.parse(cursor);
83
-
84
- return {
85
- ast: ast?.value === text ? ast : null,
86
- cursor
87
- };
74
+ return execPattern(this, text, record);
88
75
  }
89
76
 
90
77
  parse(cursor: Cursor): Node | null {
@@ -147,7 +134,6 @@ export class Literal implements Pattern {
147
134
  clone(name = this._name): Pattern {
148
135
  const clone = new Literal(name, this._token);
149
136
  clone._id = this._id;
150
- clone.shouldCompactAst = this.shouldCompactAst;
151
137
  return clone;
152
138
  }
153
139
 
@@ -2,6 +2,8 @@ import { Node } from "../ast/Node";
2
2
  import { Cursor } from "./Cursor";
3
3
  import { ParseResult } from "./ParseResult";
4
4
  import { Pattern } from "./Pattern";
5
+ import { execPattern } from "./execPattern";
6
+ import { testPattern } from "./testPattern";
5
7
 
6
8
  let idIndex = 0;
7
9
 
@@ -12,8 +14,6 @@ export class Not implements Pattern {
12
14
  private _parent: Pattern | null;
13
15
  private _children: Pattern[];
14
16
 
15
- shouldCompactAst = false;
16
-
17
17
  get id(): string {
18
18
  return this._id;
19
19
  }
@@ -51,23 +51,12 @@ export class Not implements Pattern {
51
51
  this._children[0].parent = this;
52
52
  }
53
53
 
54
- test(text: string) {
55
- const cursor = new Cursor(text);
56
- this.parse(cursor);
57
-
58
- return !cursor.hasError;
54
+ test(text: string, record = false): boolean {
55
+ return testPattern(this, text, record);
59
56
  }
60
57
 
61
58
  exec(text: string, record = false): ParseResult {
62
- const cursor = new Cursor(text);
63
- record && cursor.startRecording();
64
-
65
- const ast = this.parse(cursor);
66
-
67
- return {
68
- ast: ast?.value === text ? ast : null,
69
- cursor
70
- };
59
+ return execPattern(this, text, record);
71
60
  }
72
61
 
73
62
  parse(cursor: Cursor): Node | null {
@@ -12,8 +12,6 @@ export class Optional implements Pattern {
12
12
  private _parent: Pattern | null;
13
13
  private _children: Pattern[];
14
14
 
15
- shouldCompactAst = false;
16
-
17
15
  get id(): string {
18
16
  return this._id;
19
17
  }
@@ -80,10 +78,6 @@ export class Optional implements Pattern {
80
78
 
81
79
  return null;
82
80
  } else {
83
- if (node != null && this.shouldCompactAst) {
84
- node.compact();
85
- }
86
-
87
81
  return node;
88
82
  }
89
83
 
@@ -92,7 +86,6 @@ export class Optional implements Pattern {
92
86
  clone(name = this._name): Pattern {
93
87
  const clone = new Optional(name, this._children[0]);
94
88
  clone._id = this._id;
95
- clone.shouldCompactAst = this.shouldCompactAst;
96
89
  return clone;
97
90
  }
98
91
 
@@ -5,6 +5,8 @@ import { clonePatterns } from "./clonePatterns";
5
5
  import { findPattern } from "./findPattern";
6
6
  import { ParseResult } from "./ParseResult";
7
7
  import { isRecursivePattern } from "./isRecursivePattern";
8
+ import { execPattern } from "./execPattern";
9
+ import { testPattern } from "./testPattern";
8
10
 
9
11
  let idIndex = 0;
10
12
 
@@ -17,8 +19,6 @@ export class Options implements Pattern {
17
19
  private _isGreedy: boolean;
18
20
  private _firstIndex: number;
19
21
 
20
- shouldCompactAst = false;
21
-
22
22
  get id(): string {
23
23
  return this._id;
24
24
  }
@@ -70,23 +70,12 @@ export class Options implements Pattern {
70
70
  }
71
71
  }
72
72
 
73
- test(text: string) {
74
- const cursor = new Cursor(text);
75
- const ast = this.parse(cursor);
76
-
77
- return ast?.value === text;
73
+ test(text: string, record = false): boolean {
74
+ return testPattern(this, text, record);
78
75
  }
79
76
 
80
77
  exec(text: string, record = false): ParseResult {
81
- const cursor = new Cursor(text);
82
- record && cursor.startRecording();
83
-
84
- const ast = this.parse(cursor);
85
-
86
- return {
87
- ast: ast?.value === text ? ast : null,
88
- cursor
89
- };
78
+ return execPattern(this, text, record);
90
79
  }
91
80
 
92
81
  parse(cursor: Cursor): Node | null {
@@ -97,10 +86,6 @@ export class Options implements Pattern {
97
86
  cursor.moveTo(node.lastIndex);
98
87
  cursor.resolveError();
99
88
 
100
- if (this.shouldCompactAst) {
101
- node.compact();
102
- }
103
-
104
89
  return node;
105
90
  }
106
91
 
@@ -221,7 +206,6 @@ export class Options implements Pattern {
221
206
  clone(name = this._name): Pattern {
222
207
  const clone = new Options(name, this._children, this._isGreedy);
223
208
  clone._id = this._id;
224
- clone.shouldCompactAst = this.shouldCompactAst;
225
209
  return clone;
226
210
  }
227
211
 
@@ -6,7 +6,6 @@ export interface Pattern {
6
6
  id: string;
7
7
  type: string;
8
8
  name: string;
9
- shouldCompactAst: boolean;
10
9
  startedOnIndex: number;
11
10
  parent: Pattern | null;
12
11
  children: Pattern[];
@@ -0,0 +1,162 @@
1
+ import { PrecedenceTree } from "./PrecedenceTree";
2
+ import { Node } from "../ast/Node";
3
+
4
+ describe("Precedence Tree", () => {
5
+ test("add Binary", () => {
6
+ const tree = new PrecedenceTree({
7
+ mul: 0,
8
+ add: 1,
9
+ bool: 2
10
+ }, {});
11
+
12
+ tree.addAtom(Node.createValueNode("literal", "a", "a"));
13
+ tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
14
+ tree.addAtom(Node.createValueNode("literal", "b", "b"));
15
+ tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
16
+ tree.addAtom(Node.createValueNode("literal", "c", "c"));
17
+ tree.addBinary("bool", Node.createValueNode("literal", "||", "||"));
18
+ tree.addAtom(Node.createValueNode("literal", "d", "d"));
19
+ tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
20
+ tree.addAtom(Node.createValueNode("literal", "e", "e"));
21
+
22
+ const result = tree.commit();
23
+ const expected = Node.createNode("expression", "bool", [
24
+ Node.createNode("expression", "add", [
25
+ Node.createValueNode("literal", "a", "a"),
26
+ Node.createValueNode("literal", "+", "+"),
27
+ Node.createNode("expression", "mul", [
28
+ Node.createValueNode("literal", "b", "b"),
29
+ Node.createValueNode("literal", "*", "*"),
30
+ Node.createValueNode("literal", "c", "c"),
31
+ ]),
32
+ ]),
33
+ Node.createValueNode("literal", "||", "||"),
34
+ Node.createNode("expression", "add", [
35
+ Node.createValueNode("literal", "d", "d"),
36
+ Node.createValueNode("literal", "+", "+"),
37
+ Node.createValueNode("literal", "e", "e"),
38
+ ]),
39
+ ]);
40
+
41
+
42
+ expect(result?.toString()).toBe("a+b*c||d+e");
43
+ expect(result?.toCycleFreeObject()).toEqual(expected.toCycleFreeObject());
44
+ });
45
+
46
+ test("add Prefix", () => {
47
+ const tree = new PrecedenceTree();
48
+
49
+ tree.addPrefix("negate", Node.createValueNode("literal", "!", "!"));
50
+ tree.addPrefix("increment", Node.createValueNode("literal", "++", "++"));
51
+ tree.addPrefix("plus", Node.createValueNode("literal", "+", "+"));
52
+ tree.addAtom(Node.createValueNode("literal", "a", "a"));
53
+
54
+ let result = tree.commit();
55
+ const expected = Node.createNode("expression", "negate", [
56
+ Node.createValueNode("literal", "!", "!"),
57
+ Node.createNode("expression", "increment", [
58
+ Node.createValueNode("literal", "++", "++"),
59
+ Node.createNode("expression", "plus", [
60
+ Node.createValueNode("literal", "+", "+"),
61
+ Node.createValueNode("literal", "a", "a"),
62
+ ]),
63
+ ]),
64
+ ]);
65
+
66
+ expect(result?.toString()).toBe("!+++a");
67
+ expect(result?.toCycleFreeObject()).toEqual(expected.toCycleFreeObject());
68
+ });
69
+
70
+ test("add Postfix", () => {
71
+ const tree = new PrecedenceTree();
72
+
73
+ tree.addPostfix("decrement", Node.createValueNode("literal", "--", "--"));
74
+ tree.addPostfix("increment", Node.createValueNode("literal", "++", "++"));
75
+ tree.addAtom(Node.createValueNode("literal", "a", "a"));
76
+
77
+ const expected = Node.createNode("expression", "increment", [
78
+ Node.createNode("expression", "decrement", [
79
+ Node.createValueNode("literal", "a", "a"),
80
+ Node.createValueNode("literal", "--", "--"),
81
+ ]),
82
+ Node.createValueNode("literal", "++", "++"),
83
+ ]);
84
+
85
+ const result = tree.commit();
86
+ expect(result?.toString()).toBe("a--++");
87
+ expect(result?.toCycleFreeObject()).toEqual(expected.toCycleFreeObject());
88
+ });
89
+
90
+ test("all", () => {
91
+ const tree = new PrecedenceTree({
92
+ mul: 0,
93
+ add: 1,
94
+ bool: 2
95
+ }, {});
96
+
97
+ tree.addPrefix("negate", Node.createValueNode("literal", "!", "!"));
98
+ tree.addPostfix("increment", Node.createValueNode("literal", "++", "++"));
99
+ tree.addAtom(Node.createValueNode("literal", "a", "a"));
100
+ tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
101
+ tree.addAtom(Node.createValueNode("literal", "b", "b"));
102
+ tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
103
+ tree.addAtom(Node.createValueNode("literal", "c", "c"));
104
+
105
+ const result = tree.commit();
106
+ const expected = Node.createNode("expression", "add", [
107
+ Node.createNode("expression", "mul", [
108
+ Node.createNode("expression", "increment", [
109
+ Node.createNode("expression", "negate", [
110
+ Node.createValueNode("literal", "!", "!"),
111
+ Node.createValueNode("literal", "a", "a"),
112
+ ]),
113
+ Node.createValueNode("literal", "++", "++"),
114
+ ]),
115
+ Node.createValueNode("literal", "*", "*"),
116
+ Node.createValueNode("literal", "b", "b"),
117
+ ]),
118
+ Node.createValueNode("literal", "+", "+"),
119
+ Node.createValueNode("literal", "c", "c"),
120
+ ]);
121
+
122
+ expect(result?.toString()).toBe("!a++*b+c");
123
+ expect(result?.toCycleFreeObject()).toEqual(expected.toCycleFreeObject());
124
+ });
125
+
126
+ test("Incomplete", () => {
127
+ const tree = new PrecedenceTree({
128
+ mul: 0,
129
+ add: 1,
130
+ bool: 2
131
+ }, {});
132
+
133
+ tree.addPrefix("negate", Node.createValueNode("literal", "!", "!"));
134
+ tree.addPostfix("increment", Node.createValueNode("literal", "++", "++"));
135
+ tree.addAtom(Node.createValueNode("literal", "a", "a"));
136
+ tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
137
+ tree.addAtom(Node.createValueNode("literal", "b", "b"));
138
+ tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
139
+ tree.addAtom(Node.createValueNode("literal", "c", "c"));
140
+ tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
141
+
142
+ const result = tree.commit();
143
+ const expected = Node.createNode("expression", "add", [
144
+ Node.createNode("expression", "mul", [
145
+ Node.createNode("expression", "increment", [
146
+ Node.createNode("expression", "negate", [
147
+ Node.createValueNode("literal", "!", "!"),
148
+ Node.createValueNode("literal", "a", "a"),
149
+ ]),
150
+ Node.createValueNode("literal", "++", "++"),
151
+ ]),
152
+ Node.createValueNode("literal", "*", "*"),
153
+ Node.createValueNode("literal", "b", "b"),
154
+ ]),
155
+ Node.createValueNode("literal", "+", "+"),
156
+ Node.createValueNode("literal", "c", "c"),
157
+ ]);
158
+
159
+ expect(result?.toString()).toBe("!a++*b+c");
160
+ expect(result?.toCycleFreeObject()).toEqual(expected.toCycleFreeObject());
161
+ });
162
+ });