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/dist/ast/Node.d.ts +9 -4
- package/dist/index.browser.js +69 -45
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.esm.js +70 -45
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +69 -45
- package/dist/index.js.map +1 -1
- package/dist/patterns/Cursor.d.ts +1 -1
- package/dist/patterns/CursorHistory.d.ts +1 -1
- package/dist/patterns/Literal.d.ts +3 -3
- package/dist/patterns/Pattern.d.ts +1 -1
- package/dist/types.d.ts +797 -0
- package/package.json +1 -1
- package/src/ast/Node.test.ts +60 -30
- package/src/ast/Node.ts +76 -33
- package/src/grammar/Grammar.test.ts +26 -25
- package/src/grammar/Grammar.ts +1 -1
- package/src/index.ts +0 -2
- package/src/patterns/Cursor.ts +5 -4
- package/src/patterns/CursorHistory.ts +3 -3
- package/src/patterns/FiniteRepeat.test.ts +4 -5
- package/src/patterns/InfiniteRepeat.test.ts +1 -2
- package/src/patterns/Literal.ts +12 -11
- package/src/patterns/ParseError.ts +1 -1
- package/src/patterns/Pattern.ts +1 -1
- package/src/patterns/Repeat.test.ts +2 -3
- package/src/patterns/arePatternsEqual.ts +0 -12
package/dist/ast/Node.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export interface CycleFreeNode {
|
|
2
2
|
type: string;
|
|
3
3
|
name: string;
|
|
4
|
-
firstIndex: number;
|
|
5
|
-
lastIndex: number;
|
|
6
4
|
startIndex: number;
|
|
7
5
|
endIndex: number;
|
|
8
6
|
value: string;
|
|
@@ -25,22 +23,27 @@ export declare class Node {
|
|
|
25
23
|
get parent(): Node | null;
|
|
26
24
|
get children(): readonly Node[];
|
|
27
25
|
get hasChildren(): boolean;
|
|
26
|
+
get isLeaf(): boolean;
|
|
28
27
|
get value(): string;
|
|
29
28
|
constructor(type: string, name: string, firstIndex: number, lastIndex: number, children?: Node[], value?: string);
|
|
30
29
|
removeChild(node: Node): void;
|
|
30
|
+
findChildIndex(node: Node): number;
|
|
31
|
+
spliceChildren(index: number, deleteCount: number, ...items: Node[]): Node[];
|
|
31
32
|
removeAllChildren(): void;
|
|
32
33
|
replaceChild(newNode: Node, referenceNode: Node): void;
|
|
33
34
|
replaceWith(newNode: Node): void;
|
|
34
35
|
insertBefore(newNode: Node, referenceNode: Node | null): void;
|
|
35
36
|
appendChild(newNode: Node): void;
|
|
36
|
-
|
|
37
|
+
append(...nodes: Node[]): void;
|
|
37
38
|
nextSibling(): Node | null;
|
|
38
39
|
previousSibling(): Node | null;
|
|
39
40
|
find(predicate: (node: Node) => boolean): Node | null;
|
|
40
41
|
findAll(predicate: (node: Node) => boolean): Node[];
|
|
41
|
-
|
|
42
|
+
findAncestor(predicate: (node: Node) => boolean): Node | null;
|
|
42
43
|
walkUp(callback: (node: Node) => void): void;
|
|
43
44
|
walkDown(callback: (node: Node) => void): void;
|
|
45
|
+
walkBreadthFirst(callback: (node: Node) => void): void;
|
|
46
|
+
transform(visitors: Record<string, (node: Node) => Node>): Node;
|
|
44
47
|
flatten(): Node[];
|
|
45
48
|
reduce(): void;
|
|
46
49
|
remove(): void;
|
|
@@ -49,4 +52,6 @@ export declare class Node {
|
|
|
49
52
|
toString(): string;
|
|
50
53
|
toCycleFreeObject(): CycleFreeNode;
|
|
51
54
|
toJson(space?: number): string;
|
|
55
|
+
static createValueNode(name: string, value: string): Node;
|
|
56
|
+
static createNode(name: string, children: Node[]): Node;
|
|
52
57
|
}
|
package/dist/index.browser.js
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.clarityPatternParser = {}));
|
|
5
5
|
})(this, (function (exports) { 'use strict';
|
|
6
6
|
|
|
7
|
+
function defaultVisitor(node) {
|
|
8
|
+
return node;
|
|
9
|
+
}
|
|
7
10
|
class Node {
|
|
8
11
|
get type() {
|
|
9
12
|
return this._type;
|
|
@@ -32,6 +35,9 @@
|
|
|
32
35
|
get hasChildren() {
|
|
33
36
|
return this._children.length > 0;
|
|
34
37
|
}
|
|
38
|
+
get isLeaf() {
|
|
39
|
+
return !this.hasChildren;
|
|
40
|
+
}
|
|
35
41
|
get value() {
|
|
36
42
|
return this.toString();
|
|
37
43
|
}
|
|
@@ -52,16 +58,22 @@
|
|
|
52
58
|
node._parent = null;
|
|
53
59
|
}
|
|
54
60
|
}
|
|
61
|
+
findChildIndex(node) {
|
|
62
|
+
return this._children.indexOf(node);
|
|
63
|
+
}
|
|
64
|
+
spliceChildren(index, deleteCount, ...items) {
|
|
65
|
+
const removedItems = this._children.splice(index, deleteCount, ...items);
|
|
66
|
+
removedItems.forEach(i => i._parent = null);
|
|
67
|
+
items.forEach(i => i._parent = this);
|
|
68
|
+
return removedItems;
|
|
69
|
+
}
|
|
55
70
|
removeAllChildren() {
|
|
56
|
-
this.
|
|
57
|
-
this._children.length = 0;
|
|
71
|
+
this.spliceChildren(0, this._children.length);
|
|
58
72
|
}
|
|
59
73
|
replaceChild(newNode, referenceNode) {
|
|
60
|
-
const index = this.
|
|
74
|
+
const index = this.findChildIndex(referenceNode);
|
|
61
75
|
if (index > -1) {
|
|
62
|
-
this.
|
|
63
|
-
newNode._parent = this;
|
|
64
|
-
referenceNode._parent = null;
|
|
76
|
+
this.spliceChildren(index, 1, newNode);
|
|
65
77
|
}
|
|
66
78
|
}
|
|
67
79
|
replaceWith(newNode) {
|
|
@@ -75,20 +87,19 @@
|
|
|
75
87
|
this._children.push(newNode);
|
|
76
88
|
return;
|
|
77
89
|
}
|
|
78
|
-
const index = this.
|
|
90
|
+
const index = this.findChildIndex(referenceNode);
|
|
79
91
|
if (index > -1) {
|
|
80
92
|
this._children.splice(index, 0, newNode);
|
|
81
93
|
}
|
|
82
94
|
}
|
|
83
95
|
appendChild(newNode) {
|
|
84
|
-
newNode
|
|
85
|
-
this._children.push(newNode);
|
|
96
|
+
this.append(newNode);
|
|
86
97
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
98
|
+
append(...nodes) {
|
|
99
|
+
nodes.forEach((newNode) => {
|
|
100
|
+
newNode._parent = this;
|
|
101
|
+
this._children.push(newNode);
|
|
102
|
+
});
|
|
92
103
|
}
|
|
93
104
|
nextSibling() {
|
|
94
105
|
if (this._parent == null) {
|
|
@@ -124,7 +135,7 @@
|
|
|
124
135
|
});
|
|
125
136
|
return matches;
|
|
126
137
|
}
|
|
127
|
-
|
|
138
|
+
findAncestor(predicate) {
|
|
128
139
|
let parent = this._parent;
|
|
129
140
|
while (parent != null) {
|
|
130
141
|
if (predicate(parent)) {
|
|
@@ -144,6 +155,23 @@
|
|
|
144
155
|
callback(this);
|
|
145
156
|
childrenCopy.forEach(c => c.walkDown(callback));
|
|
146
157
|
}
|
|
158
|
+
walkBreadthFirst(callback) {
|
|
159
|
+
const queue = [this];
|
|
160
|
+
while (queue.length > 0) {
|
|
161
|
+
// biome-ignore lint/style/noNonNullAssertion: This will never be undefined.
|
|
162
|
+
const current = queue.shift();
|
|
163
|
+
callback(current);
|
|
164
|
+
queue.push(...current.children);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
transform(visitors) {
|
|
168
|
+
const childrenCopy = this._children.slice();
|
|
169
|
+
const visitor = visitors[this.name] == null ? defaultVisitor : visitors[this.name];
|
|
170
|
+
const children = childrenCopy.map(c => c.transform(visitors));
|
|
171
|
+
this.removeAllChildren();
|
|
172
|
+
this.append(...children);
|
|
173
|
+
return visitor(this);
|
|
174
|
+
}
|
|
147
175
|
flatten() {
|
|
148
176
|
const nodes = [];
|
|
149
177
|
this.walkDown((node) => {
|
|
@@ -189,8 +217,6 @@
|
|
|
189
217
|
type: this._type,
|
|
190
218
|
name: this._name,
|
|
191
219
|
value: this.toString(),
|
|
192
|
-
firstIndex: this._firstIndex,
|
|
193
|
-
lastIndex: this._lastIndex,
|
|
194
220
|
startIndex: this.startIndex,
|
|
195
221
|
endIndex: this.endIndex,
|
|
196
222
|
children: this._children.map(c => c.toCycleFreeObject()),
|
|
@@ -199,6 +225,13 @@
|
|
|
199
225
|
toJson(space) {
|
|
200
226
|
return JSON.stringify(this.toCycleFreeObject(), null, space);
|
|
201
227
|
}
|
|
228
|
+
static createValueNode(name, value) {
|
|
229
|
+
return new Node("custom-value-node", name, 0, 0, [], value);
|
|
230
|
+
}
|
|
231
|
+
static createNode(name, children) {
|
|
232
|
+
const value = children.map(c => c.toString()).join("");
|
|
233
|
+
return new Node("custom-node", name, 0, 0, children, value);
|
|
234
|
+
}
|
|
202
235
|
}
|
|
203
236
|
|
|
204
237
|
/******************************************************************************
|
|
@@ -316,10 +349,10 @@
|
|
|
316
349
|
}
|
|
317
350
|
}
|
|
318
351
|
}
|
|
319
|
-
recordErrorAt(
|
|
320
|
-
const error = new ParseError(
|
|
352
|
+
recordErrorAt(startIndex, endIndex, pattern) {
|
|
353
|
+
const error = new ParseError(startIndex, endIndex, pattern);
|
|
321
354
|
this._currentError = error;
|
|
322
|
-
if (this._furthestError === null ||
|
|
355
|
+
if (this._furthestError === null || endIndex > this._furthestError.endIndex) {
|
|
323
356
|
this._furthestError = error;
|
|
324
357
|
}
|
|
325
358
|
if (this._isRecording) {
|
|
@@ -394,7 +427,7 @@
|
|
|
394
427
|
constructor(text) {
|
|
395
428
|
this._text = text;
|
|
396
429
|
this._index = 0;
|
|
397
|
-
this._length = text.length;
|
|
430
|
+
this._length = [...text].length;
|
|
398
431
|
this._history = new CursorHistory();
|
|
399
432
|
this._stackTrace = [];
|
|
400
433
|
}
|
|
@@ -434,8 +467,8 @@
|
|
|
434
467
|
recordMatch(pattern, node) {
|
|
435
468
|
this._history.recordMatch(pattern, node);
|
|
436
469
|
}
|
|
437
|
-
recordErrorAt(
|
|
438
|
-
this._history.recordErrorAt(
|
|
470
|
+
recordErrorAt(startIndex, endIndex, onPattern) {
|
|
471
|
+
this._history.recordErrorAt(startIndex, endIndex, onPattern);
|
|
439
472
|
}
|
|
440
473
|
resolveError() {
|
|
441
474
|
this._history.resolveError();
|
|
@@ -452,7 +485,8 @@
|
|
|
452
485
|
pattern,
|
|
453
486
|
cursorIndex: this.index
|
|
454
487
|
};
|
|
455
|
-
|
|
488
|
+
const hasCycle = this._stackTrace.find(t => t.pattern.id === pattern.id && this.index === t.cursorIndex);
|
|
489
|
+
if (hasCycle) {
|
|
456
490
|
throw new Error(`Cyclical Pattern: ${this._stackTrace.map(t => `${t.pattern.name}#${t.pattern.id}{${t.cursorIndex}}`).join(" -> ")} -> ${patternName}#${pattern.id}{${this.index}}.`);
|
|
457
491
|
}
|
|
458
492
|
this._history.pushStackTrace(trace);
|
|
@@ -488,8 +522,8 @@
|
|
|
488
522
|
get name() {
|
|
489
523
|
return this._name;
|
|
490
524
|
}
|
|
491
|
-
get
|
|
492
|
-
return this.
|
|
525
|
+
get token() {
|
|
526
|
+
return this._token;
|
|
493
527
|
}
|
|
494
528
|
get parent() {
|
|
495
529
|
return this._parent;
|
|
@@ -507,15 +541,16 @@
|
|
|
507
541
|
this._id = `literal-${idIndex$9++}`;
|
|
508
542
|
this._type = "literal";
|
|
509
543
|
this._name = name;
|
|
510
|
-
this.
|
|
544
|
+
this._token = value;
|
|
511
545
|
this._runes = Array.from(value);
|
|
512
546
|
this._parent = null;
|
|
513
547
|
this._firstIndex = 0;
|
|
514
548
|
this._lastIndex = 0;
|
|
515
549
|
this._endIndex = 0;
|
|
516
550
|
}
|
|
517
|
-
test(text) {
|
|
551
|
+
test(text, record = false) {
|
|
518
552
|
const cursor = new Cursor(text);
|
|
553
|
+
record && cursor.startRecording();
|
|
519
554
|
const ast = this.parse(cursor);
|
|
520
555
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
521
556
|
}
|
|
@@ -554,7 +589,7 @@
|
|
|
554
589
|
break;
|
|
555
590
|
}
|
|
556
591
|
if (i + 1 === literalRuneLength) {
|
|
557
|
-
this._lastIndex = this._firstIndex + this.
|
|
592
|
+
this._lastIndex = this._firstIndex + this._token.length - 1;
|
|
558
593
|
passed = true;
|
|
559
594
|
break;
|
|
560
595
|
}
|
|
@@ -567,15 +602,15 @@
|
|
|
567
602
|
return passed;
|
|
568
603
|
}
|
|
569
604
|
_createNode() {
|
|
570
|
-
return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this.
|
|
605
|
+
return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this._token);
|
|
571
606
|
}
|
|
572
607
|
clone(name = this._name) {
|
|
573
|
-
const clone = new Literal(name, this.
|
|
608
|
+
const clone = new Literal(name, this._token);
|
|
574
609
|
clone._id = this._id;
|
|
575
610
|
return clone;
|
|
576
611
|
}
|
|
577
612
|
getTokens() {
|
|
578
|
-
return [this.
|
|
613
|
+
return [this._token];
|
|
579
614
|
}
|
|
580
615
|
getTokensAfter(_lastMatched) {
|
|
581
616
|
return [];
|
|
@@ -602,7 +637,7 @@
|
|
|
602
637
|
return null;
|
|
603
638
|
}
|
|
604
639
|
isEqual(pattern) {
|
|
605
|
-
return pattern.type === this.type && pattern.
|
|
640
|
+
return pattern.type === this.type && pattern._token === this._token;
|
|
606
641
|
}
|
|
607
642
|
}
|
|
608
643
|
|
|
@@ -2554,7 +2589,7 @@
|
|
|
2554
2589
|
return importBlock && importBlock.children.length > 0;
|
|
2555
2590
|
}
|
|
2556
2591
|
_buildPatterns(ast) {
|
|
2557
|
-
const body = ast.find(n => n.name === "body" && n.
|
|
2592
|
+
const body = ast.find(n => n.name === "body" && n.findAncestor(n => n.name === "head") == null);
|
|
2558
2593
|
if (body == null) {
|
|
2559
2594
|
return;
|
|
2560
2595
|
}
|
|
@@ -2874,16 +2909,6 @@
|
|
|
2874
2909
|
}
|
|
2875
2910
|
}
|
|
2876
2911
|
|
|
2877
|
-
function arePatternsEqual(a, b) {
|
|
2878
|
-
if (a === b) {
|
|
2879
|
-
return true;
|
|
2880
|
-
}
|
|
2881
|
-
else if (a == null || b == null) {
|
|
2882
|
-
return false;
|
|
2883
|
-
}
|
|
2884
|
-
return a.isEqual(b);
|
|
2885
|
-
}
|
|
2886
|
-
|
|
2887
2912
|
const kebabRegex = /-([a-z])/g; // Define the regex once
|
|
2888
2913
|
function kebabToCamelCase(str) {
|
|
2889
2914
|
return str.replace(kebabRegex, (_, char) => char.toUpperCase());
|
|
@@ -2912,7 +2937,6 @@
|
|
|
2912
2937
|
exports.Regex = Regex;
|
|
2913
2938
|
exports.Repeat = Repeat;
|
|
2914
2939
|
exports.Sequence = Sequence;
|
|
2915
|
-
exports.arePatternsEqual = arePatternsEqual;
|
|
2916
2940
|
exports.grammar = grammar;
|
|
2917
2941
|
exports.patterns = patterns;
|
|
2918
2942
|
|