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.
- package/dist/index.browser.js +41 -44
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +41 -44
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +41 -44
- package/dist/index.js.map +1 -1
- package/dist/patterns/DepthCache.d.ts +6 -0
- package/dist/patterns/Options.d.ts +0 -1
- package/dist/patterns/Sequence.d.ts +0 -1
- package/package.json +1 -1
- package/src/patterns/DepthCache.ts +26 -0
- package/src/patterns/Options.ts +14 -29
- package/src/patterns/Sequence.ts +10 -32
|
@@ -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[];
|
package/package.json
CHANGED
|
@@ -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
|
+
}
|
package/src/patterns/Options.ts
CHANGED
|
@@ -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.
|
|
104
|
-
cursor.recordErrorAt(
|
|
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
|
|
package/src/patterns/Sequence.ts
CHANGED
|
@@ -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.
|
|
90
|
+
depthCache.incrementDepth(this._id, this._firstIndex);
|
|
88
91
|
|
|
89
|
-
|
|
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
|
|