clarity-pattern-parser 11.0.6 → 11.0.8

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 CHANGED
@@ -1,8 +1,4 @@
1
- * Add a Context Pattern
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
@@ -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
- reduce(): void;
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;
@@ -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
- reduce() {
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, endIndex, pattern) {
401
- const error = new ParseError(startIndex, endIndex, pattern);
396
+ recordErrorAt(startIndex, lastIndex, pattern) {
397
+ const error = new ParseError(startIndex, lastIndex, pattern);
402
398
  this._currentError = error;
403
- if (this._furthestError === null || endIndex > this._furthestError.lastIndex) {
399
+ if (this._furthestError === null || lastIndex > this._furthestError.lastIndex) {
404
400
  this._furthestError = error;
405
401
  }
406
402
  if (this._isRecording) {
@@ -854,6 +850,8 @@
854
850
  this._cachedPattern = null;
855
851
  this._children = [];
856
852
  this._firstIndex = 0;
853
+ this._cachedAncestors = false;
854
+ this._recursiveAncestors = [];
857
855
  }
858
856
  test(text, record = false) {
859
857
  return testPattern(this, text, record);
@@ -863,8 +861,36 @@
863
861
  }
864
862
  parse(cursor) {
865
863
  this._firstIndex = cursor.index;
864
+ this._cacheAncestors();
865
+ if (this._isBeyondRecursiveAllowance()) {
866
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
867
+ return null;
868
+ }
866
869
  return this.getReferencePatternSafely().parse(cursor);
867
870
  }
871
+ _cacheAncestors() {
872
+ if (!this._cachedAncestors) {
873
+ let pattern = this.parent;
874
+ while (pattern != null) {
875
+ if (pattern.type === this.type && pattern.id === this._id) {
876
+ this._recursiveAncestors.push(pattern);
877
+ }
878
+ pattern = pattern.parent;
879
+ }
880
+ }
881
+ }
882
+ _isBeyondRecursiveAllowance() {
883
+ let depth = 0;
884
+ for (let pattern of this._recursiveAncestors) {
885
+ if (pattern._firstIndex === this._firstIndex) {
886
+ depth++;
887
+ if (depth > 2) {
888
+ return true;
889
+ }
890
+ }
891
+ }
892
+ return false;
893
+ }
868
894
  getReferencePatternSafely() {
869
895
  if (this._pattern === null) {
870
896
  let pattern = null;
@@ -1050,9 +1076,6 @@
1050
1076
  return null;
1051
1077
  }
1052
1078
  _tryToParse(cursor) {
1053
- if (this._isBeyondRecursiveAllowance()) {
1054
- return null;
1055
- }
1056
1079
  const results = [];
1057
1080
  for (const pattern of this._children) {
1058
1081
  cursor.moveTo(this._firstIndex);
@@ -1070,20 +1093,6 @@
1070
1093
  nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
1071
1094
  return nonNullResults[0] || null;
1072
1095
  }
1073
- _isBeyondRecursiveAllowance() {
1074
- let depth = 0;
1075
- let pattern = this;
1076
- while (pattern != null) {
1077
- if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
1078
- depth++;
1079
- }
1080
- if (depth > 2) {
1081
- return true;
1082
- }
1083
- pattern = pattern.parent;
1084
- }
1085
- return false;
1086
- }
1087
1096
  getTokens() {
1088
1097
  const tokens = [];
1089
1098
  for (const pattern of this._children) {
@@ -1194,7 +1203,6 @@
1194
1203
  }
1195
1204
  parse(cursor) {
1196
1205
  this._firstIndex = cursor.index;
1197
- const startIndex = cursor.index;
1198
1206
  const nodes = [];
1199
1207
  const modulo = this._hasDivider ? 2 : 1;
1200
1208
  let matchCount = 0;
@@ -1230,12 +1238,12 @@
1230
1238
  }
1231
1239
  if (matchCount < this._min) {
1232
1240
  const lastIndex = cursor.index;
1233
- cursor.moveTo(startIndex);
1234
- cursor.recordErrorAt(startIndex, lastIndex, this);
1241
+ cursor.moveTo(this._firstIndex);
1242
+ cursor.recordErrorAt(this._firstIndex, lastIndex, this);
1235
1243
  return null;
1236
1244
  }
1237
1245
  if (nodes.length === 0 && !cursor.hasError) {
1238
- cursor.moveTo(startIndex);
1246
+ cursor.moveTo(this._firstIndex);
1239
1247
  return null;
1240
1248
  }
1241
1249
  const firstIndex = nodes[0].firstIndex;
@@ -1359,7 +1367,7 @@
1359
1367
  this._children = children;
1360
1368
  this._pattern = children[0];
1361
1369
  this._divider = children[1];
1362
- this._firstIndex = -1;
1370
+ this._firstIndex = 0;
1363
1371
  this._nodes = [];
1364
1372
  this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
1365
1373
  }
@@ -1539,7 +1547,7 @@
1539
1547
  patterns.push(this._children[0]);
1540
1548
  }
1541
1549
  // If there is no divider then suggest the repeating pattern and the next pattern after.
1542
- if (index === 0 && !this._divider && this._parent) {
1550
+ if (index === 0 && this._divider == null && this._parent) {
1543
1551
  patterns.push(this._children[0]);
1544
1552
  patterns.push(...this._parent.getPatternsAfter(this));
1545
1553
  }
@@ -1740,10 +1748,6 @@
1740
1748
  return null;
1741
1749
  }
1742
1750
  tryToParse(cursor) {
1743
- if (this._isBeyondRecursiveAllowance()) {
1744
- cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
1745
- return false;
1746
- }
1747
1751
  let passed = false;
1748
1752
  for (let i = 0; i < this._children.length; i++) {
1749
1753
  const runningCursorIndex = cursor.index;
@@ -1807,20 +1811,6 @@
1807
1811
  }
1808
1812
  return nodes[nodes.length - 1];
1809
1813
  }
1810
- _isBeyondRecursiveAllowance() {
1811
- let depth = 0;
1812
- let pattern = this;
1813
- while (pattern != null) {
1814
- if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
1815
- depth++;
1816
- }
1817
- if (depth > 1) {
1818
- return true;
1819
- }
1820
- pattern = pattern.parent;
1821
- }
1822
- return false;
1823
- }
1824
1814
  areRemainingPatternsOptional(fromIndex) {
1825
1815
  const startOnIndex = fromIndex + 1;
1826
1816
  const length = this._children.length;
@@ -2132,13 +2122,13 @@
2132
2122
  const optionalNot = new Optional("optional-not", new Literal("not", "!"));
2133
2123
  const optionalIsOptional$1 = new Optional("optional-is-optional", new Literal("is-optional", "?"));
2134
2124
  const patternName$1 = name$1.clone("pattern-name");
2135
- const patterns$2 = new Options("and-patterns", [patternName$1, anonymousPattern]);
2136
- const pattern$1 = new Sequence("and-child-pattern", [
2125
+ const patterns$2 = new Options("sequence-patterns", [patternName$1, anonymousPattern]);
2126
+ const pattern$1 = new Sequence("sequence-child-pattern", [
2137
2127
  optionalNot,
2138
2128
  patterns$2,
2139
2129
  optionalIsOptional$1,
2140
2130
  ]);
2141
- const divider$1 = new Regex("and-divider", "\\s*[+]\\s*");
2131
+ const divider$1 = new Regex("sequence-divider", "\\s*[+]\\s*");
2142
2132
  divider$1.setTokens([" + "]);
2143
2133
  const sequenceLiteral = new Repeat("sequence-literal", pattern$1, { divider: divider$1, min: 2, trimDivider: true });
2144
2134
 
@@ -2880,7 +2870,7 @@
2880
2870
  }
2881
2871
 
2882
2872
  let indexId$1 = 0;
2883
- class ExpressionPattern {
2873
+ class Expression {
2884
2874
  get id() {
2885
2875
  return this._id;
2886
2876
  }
@@ -2922,7 +2912,7 @@
2922
2912
  this._type = "expression";
2923
2913
  this._name = name;
2924
2914
  this._parent = null;
2925
- this._firstIndex = -1;
2915
+ this._firstIndex = 0;
2926
2916
  this._atomPatterns = [];
2927
2917
  this._prefixPatterns = [];
2928
2918
  this._prefixNames = [];
@@ -2967,10 +2957,10 @@
2967
2957
  }
2968
2958
  else if (this._isBinary(pattern)) {
2969
2959
  const name = this._extractName(pattern);
2970
- const clone = this._extractBinary(pattern);
2971
- clone.parent = this;
2960
+ const binary = this._extractBinary(pattern);
2961
+ binary.parent = this;
2972
2962
  this._precedenceMap[name] = this._binaryPatterns.length;
2973
- this._binaryPatterns.push(clone);
2963
+ this._binaryPatterns.push(binary);
2974
2964
  this._binaryNames.push(name);
2975
2965
  if (pattern.type === "right-associated") {
2976
2966
  this._associationMap[name] = Association.right;
@@ -2978,7 +2968,7 @@
2978
2968
  else {
2979
2969
  this._associationMap[name] = Association.left;
2980
2970
  }
2981
- finalPatterns.push(clone);
2971
+ finalPatterns.push(binary);
2982
2972
  }
2983
2973
  });
2984
2974
  return finalPatterns;
@@ -3064,10 +3054,6 @@
3064
3054
  return null;
3065
3055
  }
3066
3056
  _tryToParse(cursor) {
3067
- if (this._isBeyondRecursiveAllowance()) {
3068
- cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
3069
- return null;
3070
- }
3071
3057
  this._shouldStopParsing = false;
3072
3058
  while (true) {
3073
3059
  cursor.resolveError();
@@ -3198,20 +3184,6 @@
3198
3184
  this._shouldStopParsing = true;
3199
3185
  }
3200
3186
  }
3201
- _isBeyondRecursiveAllowance() {
3202
- let depth = 0;
3203
- let pattern = this;
3204
- while (pattern != null) {
3205
- if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
3206
- depth++;
3207
- }
3208
- if (depth > 2) {
3209
- return true;
3210
- }
3211
- pattern = pattern.parent;
3212
- }
3213
- return false;
3214
- }
3215
3187
  test(text, record = false) {
3216
3188
  return testPattern(this, text, record);
3217
3189
  }
@@ -3219,7 +3191,9 @@
3219
3191
  return execPattern(this, text, record);
3220
3192
  }
3221
3193
  getTokens() {
3222
- return this.atomPatterns.map(p => p.getTokens()).flat();
3194
+ const atomTokens = this._atomPatterns.map(p => p.getTokens()).flat();
3195
+ const prefixTokens = this.prefixPatterns.map(p => p.getTokens()).flat();
3196
+ return [...prefixTokens, ...atomTokens];
3223
3197
  }
3224
3198
  getTokensAfter(childReference) {
3225
3199
  if (this._prefixPatterns.includes(childReference) || this._binaryPatterns.includes(childReference)) {
@@ -3248,7 +3222,9 @@
3248
3222
  return this._parent.getTokensAfter(this);
3249
3223
  }
3250
3224
  getPatterns() {
3251
- return this.atomPatterns.map(p => p.getPatterns()).flat();
3225
+ const atomPatterns = this._atomPatterns.map(p => p.getPatterns()).flat();
3226
+ const prefixPatterns = this.prefixPatterns.map(p => p.getPatterns()).flat();
3227
+ return [...prefixPatterns, ...atomPatterns];
3252
3228
  }
3253
3229
  getPatternsAfter(childReference) {
3254
3230
  if (this._prefixPatterns.includes(childReference) || this._binaryPatterns.includes(childReference)) {
@@ -3280,7 +3256,7 @@
3280
3256
  return findPattern(this, predicate);
3281
3257
  }
3282
3258
  clone(name = this._name) {
3283
- const clone = new ExpressionPattern(name, this._originalPatterns);
3259
+ const clone = new Expression(name, this._originalPatterns);
3284
3260
  clone._id = this._id;
3285
3261
  return clone;
3286
3262
  }
@@ -3290,7 +3266,7 @@
3290
3266
  }
3291
3267
 
3292
3268
  let indexId = 0;
3293
- class RightAssociatedPattern {
3269
+ class RightAssociated {
3294
3270
  get id() {
3295
3271
  return this._id;
3296
3272
  }
@@ -3329,7 +3305,7 @@
3329
3305
  return this.children[0].test(text, record);
3330
3306
  }
3331
3307
  clone(_name) {
3332
- const clone = new RightAssociatedPattern(this.children[0]);
3308
+ const clone = new RightAssociated(this.children[0]);
3333
3309
  clone._id = this._id;
3334
3310
  return clone;
3335
3311
  }
@@ -3422,14 +3398,6 @@
3422
3398
  return this._buildPatternRecord();
3423
3399
  });
3424
3400
  }
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
3401
  parseString(expression) {
3434
3402
  this._parseContext = new ParseContext(this._params);
3435
3403
  const ast = this._tryToParse(expression);
@@ -3439,6 +3407,14 @@
3439
3407
  this._buildPatterns(ast);
3440
3408
  return this._buildPatternRecord();
3441
3409
  }
