clarity-pattern-parser 9.2.4 → 10.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clarity-pattern-parser",
3
- "version": "9.2.4",
3
+ "version": "10.0.0",
4
4
  "description": "Parsing Library for Typescript and Javascript.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.esm.js",
@@ -16,7 +16,7 @@ describe("Node", () => {
16
16
  });
17
17
 
18
18
  test("Properties", () => {
19
- const child = new Node("child", "child", 0, 0, undefined, "Content")
19
+ const child = new Node("child", "child", 0, 0, undefined, "Content");
20
20
  const parent = new Node("parent", "parent", 0, 0, [
21
21
  child,
22
22
  ]);
@@ -99,7 +99,7 @@ describe("Node", () => {
99
99
  parent.insertBefore(b, a);
100
100
 
101
101
  expect(parent.children.length).toBe(2);
102
- expect(parent.value).toBe("BA")
102
+ expect(parent.value).toBe("BA");
103
103
  expect(parent.children[0]).toBe(b);
104
104
  expect(parent.children[1]).toBe(a);
105
105
  expect(a.parent).toBe(parent);
@@ -118,7 +118,7 @@ describe("Node", () => {
118
118
  parent.insertBefore(b, null);
119
119
 
120
120
  expect(parent.children.length).toBe(2);
121
- expect(parent.value).toBe("AB")
121
+ expect(parent.value).toBe("AB");
122
122
  expect(parent.children[0]).toBe(a);
123
123
  expect(parent.children[1]).toBe(b);
124
124
  expect(a.parent).toBe(parent);
@@ -137,7 +137,7 @@ describe("Node", () => {
137
137
  parent.appendChild(b);
138
138
 
139
139
  expect(parent.children.length).toBe(2);
140
- expect(parent.value).toBe("AB")
140
+ expect(parent.value).toBe("AB");
141
141
  expect(parent.children[0]).toBe(a);
142
142
  expect(parent.children[1]).toBe(b);
143
143
  expect(a.parent).toBe(parent);
@@ -156,7 +156,7 @@ describe("Node", () => {
156
156
  parent.spliceChildren(0, 0, b);
157
157
 
158
158
  expect(parent.children.length).toBe(2);
159
- expect(parent.value).toBe("BA")
159
+ expect(parent.value).toBe("BA");
160
160
  expect(parent.children[0]).toBe(b);
161
161
  expect(parent.children[1]).toBe(a);
162
162
  expect(a.parent).toBe(parent);
@@ -175,7 +175,7 @@ describe("Node", () => {
175
175
  parent.spliceChildren(0, 1, b);
176
176
 
177
177
  expect(parent.children.length).toBe(1);
178
- expect(parent.value).toBe("B")
178
+ expect(parent.value).toBe("B");
179
179
  expect(parent.children[0]).toBe(b);
180
180
  expect(a.parent).toBeNull();
181
181
  expect(b.parent).toBe(parent);
@@ -191,7 +191,7 @@ describe("Node", () => {
191
191
  parent.find(p => p.name === "b")?.remove();
192
192
 
193
193
  expect(parent.children.length).toBe(1);
194
- expect(parent.value).toBe("A")
194
+ expect(parent.value).toBe("A");
195
195
  expect(parent.children[0]).toBe(a);
196
196
  expect(a.parent).toBe(parent);
197
197
  expect(b.parent).toBeNull();
@@ -203,7 +203,7 @@ describe("Node", () => {
203
203
  const b = new Node("b", "b", 0, 0, [], "B");
204
204
  new Node("parent", "parent", 0, 0, [a, b]);
205
205
 
206
- const nextSibling = a.nextSibling()
206
+ const nextSibling = a.nextSibling();
207
207
 
208
208
  expect(nextSibling).toBe(b);
209
209
  });
@@ -211,7 +211,7 @@ describe("Node", () => {
211
211
  test("Next Sibling (No Parent)", () => {
212
212
  const a = new Node("a", "a", 0, 0, [], "A");
213
213
 
214
- const nextSibling = a.nextSibling()
214
+ const nextSibling = a.nextSibling();
215
215
  expect(nextSibling).toBeNull;
216
216
  });
217
217
 
@@ -220,7 +220,7 @@ describe("Node", () => {
220
220
  const b = new Node("b", "b", 0, 0, [], "B");
221
221
  new Node("parent", "parent", 0, 0, [a, b]);
222
222
 
223
- const nextSibling = b.nextSibling()
223
+ const nextSibling = b.nextSibling();
224
224
  expect(nextSibling).toBeNull;
225
225
  });
226
226
 
@@ -229,14 +229,14 @@ describe("Node", () => {
229
229
  const b = new Node("b", "b", 0, 0, [], "B");
230
230
  new Node("parent", "parent", 0, 0, [a, b]);
231
231
 
232
- const previousSibling = b.previousSibling()
232
+ const previousSibling = b.previousSibling();
233
233
 
234
234
  expect(previousSibling).toBe(a);
235
235
  });
236
236
 
237
237
  test("Previous Sibling (No Parent)", () => {
238
238
  const a = new Node("a", "a", 0, 0, [], "A");
239
- const previousSibling = a.previousSibling()
239
+ const previousSibling = a.previousSibling();
240
240
  expect(previousSibling).toBeNull();
241
241
  });
242
242
 
@@ -245,7 +245,7 @@ describe("Node", () => {
245
245
  const b = new Node("b", "b", 0, 0, [], "B");
246
246
  new Node("parent", "parent", 0, 0, [a, b]);
247
247
 
248
- const previousSibling = a.previousSibling()
248
+ const previousSibling = a.previousSibling();
249
249
  expect(previousSibling).toBeNull;
250
250
  });
251
251
 
@@ -256,7 +256,7 @@ describe("Node", () => {
256
256
 
257
257
  const result = parent.find(n => n.name === "a");
258
258
 
259
- expect(result).toBe(a)
259
+ expect(result).toBe(a);
260
260
  });
261
261
 
262
262
  test("Walk Down", () => {
@@ -266,7 +266,7 @@ describe("Node", () => {
266
266
  const parent = new Node("parent", "parent", 0, 0, [a, b]);
267
267
 
268
268
  parent.walkDown((n) => {
269
- result.push(n)
269
+ result.push(n);
270
270
  });
271
271
 
272
272
  const expected = [parent, a, b];
@@ -281,7 +281,7 @@ describe("Node", () => {
281
281
  const parent = new Node("parent", "parent", 0, 0, [a, b]);
282
282
 
283
283
  parent.walkUp((n) => {
284
- result.push(n)
284
+ result.push(n);
285
285
  });
286
286
 
287
287
  const expected = [a, b, parent];
@@ -295,7 +295,7 @@ describe("Node", () => {
295
295
  const parent = new Node("parent", "parent", 0, 0, [a, b]);
296
296
  const clone = parent.clone();
297
297
 
298
- expect(clone).toEqual(parent)
298
+ expect(clone).toEqual(parent);
299
299
  });
300
300
 
301
301
  test("Turn Into JSON", () => {
@@ -307,16 +307,12 @@ describe("Node", () => {
307
307
  type: "parent",
308
308
  name: "parent",
309
309
  value: "AB",
310
- firstIndex: 0,
311
- lastIndex: 0,
312
310
  startIndex: 0,
313
311
  endIndex: 1,
314
312
  children: [{
315
313
  type: "a",
316
314
  name: "a",
317
315
  value: "A",
318
- firstIndex: 0,
319
- lastIndex: 0,
320
316
  startIndex: 0,
321
317
  endIndex: 1,
322
318
  children: [],
@@ -324,15 +320,13 @@ describe("Node", () => {
324
320
  type: "b",
325
321
  name: "b",
326
322
  value: "B",
327
- firstIndex: 0,
328
- lastIndex: 0,
329
323
  startIndex: 0,
330
324
  endIndex: 1,
331
325
  children: [],
332
326
  }],
333
327
  });
334
328
 
335
- expect(result).toEqual(expected)
329
+ expect(result).toEqual(expected);
336
330
  });
337
331
 
338
332
  test("Reduce", () => {
@@ -343,7 +337,7 @@ describe("Node", () => {
343
337
  parent.reduce();
344
338
 
345
339
  expect(parent.hasChildren).toBeFalsy();
346
- expect(parent.value).toBe("Content")
340
+ expect(parent.value).toBe("Content");
347
341
  });
348
342
 
349
343
  test("Flatten", () => {
@@ -364,22 +358,22 @@ describe("Node", () => {
364
358
  const nodes = grandParent.flatten();
365
359
  const expected = [a, b, c];
366
360
 
367
- expect(nodes).toEqual(expected)
361
+ expect(nodes).toEqual(expected);
368
362
  });
369
363
 
370
364
  test("Find Ancester", () => {
371
365
  const child = new Node("child", "child", 0, 0, []);
372
366
  const parent = new Node("parent", "parent", 0, 0, [child]);
373
367
  const grandParent = new Node("grand-parent", "grand-parent", 0, 0, [parent]);
374
- const result = child.findAncester(p => p.name === "grand-parent")
368
+ const result = child.findAncestor(p => p.name === "grand-parent");
375
369
 
376
- expect(result).toBe(grandParent)
370
+ expect(result).toBe(grandParent);
377
371
  });
378
372
 
379
373
  test("Find Ancester Without Parent", () => {
380
374
  const child = new Node("child", "child", 0, 0, []);
381
- const result = child.findAncester(p => p.name === "parent")
382
- expect(result).toBeNull()
375
+ const result = child.findAncestor(p => p.name === "parent");
376
+ expect(result).toBeNull();
383
377
  });
384
378
 
385
379
  test("Normalize values and index", () => {
@@ -426,4 +420,40 @@ describe("Node", () => {
426
420
 
427
421
  });
428
422
 
423
+ test("Transform", () => {
424
+ const node = Node.createNode("grandparent", [
425
+ Node.createNode("parent", [
426
+ Node.createValueNode("child", "John"),
427
+ Node.createValueNode("child", "Jane"),
428
+ Node.createValueNode("child", "Jack")
429
+ ]),
430
+ Node.createValueNode("aunt", "aunt")
431
+ ]);
432
+
433
+ const result = node.transform({
434
+ "child": (node: Node) => {
435
+ return Node.createValueNode("adopted-child", node.value);
436
+ },
437
+ "parent": (node)=>{
438
+ return Node.createNode("adopted-parent", node.children.slice());
439
+ },
440
+ "grandparent": (node)=>{
441
+ return Node.createNode("adopted-grandparent", node.children.slice());
442
+ }
443
+ });
444
+
445
+ const expected = Node.createNode("adopted-grandparent", [
446
+ Node.createNode("adopted-parent", [
447
+ Node.createValueNode("adopted-child", "John"),
448
+ Node.createValueNode("adopted-child", "Jane"),
449
+ Node.createValueNode("adopted-child", "Jack")
450
+ ]),
451
+ Node.createValueNode("aunt", "aunt")
452
+ ]);
453
+
454
+
455
+
456
+ expect(result.toJson()).toBe(expected.toJson());
457
+ });
458
+
429
459
  });
package/src/ast/Node.ts CHANGED
@@ -1,8 +1,10 @@
1
+ function defaultVisitor(node: Node) {
2
+ return node;
3
+ }
4
+
1
5
  export interface CycleFreeNode {
2
6
  type: string;
3
7
  name: string;
4
- firstIndex: number;
5
- lastIndex: number;
6
8
  startIndex: number;
7
9
  endIndex: number;
8
10
  value: string;
@@ -54,6 +56,10 @@ export class Node {
54
56
  return this._children.length > 0;
55
57
  }
56
58
 
59
+ get isLeaf(): boolean {
60
+ return !this.hasChildren;
61
+ }
62
+
57
63
  get value() {
58
64
  return this.toString();
59
65
  }
@@ -74,7 +80,7 @@ export class Node {
74
80
  this._children = children;
75
81
  this._value = value;
76
82
 
77
- this._children.forEach(c => c._parent = this)
83
+ this._children.forEach(c => c._parent = this);
78
84
  }
79
85
 
80
86
  removeChild(node: Node) {
@@ -86,18 +92,28 @@ export class Node {
86
92
  }
87
93
  }
88
94
 
95
+ findChildIndex(node: Node) {
96
+ return this._children.indexOf(node);
97
+ }
98
+
99
+ spliceChildren(index: number, deleteCount: number, ...items: Node[]) {
100
+ const removedItems = this._children.splice(index, deleteCount, ...items);
101
+
102
+ removedItems.forEach(i => i._parent = null);
103
+ items.forEach(i => i._parent = this);
104
+
105
+ return removedItems;
106
+ }
107
+
89
108
  removeAllChildren() {
90
- this._children.forEach(c => c._parent = null);
91
- this._children.length = 0;
109
+ this.spliceChildren(0, this._children.length);
92
110
  }
93
111
 
94
112
  replaceChild(newNode: Node, referenceNode: Node) {
95
- const index = this._children.indexOf(referenceNode);
113
+ const index = this.findChildIndex(referenceNode);
96
114
 
97
115
  if (index > -1) {
98
- this._children.splice(index, 1, newNode);
99
- newNode._parent = this;
100
- referenceNode._parent = null;
116
+ this.spliceChildren(index, 1, newNode);
101
117
  }
102
118
  }
103
119
 
@@ -115,7 +131,7 @@ export class Node {
115
131
  return;
116
132
  }
117
133
 
118
- const index = this._children.indexOf(referenceNode);
134
+ const index = this.findChildIndex(referenceNode);
119
135
 
120
136
  if (index > -1) {
121
137
  this._children.splice(index, 0, newNode);
@@ -123,17 +139,14 @@ export class Node {
123
139
  }
124
140
 
125
141
  appendChild(newNode: Node) {
126
- newNode._parent = this;
127
- this._children.push(newNode);
142
+ this.append(newNode);
128
143
  }
129
144
 
130
- spliceChildren(index: number, deleteCount: number, ...items: Node[]) {
131
- const removedItems = this._children.splice(index, deleteCount, ...items);
132
-
133
- removedItems.forEach(i => i._parent = null);
134
- items.forEach(i => i._parent = this);
135
-
136
- return removedItems;
145
+ append(...nodes: Node[]) {
146
+ nodes.forEach((newNode: Node) => {
147
+ newNode._parent = this;
148
+ this._children.push(newNode);
149
+ });
137
150
  }
138
151
 
139
152
  nextSibling() {
@@ -145,10 +158,10 @@ export class Node {
145
158
  const index = children.indexOf(this);
146
159
 
147
160
  if (index > -1 && index < children.length - 1) {
148
- return children[index + 1]
161
+ return children[index + 1];
149
162
  }
150
163
 
151
- return null
164
+ return null;
152
165
  }
153
166
 
154
167
  previousSibling() {
@@ -160,26 +173,27 @@ export class Node {
160
173
  const index = children.indexOf(this);
161
174
 
162
175
  if (index > -1 && index > 0) {
163
- return children[index - 1]
176
+ return children[index - 1];
164
177
  }
165
178
 
166
- return null
179
+ return null;
167
180
  }
168
181
 
169
182
  find(predicate: (node: Node) => boolean): Node | null {
170
- return this.findAll(predicate)[0] || null
183
+ return this.findAll(predicate)[0] || null;
171
184
  }
172
185
 
173
186
  findAll(predicate: (node: Node) => boolean): Node[] {
174
187
  const matches: Node[] = [];
188
+
175
189
  this.walkUp(n => {
176
190
  if (predicate(n)) { matches.push(n); }
177
- })
191
+ });
178
192
 
179
193
  return matches;
180
194
  }
181
195
 
182
- findAncester(predicate: (node: Node) => boolean) {
196
+ findAncestor(predicate: (node: Node) => boolean) {
183
197
  let parent = this._parent;
184
198
 
185
199
  while (parent != null) {
@@ -196,7 +210,7 @@ export class Node {
196
210
  walkUp(callback: (node: Node) => void) {
197
211
  const childrenCopy = this._children.slice();
198
212
 
199
- childrenCopy.forEach(c => c.walkUp(callback))
213
+ childrenCopy.forEach(c => c.walkUp(callback));
200
214
  callback(this);
201
215
  }
202
216
 
@@ -204,7 +218,29 @@ export class Node {
204
218
  const childrenCopy = this._children.slice();
205
219
 
206
220
  callback(this);
207
- childrenCopy.forEach(c => c.walkDown(callback))
221
+ childrenCopy.forEach(c => c.walkDown(callback));
222
+ }
223
+
224
+ walkBreadthFirst(callback: (node: Node) => void): void {
225
+ const queue: Node[] = [this];
226
+
227
+ while (queue.length > 0) {
228
+ // biome-ignore lint/style/noNonNullAssertion: This will never be undefined.
229
+ const current = queue.shift()!;
230
+ callback(current);
231
+ queue.push(...current.children);
232
+ }
233
+ }
234
+
235
+ transform(visitors: Record<string, (node: Node) => Node>) {
236
+ const childrenCopy = this._children.slice();
237
+ const visitor = visitors[this.name] == null ? defaultVisitor : visitors[this.name];
238
+
239
+ const children = childrenCopy.map(c => c.transform(visitors));
240
+ this.removeAllChildren();
241
+ this.append(...children);
242
+
243
+ return visitor(this);
208
244
  }
209
245
 
210
246
  flatten() {
@@ -261,7 +297,7 @@ export class Node {
261
297
  return this._value;
262
298
  }
263
299
 
264
- return this._children.map(c => c.toString()).join("")
300
+ return this._children.map(c => c.toString()).join("");
265
301
  }
266
302
 
267
303
  toCycleFreeObject(): CycleFreeNode {
@@ -269,15 +305,22 @@ export class Node {
269
305
  type: this._type,
270
306
  name: this._name,
271
307
  value: this.toString(),
272
- firstIndex: this._firstIndex,
273
- lastIndex: this._lastIndex,
274
308
  startIndex: this.startIndex,
275
309
  endIndex: this.endIndex,
276
310
  children: this._children.map(c => c.toCycleFreeObject()),
277
- }
311
+ };
278
312
  }
279
313
 
280
314
  toJson(space?: number): string {
281
- return JSON.stringify(this.toCycleFreeObject(), null, space)
315
+ return JSON.stringify(this.toCycleFreeObject(), null, space);
316
+ }
317
+
318
+ static createValueNode(name: string, value: string) {
319
+ return new Node("custom-value-node", name, 0, 0, [], value);
320
+ }
321
+
322
+ static createNode(name: string, children: Node[]) {
323
+ const value = children.map(c => c.toString()).join("");
324
+ return new Node("custom-node", name, 0, 0, children, value);
282
325
  }
283
326
  }
@@ -1,5 +1,4 @@
1
1
  import { Sequence } from "../patterns/Sequence";
2
- import { arePatternsEqual } from "../patterns/arePatternsEqual";
3
2
  import { Literal } from "../patterns/Literal";
4
3
  import { Not } from "../patterns/Not";
5
4
  import { Options } from "../patterns/Options";
@@ -20,7 +19,7 @@ describe("Grammar", () => {
20
19
  const namePattern = patterns["name"];
21
20
  const expected = new Literal("name", "John");
22
21
 
23
- expect(arePatternsEqual(namePattern, expected)).toBeTruthy();
22
+ expect(namePattern.isEqual(expected)).toBeTruthy();
24
23
  });
25
24
 
26
25
  test("Literal With Escaped Characters", () => {
@@ -31,7 +30,7 @@ describe("Grammar", () => {
31
30
  const namePattern = patterns["chars"];
32
31
  const expected = new Literal("chars", "\n\r\t\b\f\v\0\x00\u0000\"\\");
33
32
 
34
- expect(arePatternsEqual(namePattern, expected)).toBeTruthy();
33
+ expect(namePattern.isEqual(expected)).toBeTruthy();
35
34
  });
36
35
 
37
36
  test("Literal With Escaped Quotes", () => {
@@ -42,7 +41,7 @@ describe("Grammar", () => {
42
41
  const namePattern = patterns["content"];
43
42
  const expected = new Literal("content", "With Con\"tent");
44
43
 
45
- expect(arePatternsEqual(namePattern, expected)).toBeTruthy();
44
+ expect(namePattern.isEqual(expected)).toBeTruthy();
46
45
  });
47
46
 
48
47
  test("Regex", () => {
@@ -54,7 +53,7 @@ describe("Grammar", () => {
54
53
  const pattern = patterns["name"];
55
54
  const name = new Regex("name", "\\w");
56
55
 
57
- expect(arePatternsEqual(pattern, name)).toBeTruthy();
56
+ expect(pattern.isEqual(name)).toBeTruthy();
58
57
  });
59
58
 
60
59
  test("Or", () => {
@@ -70,7 +69,7 @@ describe("Grammar", () => {
70
69
  const jane = new Literal("jane", "Jane");
71
70
  const names = new Options("names", [john, jane], true);
72
71
 
73
- expect(arePatternsEqual(pattern, names)).toBeTruthy();
72
+ expect(pattern.isEqual(names)).toBeTruthy();
74
73
  });
75
74
 
76
75
  test("And", () => {
@@ -88,7 +87,7 @@ describe("Grammar", () => {
88
87
  const lastName = new Regex("last-name", "\\w");
89
88
  const fullName = new Sequence("full-name", [firstName, space, lastName]);
90
89
 
91
- expect(arePatternsEqual(pattern, fullName)).toBeTruthy();
90
+ expect(pattern.isEqual(fullName)).toBeTruthy();
92
91
  });
93
92
 
94
93
  test("And With Optional Pattern", () => {
@@ -110,7 +109,7 @@ describe("Grammar", () => {
110
109
  const middleNameWithSpace = new Optional("optional-middle-name-with-space", new Sequence("middle-name-with-space", [middleName, space]));
111
110
  const fullName = new Sequence("full-name", [firstName, space, middleNameWithSpace, lastName]);
112
111
 
113
- expect(arePatternsEqual(pattern, fullName)).toBeTruthy();
112
+ expect(pattern.isEqual(fullName)).toBeTruthy();
114
113
  });
115
114
 
116
115
  test("And With Not Pattern", () => {
@@ -134,7 +133,8 @@ describe("Grammar", () => {
134
133
  const notJack = new Not("not-jack", jack);
135
134
  const middleNameWithSpace = new Optional("optional-middle-name-with-space", new Sequence("middle-name-with-space", [middleName, space]));
136
135
  const fullName = new Sequence("full-name", [notJack, firstName, space, middleNameWithSpace, lastName]);
137
- expect(arePatternsEqual(pattern, fullName)).toBeTruthy();
136
+
137
+ expect(pattern.isEqual(fullName)).toBeTruthy();
138
138
  });
139
139
 
140
140
  test("Repeat", () => {
@@ -148,7 +148,7 @@ describe("Grammar", () => {
148
148
  const digit = new Regex("digit", "\\d");
149
149
  const digits = new Repeat("digits", digit);
150
150
 
151
- expect(arePatternsEqual(pattern, digits)).toBeTruthy();
151
+ expect(pattern.isEqual(digits)).toBeTruthy();
152
152
  });
153
153
 
154
154
  test("Repeat Zero Or More", () => {
@@ -162,7 +162,7 @@ describe("Grammar", () => {
162
162
  const digit = new Regex("digit", "\\d");
163
163
  const digits = new Optional("digits", new Repeat("digits", digit, { min: 0 }));
164
164
 
165
- expect(arePatternsEqual(pattern, digits)).toBeTruthy();
165
+ expect(pattern.isEqual(digits)).toBeTruthy();
166
166
  });
167
167
 
168
168
  test("Repeat Lower Limit", () => {
@@ -176,7 +176,7 @@ describe("Grammar", () => {
176
176
  const digit = new Regex("digit", "\\d+");
177
177
  const digits = new Repeat("digits", digit, { min: 1 });
178
178
 
179
- expect(arePatternsEqual(pattern, digits)).toBeTruthy();
179
+ expect(pattern.isEqual(digits)).toBeTruthy();
180
180
  });
181
181
 
182
182
  test("Repeat Bounded", () => {
@@ -189,7 +189,8 @@ describe("Grammar", () => {
189
189
  const pattern = patterns["digits"];
190
190
  const digit = new Regex("digit", "\\d+");
191
191
  const digits = new Repeat("digits", digit, { min: 1, max: 3 });
192
- expect(arePatternsEqual(pattern, digits)).toBeTruthy();
192
+
193
+ expect(pattern.isEqual(digits)).toBeTruthy();
193
194
  });
194
195
 
195
196
  test("Repeat Upper Limit", () => {
@@ -203,7 +204,7 @@ describe("Grammar", () => {
203
204
  const digit = new Regex("digit", "\\d+");
204
205
  const digits = new Repeat("digits", digit, { min: 0, max: 3 });
205
206
 
206
- expect(arePatternsEqual(pattern, digits)).toBeTruthy();
207
+ expect(pattern.isEqual(digits)).toBeTruthy();
207
208
  });
208
209
 
209
210
  test("Repeat Exact", () => {
@@ -217,7 +218,7 @@ describe("Grammar", () => {
217
218
  const digit = new Regex("digit", "\\d+");
218
219
  const digits = new Repeat("digits", digit, { min: 3, max: 3 });
219
220
 
220
- expect(arePatternsEqual(pattern, digits)).toBeTruthy();
221
+ expect(pattern.isEqual(digits)).toBeTruthy();
221
222
  });
222
223
 
223
224
  test("Repeat Divider", () => {
@@ -233,7 +234,7 @@ describe("Grammar", () => {
233
234
  const divider = new Literal("comma", ",");
234
235
  const digits = new Repeat("digits", digit, { divider, min: 3, max: 3 });
235
236
 
236
- expect(arePatternsEqual(pattern, digits)).toBeTruthy();
237
+ expect(pattern.isEqual(digits)).toBeTruthy();
237
238
  });
238
239
 
239
240
  test("Repeat Divider With Trim Divider", () => {
@@ -248,8 +249,8 @@ describe("Grammar", () => {
248
249
  const digit = new Regex("digit", "\\d+");
249
250
  const divider = new Literal("comma", ",");
250
251
  const digits = new Repeat("digits", digit, { divider, min: 1, trimDivider: true });
251
- debugger;
252
- expect(arePatternsEqual(pattern, digits)).toBeTruthy();
252
+
253
+ expect(pattern.isEqual(digits)).toBeTruthy();
253
254
  });
254
255
 
255
256
  test("Repeat Divider With Trim Divider And Bounds", () => {
@@ -265,7 +266,7 @@ describe("Grammar", () => {
265
266
  const divider = new Literal("comma", ",");
266
267
  const digits = new Repeat("digits", digit, { divider, min: 3, max: 3, trimDivider: true });
267
268
 
268
- expect(arePatternsEqual(pattern, digits)).toBeTruthy();
269
+ expect(pattern.isEqual(digits)).toBeTruthy();
269
270
  });
270
271
 
271
272
  test("Reference", () => {
@@ -303,8 +304,8 @@ describe("Grammar", () => {
303
304
  const alias = patterns["alias"];
304
305
  const expectedAlias = new Regex("alias", "regex");
305
306
 
306
- expect(arePatternsEqual(name, expectedName)).toBeTruthy();
307
- expect(arePatternsEqual(alias, expectedAlias)).toBeTruthy();
307
+ expect(name.isEqual(expectedName)).toBeTruthy();
308
+ expect(alias.isEqual(expectedAlias)).toBeTruthy();
308
309
  });
309
310
 
310
311
  test("Bad Grammar At Beginning", () => {
@@ -497,17 +498,17 @@ describe("Grammar", () => {
497
498
  ])
498
499
  ]);
499
500
 
500
- expect(arePatternsEqual(patterns["complex-expression"], expected)).toBeTruthy();
501
+ expect(patterns["complex-expression"].isEqual(expected)).toBeTruthy();
501
502
  });
502
503
 
503
- test("Grammar With Spaces", ()=>{
504
+ test("Grammar With Spaces", () => {
504
505
  const expression = `
505
506
  john = "John"
506
507
 
507
508
  jane = "Jane"
508
509
  `;
509
510
  const patterns = Grammar.parseString(expression);
510
- expect(patterns.john).not.toBeNull();
511
- expect(patterns.jane).not.toBeNull();
511
+ expect(patterns.john).not.toBeNull();
512
+ expect(patterns.jane).not.toBeNull();
512
513
  });
513
514
  });
@@ -131,7 +131,7 @@ export class Grammar {
131
131
  }
132
132
 
133
133
  private _buildPatterns(ast: Node) {
134
- const body = ast.find(n => n.name === "body" && n.findAncester(n => n.name === "head") == null);
134
+ const body = ast.find(n => n.name === "body" && n.findAncestor(n => n.name === "head") == null);
135
135
 
136
136
  if (body == null) {
137
137
  return;