clarity-pattern-parser 11.0.6 → 11.0.7
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/TODO.md +1 -5
- package/dist/ast/Node.d.ts +3 -4
- package/dist/grammar/Grammar.d.ts +1 -1
- package/dist/index.browser.js +54 -54
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.esm.js +53 -54
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +54 -54
- package/dist/index.js.map +1 -1
- package/dist/patterns/CursorHistory.d.ts +1 -1
- package/dist/patterns/Expression.d.ts +66 -0
- package/dist/patterns/Pattern.d.ts +1 -1
- package/dist/patterns/RightAssociated.d.ts +31 -0
- package/package.json +1 -1
- package/src/ast/Node.test.ts +2 -2
- package/src/ast/Node.ts +15 -20
- package/src/grammar/Grammar.ts +20 -20
- package/src/grammar/patterns/sequenceLiteral.ts +3 -3
- package/src/index.ts +4 -2
- package/src/patterns/CursorHistory.ts +3 -3
- package/src/patterns/{ExpressionPattern.test.ts → Expression.test.ts} +8 -8
- package/src/patterns/{ExpressionPattern.ts → Expression.ts} +19 -13
- package/src/patterns/FiniteRepeat.ts +10 -5
- package/src/patterns/InfiniteRepeat.ts +2 -5
- package/src/patterns/Pattern.ts +1 -1
- package/src/patterns/{RightAssociatedPattern.ts → RightAssociated.ts} +2 -2
package/TODO.md
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
*
|
|
2
|
-
This will allow you to store a list of patterns and the pattern you want to start a parse from. This will hold the context of many patterns
|
|
3
|
-
that perhaps are references but are by way of the context. This will be helpful with cpat files.
|
|
4
|
-
|
|
5
|
-
* Optimizations We can add a map to the cursor where we can search through previous matches and if the match for this pattern with this id has already matched in other bracnhes of the parse it can just use the node and clone it and skip the full parse and speed up things tremendously
|
|
1
|
+
* Fix infinite repeat recursion with a reference
|
|
6
2
|
|
|
7
3
|
|
|
8
4
|
* Generate typescript files from cpat
|
package/dist/ast/Node.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export declare class Node {
|
|
|
16
16
|
private _value;
|
|
17
17
|
get type(): string;
|
|
18
18
|
get name(): string;
|
|
19
|
+
get value(): string;
|
|
19
20
|
get firstIndex(): number;
|
|
20
21
|
get lastIndex(): number;
|
|
21
22
|
get startIndex(): number;
|
|
@@ -24,7 +25,6 @@ export declare class Node {
|
|
|
24
25
|
get children(): readonly Node[];
|
|
25
26
|
get hasChildren(): boolean;
|
|
26
27
|
get isLeaf(): boolean;
|
|
27
|
-
get value(): string;
|
|
28
28
|
constructor(type: string, name: string, firstIndex: number, lastIndex: number, children?: Node[], value?: string);
|
|
29
29
|
removeChild(node: Node): void;
|
|
30
30
|
findChildIndex(node: Node): number;
|
|
@@ -38,19 +38,18 @@ export declare class Node {
|
|
|
38
38
|
nextSibling(): Node | null;
|
|
39
39
|
previousSibling(): Node | null;
|
|
40
40
|
find(predicate: (node: Node) => boolean): Node | null;
|
|
41
|
-
findRoot(): Node;
|
|
42
41
|
findAll(predicate: (node: Node) => boolean): Node[];
|
|
42
|
+
findRoot(): Node;
|
|
43
43
|
findAncestor(predicate: (node: Node) => boolean): Node | null;
|
|
44
44
|
walkUp(callback: (node: Node) => void): void;
|
|
45
45
|
walkDown(callback: (node: Node) => void): void;
|
|
46
46
|
walkBreadthFirst(callback: (node: Node) => void): void;
|
|
47
47
|
transform(visitors: Record<string, (node: Node) => Node>): Node;
|
|
48
48
|
flatten(): Node[];
|
|
49
|
-
|
|
49
|
+
compact(): void;
|
|
50
50
|
remove(): void;
|
|
51
51
|
clone(): Node;
|
|
52
52
|
normalize(startIndex?: number): number;
|
|
53
|
-
compact(): void;
|
|
54
53
|
toString(): string;
|
|
55
54
|
toCycleFreeObject(): CycleFreeNode;
|
|
56
55
|
toJson(space?: number): string;
|
|
@@ -17,8 +17,8 @@ export declare class Grammar {
|
|
|
17
17
|
constructor(options?: GrammarOptions);
|
|
18
18
|
import(path: string): Promise<Record<string, Pattern>>;
|
|
19
19
|
parse(expression: string): Promise<Record<string, Pattern>>;
|
|
20
|
-
private _buildPatternRecord;
|
|
21
20
|
parseString(expression: string): Record<string, Pattern>;
|
|
21
|
+
private _buildPatternRecord;
|
|
22
22
|
private _tryToParse;
|
|
23
23
|
private _hasImports;
|
|
24
24
|
private _buildPatterns;
|
package/dist/index.browser.js
CHANGED
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
get name() {
|
|
15
15
|
return this._name;
|
|
16
16
|
}
|
|
17
|
+
get value() {
|
|
18
|
+
return this.toString();
|
|
19
|
+
}
|
|
17
20
|
get firstIndex() {
|
|
18
21
|
return this._firstIndex;
|
|
19
22
|
}
|
|
@@ -38,9 +41,6 @@
|
|
|
38
41
|
get isLeaf() {
|
|
39
42
|
return !this.hasChildren;
|
|
40
43
|
}
|
|
41
|
-
get value() {
|
|
42
|
-
return this.toString();
|
|
43
|
-
}
|
|
44
44
|
constructor(type, name, firstIndex, lastIndex, children = [], value = "") {
|
|
45
45
|
this._type = type;
|
|
46
46
|
this._name = name;
|
|
@@ -128,15 +128,6 @@
|
|
|
128
128
|
find(predicate) {
|
|
129
129
|
return this.findAll(predicate)[0] || null;
|
|
130
130
|
}
|
|
131
|
-
findRoot() {
|
|
132
|
-
let pattern = this;
|
|
133
|
-
while (true) {
|
|
134
|
-
if (pattern.parent == null) {
|
|
135
|
-
return pattern;
|
|
136
|
-
}
|
|
137
|
-
pattern = pattern.parent;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
131
|
findAll(predicate) {
|
|
141
132
|
const matches = [];
|
|
142
133
|
this.walkUp(n => {
|
|
@@ -146,6 +137,15 @@
|
|
|
146
137
|
});
|
|
147
138
|
return matches;
|
|
148
139
|
}
|
|
140
|
+
findRoot() {
|
|
141
|
+
let pattern = this;
|
|
142
|
+
while (true) {
|
|
143
|
+
if (pattern.parent == null) {
|
|
144
|
+
return pattern;
|
|
145
|
+
}
|
|
146
|
+
pattern = pattern.parent;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
149
|
findAncestor(predicate) {
|
|
150
150
|
let parent = this._parent;
|
|
151
151
|
while (parent != null) {
|
|
@@ -191,7 +191,7 @@
|
|
|
191
191
|
});
|
|
192
192
|
return nodes;
|
|
193
193
|
}
|
|
194
|
-
|
|
194
|
+
compact() {
|
|
195
195
|
const value = this.toString();
|
|
196
196
|
this.removeAllChildren();
|
|
197
197
|
this._value = value;
|
|
@@ -222,10 +222,6 @@
|
|
|
222
222
|
this._lastIndex = Math.max(startIndex + length - 1, 0);
|
|
223
223
|
return length;
|
|
224
224
|
}
|
|
225
|
-
compact() {
|
|
226
|
-
this._value = this.toString();
|
|
227
|
-
this._children.length = 0;
|
|
228
|
-
}
|
|
229
225
|
toString() {
|
|
230
226
|
if (this._children.length === 0) {
|
|
231
227
|
return this._value;
|
|
@@ -397,10 +393,10 @@
|
|
|
397
393
|
}
|
|
398
394
|
}
|
|
399
395
|
}
|
|
400
|
-
recordErrorAt(startIndex,
|
|
401
|
-
const error = new ParseError(startIndex,
|
|
396
|
+
recordErrorAt(startIndex, lastIndex, pattern) {
|
|
397
|
+
const error = new ParseError(startIndex, lastIndex, pattern);
|
|
402
398
|
this._currentError = error;
|
|
403
|
-
if (this._furthestError === null ||
|
|
399
|
+
if (this._furthestError === null || lastIndex > this._furthestError.lastIndex) {
|
|
404
400
|
this._furthestError = error;
|
|
405
401
|
}
|
|
406
402
|
if (this._isRecording) {
|
|
@@ -1194,7 +1190,6 @@
|
|
|
1194
1190
|
}
|
|
1195
1191
|
parse(cursor) {
|
|
1196
1192
|
this._firstIndex = cursor.index;
|
|
1197
|
-
const startIndex = cursor.index;
|
|
1198
1193
|
const nodes = [];
|
|
1199
1194
|
const modulo = this._hasDivider ? 2 : 1;
|
|
1200
1195
|
let matchCount = 0;
|
|
@@ -1230,12 +1225,12 @@
|
|
|
1230
1225
|
}
|
|
1231
1226
|
if (matchCount < this._min) {
|
|
1232
1227
|
const lastIndex = cursor.index;
|
|
1233
|
-
cursor.moveTo(
|
|
1234
|
-
cursor.recordErrorAt(
|
|
1228
|
+
cursor.moveTo(this._firstIndex);
|
|
1229
|
+
cursor.recordErrorAt(this._firstIndex, lastIndex, this);
|
|
1235
1230
|
return null;
|
|
1236
1231
|
}
|
|
1237
1232
|
if (nodes.length === 0 && !cursor.hasError) {
|
|
1238
|
-
cursor.moveTo(
|
|
1233
|
+
cursor.moveTo(this._firstIndex);
|
|
1239
1234
|
return null;
|
|
1240
1235
|
}
|
|
1241
1236
|
const firstIndex = nodes[0].firstIndex;
|
|
@@ -1359,7 +1354,7 @@
|
|
|
1359
1354
|
this._children = children;
|
|
1360
1355
|
this._pattern = children[0];
|
|
1361
1356
|
this._divider = children[1];
|
|
1362
|
-
this._firstIndex =
|
|
1357
|
+
this._firstIndex = 0;
|
|
1363
1358
|
this._nodes = [];
|
|
1364
1359
|
this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
|
|
1365
1360
|
}
|
|
@@ -1539,7 +1534,7 @@
|
|
|
1539
1534
|
patterns.push(this._children[0]);
|
|
1540
1535
|
}
|
|
1541
1536
|
// If there is no divider then suggest the repeating pattern and the next pattern after.
|
|
1542
|
-
if (index === 0 &&
|
|
1537
|
+
if (index === 0 && this._divider == null && this._parent) {
|
|
1543
1538
|
patterns.push(this._children[0]);
|
|
1544
1539
|
patterns.push(...this._parent.getPatternsAfter(this));
|
|
1545
1540
|
}
|
|
@@ -2132,13 +2127,13 @@
|
|
|
2132
2127
|
const optionalNot = new Optional("optional-not", new Literal("not", "!"));
|
|
2133
2128
|
const optionalIsOptional$1 = new Optional("optional-is-optional", new Literal("is-optional", "?"));
|
|
2134
2129
|
const patternName$1 = name$1.clone("pattern-name");
|
|
2135
|
-
const patterns$2 = new Options("
|
|
2136
|
-
const pattern$1 = new Sequence("
|
|
2130
|
+
const patterns$2 = new Options("sequence-patterns", [patternName$1, anonymousPattern]);
|
|
2131
|
+
const pattern$1 = new Sequence("sequence-child-pattern", [
|
|
2137
2132
|
optionalNot,
|
|
2138
2133
|
patterns$2,
|
|
2139
2134
|
optionalIsOptional$1,
|
|
2140
2135
|
]);
|
|
2141
|
-
const divider$1 = new Regex("
|
|
2136
|
+
const divider$1 = new Regex("sequence-divider", "\\s*[+]\\s*");
|
|
2142
2137
|
divider$1.setTokens([" + "]);
|
|
2143
2138
|
const sequenceLiteral = new Repeat("sequence-literal", pattern$1, { divider: divider$1, min: 2, trimDivider: true });
|
|
2144
2139
|
|
|
@@ -2880,7 +2875,7 @@
|
|
|
2880
2875
|
}
|
|
2881
2876
|
|
|
2882
2877
|
let indexId$1 = 0;
|
|
2883
|
-
class
|
|
2878
|
+
class Expression {
|
|
2884
2879
|
get id() {
|
|
2885
2880
|
return this._id;
|
|
2886
2881
|
}
|
|
@@ -2922,7 +2917,7 @@
|
|
|
2922
2917
|
this._type = "expression";
|
|
2923
2918
|
this._name = name;
|
|
2924
2919
|
this._parent = null;
|
|
2925
|
-
this._firstIndex =
|
|
2920
|
+
this._firstIndex = 0;
|
|
2926
2921
|
this._atomPatterns = [];
|
|
2927
2922
|
this._prefixPatterns = [];
|
|
2928
2923
|
this._prefixNames = [];
|
|
@@ -2967,10 +2962,10 @@
|
|
|
2967
2962
|
}
|
|
2968
2963
|
else if (this._isBinary(pattern)) {
|
|
2969
2964
|
const name = this._extractName(pattern);
|
|
2970
|
-
const
|
|
2971
|
-
|
|
2965
|
+
const binary = this._extractBinary(pattern);
|
|
2966
|
+
binary.parent = this;
|
|
2972
2967
|
this._precedenceMap[name] = this._binaryPatterns.length;
|
|
2973
|
-
this._binaryPatterns.push(
|
|
2968
|
+
this._binaryPatterns.push(binary);
|
|
2974
2969
|
this._binaryNames.push(name);
|
|
2975
2970
|
if (pattern.type === "right-associated") {
|
|
2976
2971
|
this._associationMap[name] = Association.right;
|
|
@@ -2978,7 +2973,7 @@
|
|
|
2978
2973
|
else {
|
|
2979
2974
|
this._associationMap[name] = Association.left;
|
|
2980
2975
|
}
|
|
2981
|
-
finalPatterns.push(
|
|
2976
|
+
finalPatterns.push(binary);
|
|
2982
2977
|
}
|
|
2983
2978
|
});
|
|
2984
2979
|
return finalPatterns;
|
|
@@ -3219,7 +3214,9 @@
|
|
|
3219
3214
|
return execPattern(this, text, record);
|
|
3220
3215
|
}
|
|
3221
3216
|
getTokens() {
|
|
3222
|
-
|
|
3217
|
+
const atomTokens = this._atomPatterns.map(p => p.getTokens()).flat();
|
|
3218
|
+
const prefixTokens = this.prefixPatterns.map(p => p.getTokens()).flat();
|
|
3219
|
+
return [...prefixTokens, ...atomTokens];
|
|
3223
3220
|
}
|
|
3224
3221
|
getTokensAfter(childReference) {
|
|
3225
3222
|
if (this._prefixPatterns.includes(childReference) || this._binaryPatterns.includes(childReference)) {
|
|
@@ -3248,7 +3245,9 @@
|
|
|
3248
3245
|
return this._parent.getTokensAfter(this);
|
|
3249
3246
|
}
|
|
3250
3247
|
getPatterns() {
|
|
3251
|
-
|
|
3248
|
+
const atomPatterns = this._atomPatterns.map(p => p.getPatterns()).flat();
|
|
3249
|
+
const prefixPatterns = this.prefixPatterns.map(p => p.getPatterns()).flat();
|
|
3250
|
+
return [...prefixPatterns, ...atomPatterns];
|
|
3252
3251
|
}
|
|
3253
3252
|
getPatternsAfter(childReference) {
|
|
3254
3253
|
if (this._prefixPatterns.includes(childReference) || this._binaryPatterns.includes(childReference)) {
|
|
@@ -3280,7 +3279,7 @@
|
|
|
3280
3279
|
return findPattern(this, predicate);
|
|
3281
3280
|
}
|
|
3282
3281
|
clone(name = this._name) {
|
|
3283
|
-
const clone = new
|
|
3282
|
+
const clone = new Expression(name, this._originalPatterns);
|
|
3284
3283
|
clone._id = this._id;
|
|
3285
3284
|
return clone;
|
|
3286
3285
|
}
|
|
@@ -3290,7 +3289,7 @@
|
|
|
3290
3289
|
}
|
|
3291
3290
|
|
|
3292
3291
|
let indexId = 0;
|
|
3293
|
-
class
|
|
3292
|
+
class RightAssociated {
|
|
3294
3293
|
get id() {
|
|
3295
3294
|
return this._id;
|
|
3296
3295
|
}
|
|
@@ -3329,7 +3328,7 @@
|
|
|
3329
3328
|
return this.children[0].test(text, record);
|
|
3330
3329
|
}
|
|
3331
3330
|
clone(_name) {
|
|
3332
|
-
const clone = new
|
|
3331
|
+
const clone = new RightAssociated(this.children[0]);
|
|
3333
3332
|
clone._id = this._id;
|
|
3334
3333
|
return clone;
|
|
3335
3334
|
}
|
|
@@ -3422,14 +3421,6 @@
|
|
|
3422
3421
|
return this._buildPatternRecord();
|
|
3423
3422
|
});
|
|
3424
3423
|
}
|
|
3425
|
-
_buildPatternRecord() {
|
|
3426
|
-
const patterns = {};
|
|
3427
|
-
const allPatterns = Array.from(this._parseContext.patternsByName.values());
|
|
3428
|
-
allPatterns.forEach(p => {
|
|
3429
|
-
patterns[p.name] = new Context(p.name, p, allPatterns.filter(o => o !== p));
|
|
3430
|
-
});
|
|
3431
|
-
return patterns;
|
|
3432
|
-
}
|
|
3433
3424
|
parseString(expression) {
|
|
3434
3425
|
this._parseContext = new ParseContext(this._params);
|
|
3435
3426
|
const ast = this._tryToParse(expression);
|
|
@@ -3439,6 +3430,14 @@
|
|
|
3439
3430
|
this._buildPatterns(ast);
|
|
3440
3431
|
return this._buildPatternRecord();
|
|
3441
3432
|
}
|
|
3433
|
+
_buildPatternRecord() {
|
|
3434
|
+
const patterns = {};
|
|
3435
|
+
const allPatterns = Array.from(this._parseContext.patternsByName.values());
|
|
3436
|
+
allPatterns.forEach(p => {
|
|
3437
|
+
patterns[p.name] = new Context(p.name, p, allPatterns.filter(o => o !== p));
|
|
3438
|
+
});
|
|
3439
|
+
return patterns;
|
|
3440
|
+
}
|
|
3442
3441
|
_tryToParse(expression) {
|
|
3443
3442
|
const { ast, cursor, options, isComplete } = this._autoComplete.suggestFor(expression);
|
|
3444
3443
|
if (!isComplete) {
|
|
@@ -3555,7 +3554,7 @@
|
|
|
3555
3554
|
const patterns = patternNodes.map(n => {
|
|
3556
3555
|
const rightAssociated = n.find(n => n.name === "right-associated");
|
|
3557
3556
|
if (rightAssociated != null) {
|
|
3558
|
-
return new
|
|
3557
|
+
return new RightAssociated(this._buildPattern(n.children[0]));
|
|
3559
3558
|
}
|
|
3560
3559
|
else {
|
|
3561
3560
|
return this._buildPattern(n.children[0]);
|
|
@@ -3564,13 +3563,13 @@
|
|
|
3564
3563
|
const hasRecursivePattern = patterns.some(p => this._isRecursive(name, p));
|
|
3565
3564
|
if (hasRecursivePattern && !isGreedy) {
|
|
3566
3565
|
try {
|
|
3567
|
-
const expression = new
|
|
3566
|
+
const expression = new Expression(name, patterns);
|
|
3568
3567
|
return expression;
|
|
3569
3568
|
}
|
|
3570
3569
|
catch (_a) { }
|
|
3571
3570
|
}
|
|
3572
|
-
const
|
|
3573
|
-
return
|
|
3571
|
+
const options = new Options(name, patterns, isGreedy);
|
|
3572
|
+
return options;
|
|
3574
3573
|
}
|
|
3575
3574
|
_isRecursive(name, pattern) {
|
|
3576
3575
|
if (pattern.type === "right-associated" && this._isRecursivePattern(name, pattern.children[0])) {
|
|
@@ -3625,7 +3624,7 @@
|
|
|
3625
3624
|
this._parseContext.patternsByName.set(name, sequence);
|
|
3626
3625
|
}
|
|
3627
3626
|
_buildSequence(name, node) {
|
|
3628
|
-
const patternNodes = node.children.filter(n => n.name !== "
|
|
3627
|
+
const patternNodes = node.children.filter(n => n.name !== "sequence-divider");
|
|
3629
3628
|
const patterns = patternNodes.map(n => {
|
|
3630
3629
|
const patternNode = n.children[0].name === "not" ? n.children[1] : n.children[0];
|
|
3631
3630
|
const isNot = n.find(n => n.name === "not") != null;
|
|
@@ -3834,7 +3833,7 @@
|
|
|
3834
3833
|
exports.Context = Context;
|
|
3835
3834
|
exports.Cursor = Cursor;
|
|
3836
3835
|
exports.CursorHistory = CursorHistory;
|
|
3837
|
-
exports.
|
|
3836
|
+
exports.Expression = Expression;
|
|
3838
3837
|
exports.Grammar = Grammar;
|
|
3839
3838
|
exports.Literal = Literal;
|
|
3840
3839
|
exports.Node = Node;
|
|
@@ -3845,6 +3844,7 @@
|
|
|
3845
3844
|
exports.Reference = Reference;
|
|
3846
3845
|
exports.Regex = Regex;
|
|
3847
3846
|
exports.Repeat = Repeat;
|
|
3847
|
+
exports.RightAssociated = RightAssociated;
|
|
3848
3848
|
exports.Sequence = Sequence;
|
|
3849
3849
|
exports.compact = compact;
|
|
3850
3850
|
exports.grammar = grammar;
|