clarity-pattern-parser 10.0.6 → 10.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.
@@ -0,0 +1,6 @@
1
+ export declare class DepthCache {
2
+ private _depthMap;
3
+ getDepth(name: string, cursorIndex: number): number;
4
+ incrementDepth(name: string, cursorIndex: number): void;
5
+ decrementDepth(name: string, cursorIndex: number): void;
6
+ }
@@ -22,7 +22,6 @@ export declare class Options implements Pattern {
22
22
  exec(text: string, record?: boolean): ParseResult;
23
23
  parse(cursor: Cursor): Node | null;
24
24
  private _tryToParse;
25
- private _isBeyondRecursiveLimit;
26
25
  getTokens(): string[];
27
26
  getTokensAfter(_childReference: Pattern): string[];
28
27
  getNextTokens(): string[];
@@ -24,7 +24,6 @@ export declare class Sequence implements Pattern {
24
24
  };
25
25
  parse(cursor: Cursor): Node | null;
26
26
  private tryToParse;
27
- private _isBeyondRecursiveLimit;
28
27
  private getLastValidNode;
29
28
  private areRemainingPatternsOptional;
30
29
  private createNode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clarity-pattern-parser",
3
- "version": "10.0.6",
3
+ "version": "10.0.7",
4
4
  "description": "Parsing Library for Typescript and Javascript.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.esm.js",
@@ -0,0 +1,26 @@
1
+ export class DepthCache {
2
+ private _depthMap: Record<string, Record<number, number>> = {};
3
+
4
+ getDepth(name: string, cursorIndex: number) {
5
+ if (this._depthMap[name] == null) {
6
+ this._depthMap[name] = {};
7
+ }
8
+
9
+ if (this._depthMap[name][cursorIndex] == null) {
10
+ this._depthMap[name][cursorIndex] = 0;
11
+ }
12
+
13
+
14
+ return this._depthMap[name][cursorIndex];
15
+ }
16
+
17
+ incrementDepth(name: string, cursorIndex: number) {
18
+ const depth = this.getDepth(name, cursorIndex);
19
+ this._depthMap[name][cursorIndex] = depth + 1;
20
+ }
21
+
22
+ decrementDepth(name: string, cursorIndex: number) {
23
+ const depth = this.getDepth(name, cursorIndex);
24
+ this._depthMap[name][cursorIndex] = depth - 1;
25
+ }
26
+ }
@@ -4,7 +4,13 @@ import { Pattern } from "./Pattern";
4
4
  import { clonePatterns } from "./clonePatterns";
5
5
  import { findPattern } from "./findPattern";
6
6
  import { ParseResult } from "./ParseResult";
7
+ import { DepthCache } from './DepthCache';
7
8
 
9
+ /*
10
+ The following is created to reduce the overhead of recursion check.
11
+ */
12
+
13
+ const depthCache = new DepthCache();
8
14
  let idIndex = 0;
9
15
 
10
16
  export class Options implements Pattern {
@@ -83,13 +89,18 @@ export class Options implements Pattern {
83
89
  }
84
90
 
85
91
  parse(cursor: Cursor): Node | null {
92
+ // This is a cache to help with speed
93
+ this._firstIndex = cursor.index;
94
+ depthCache.incrementDepth(this._id, this._firstIndex);
95
+
86
96
  this._firstIndex = cursor.index;
87
97
  const node = this._tryToParse(cursor);
88
98
 
99
+ depthCache.decrementDepth(this._id, this._firstIndex);
100
+
89
101
  if (node != null) {
90
102
  cursor.moveTo(node.lastIndex);
91
103
  cursor.resolveError();
92
-
93
104
  return node;
94
105
  }
95
106
 
@@ -100,8 +111,8 @@ export class Options implements Pattern {
100
111
 
101
112
 
102
113
  private _tryToParse(cursor: Cursor): Node | null {
103
- if (this._isBeyondRecursiveLimit()){
104
- cursor.recordErrorAt(cursor.index, cursor.index, this);
114
+ if (depthCache.getDepth(this._id, this._firstIndex) > 2) {
115
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
105
116
  return null;
106
117
  }
107
118
 
@@ -130,32 +141,6 @@ export class Options implements Pattern {
130
141
  return nonNullResults[0] || null;
131
142
  }
132
143
 
133
- private _isBeyondRecursiveLimit(){
134
- let pattern: Pattern = this;
135
- const matches: Pattern[] = [];
136
-
137
- while(pattern.parent != null){
138
- if (pattern.type !== "options"){
139
- pattern = pattern.parent;
140
- continue;
141
- }
142
-
143
- const optionsPattern = pattern as Options;
144
-
145
- if (pattern.id === this.id && optionsPattern._firstIndex === this._firstIndex){
146
- matches.push(pattern);
147
-
148
- if (matches.length > 2){
149
- return true;
150
- }
151
- }
152
-
153
- pattern = pattern.parent;
154
- }
155
-
156
- return false;
157
- }
158
-
159
144
  getTokens(): string[] {
160
145
  const tokens: string[] = [];
161
146
 
@@ -4,7 +4,9 @@ import { Node } from "../ast/Node";
4
4
  import { clonePatterns } from "./clonePatterns";
5
5
  import { filterOutNull } from "./filterOutNull";
6
6
  import { findPattern } from "./findPattern";
7
+ import { DepthCache } from "./DepthCache";
7
8
 
9
+ const depthCache = new DepthCache();
8
10
  let idIndex = 0;
9
11
 
10
12
  export class Sequence implements Pattern {
@@ -83,15 +85,14 @@ export class Sequence implements Pattern {
83
85
  }
84
86
 
85
87
  parse(cursor: Cursor): Node | null {
88
+ // This is a cache to help with speed
86
89
  this._firstIndex = cursor.index;
87
- this._nodes = [];
90
+ depthCache.incrementDepth(this._id, this._firstIndex);
88
91
 
89
- if (this._isBeyondRecursiveLimit()) {
90
- cursor.recordErrorAt(cursor.index, cursor.index, this);
91
- return null;
92
- }
92
+ this._nodes = [];
93
93
 
94
94
  const passed = this.tryToParse(cursor);
95
+ depthCache.decrementDepth(this._id, this._firstIndex);
95
96
 
96
97
  if (passed) {
97
98
  const node = this.createNode(cursor);
@@ -107,7 +108,10 @@ export class Sequence implements Pattern {
107
108
  }
108
109
 
109
110
  private tryToParse(cursor: Cursor): boolean {
110
-
111
+ if (depthCache.getDepth(this._id, this._firstIndex) > 1) {
112
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
113
+ return false;
114
+ }
111
115
 
112
116
  let passed = false;
113
117
 
@@ -169,32 +173,6 @@ export class Sequence implements Pattern {
169
173
  return passed;
170
174
  }
171
175
 
172
- private _isBeyondRecursiveLimit() {
173
- let pattern: Pattern = this;
174
- const matches: Pattern[] = [];
175
-
176
- while (pattern.parent != null) {
177
- if (pattern.type !== "sequence") {
178
- pattern = pattern.parent;
179
- continue;
180
- }
181
-
182
- const sequencePattern = pattern as Sequence;
183
-
184
- if (pattern.id === this.id && sequencePattern._firstIndex === this._firstIndex) {
185
- matches.push(pattern);
186
-
187
- if (matches.length > 1) {
188
- return true;
189
- }
190
- }
191
-
192
- pattern = pattern.parent;
193
- }
194
-
195
- return false;
196
- }
197
-
198
176
  private getLastValidNode(): Node | null {
199
177
  const nodes = filterOutNull(this._nodes);
200
178