3410
+ _buildPatternRecord() {
3411
+ const patterns = {};
3412
+ const allPatterns = Array.from(this._parseContext.patternsByName.values());
3413
+ allPatterns.forEach(p => {
3414
+ patterns[p.name] = new Context(p.name, p, allPatterns.filter(o => o !== p));
3415
+ });
3416
+ return patterns;
3417
+ }
3442
3418
  _tryToParse(expression) {
3443
3419
  const { ast, cursor, options, isComplete } = this._autoComplete.suggestFor(expression);
3444
3420
  if (!isComplete) {
@@ -3555,7 +3531,7 @@
3555
3531
  const patterns = patternNodes.map(n => {
3556
3532
  const rightAssociated = n.find(n => n.name === "right-associated");
3557
3533
  if (rightAssociated != null) {
3558
- return new RightAssociatedPattern(this._buildPattern(n.children[0]));
3534
+ return new RightAssociated(this._buildPattern(n.children[0]));
3559
3535
  }
3560
3536
  else {
3561
3537
  return this._buildPattern(n.children[0]);
@@ -3564,13 +3540,13 @@
3564
3540
  const hasRecursivePattern = patterns.some(p => this._isRecursive(name, p));
3565
3541
  if (hasRecursivePattern && !isGreedy) {
3566
3542
  try {
3567
- const expression = new ExpressionPattern(name, patterns);
3543
+ const expression = new Expression(name, patterns);
3568
3544
  return expression;
3569
3545
  }
3570
3546
  catch (_a) { }
3571
3547
  }
3572
- const or = new Options(name, patterns, isGreedy);
3573
- return or;
3548
+ const options = new Options(name, patterns, isGreedy);
3549
+ return options;
3574
3550
  }
3575
3551
  _isRecursive(name, pattern) {
3576
3552
  if (pattern.type === "right-associated" && this._isRecursivePattern(name, pattern.children[0])) {
@@ -3625,7 +3601,7 @@
3625
3601
  this._parseContext.patternsByName.set(name, sequence);
3626
3602
  }
3627
3603
  _buildSequence(name, node) {
3628
- const patternNodes = node.children.filter(n => n.name !== "and-divider");
3604
+ const patternNodes = node.children.filter(n => n.name !== "sequence-divider");
3629
3605
  const patterns = patternNodes.map(n => {
3630
3606
  const patternNode = n.children[0].name === "not" ? n.children[1] : n.children[0];
3631
3607
  const isNot = n.find(n => n.name === "not") != null;
@@ -3834,7 +3810,7 @@
3834
3810
  exports.Context = Context;
3835
3811
  exports.Cursor = Cursor;
3836
3812
  exports.CursorHistory = CursorHistory;
3837
- exports.ExpressionPattern = ExpressionPattern;
3813
+ exports.Expression = Expression;
3838
3814
  exports.Grammar = Grammar;
3839
3815
  exports.Literal = Literal;
3840
3816
  exports.Node = Node;
@@ -3845,6 +3821,7 @@
3845
3821
  exports.Reference = Reference;
3846
3822
  exports.Regex = Regex;
3847
3823
  exports.Repeat = Repeat;
3824
+ exports.RightAssociated = RightAssociated;
3848
3825
  exports.Sequence = Sequence;
3849
3826
  exports.compact = compact;
3850
3827
  exports.grammar = grammar;