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 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) {
@@ -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(startIndex);
1234
- cursor.recordErrorAt(startIndex, lastIndex, this);
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(startIndex);
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 = -1;
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 && !this._divider && this._parent) {
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("and-patterns", [patternName$1, anonymousPattern]);
2136
- const pattern$1 = new Sequence("and-child-pattern", [
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("and-divider", "\\s*[+]\\s*");
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 ExpressionPattern {
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 = -1;
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 clone = this._extractBinary(pattern);
2971
- clone.parent = this;
2965
+ const binary = this._extractBinary(pattern);
2966
+ binary.parent = this;
2972
2967
  this._precedenceMap[name] = this._binaryPatterns.length;
2973
- this._binaryPatterns.push(clone);
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(clone);
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
- return this.atomPatterns.map(p => p.getTokens()).flat();
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
- return this.atomPatterns.map(p => p.getPatterns()).flat();
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 ExpressionPattern(name, this._originalPatterns);
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 RightAssociatedPattern {
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 RightAssociatedPattern(this.children[0]);
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 RightAssociatedPattern(this._buildPattern(n.children[0]));
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 ExpressionPattern(name, patterns);
3566
+ const expression = new Expression(name, patterns);
3568
3567
  return expression;
3569
3568
  }
3570
3569
  catch (_a) { }
3571
3570
  }
3572
- const or = new Options(name, patterns, isGreedy);
3573
- return or;
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 !== "and-divider");
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.ExpressionPattern = ExpressionPattern;
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;