clarity-pattern-parser 10.3.1 → 10.3.3
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 +182 -80
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +182 -80
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +182 -80
- package/dist/index.js.map +1 -1
- package/dist/patterns/Context.d.ts +1 -0
- package/dist/patterns/ExpressionPattern.d.ts +8 -1
- package/dist/patterns/FiniteRepeat.d.ts +2 -0
- package/dist/patterns/InfiniteRepeat.d.ts +1 -0
- package/dist/patterns/Literal.d.ts +1 -0
- package/dist/patterns/Not.d.ts +1 -0
- package/dist/patterns/Optional.d.ts +1 -0
- package/dist/patterns/Options.d.ts +2 -0
- package/dist/patterns/Pattern.d.ts +1 -0
- package/dist/patterns/Reference.d.ts +2 -0
- package/dist/patterns/Regex.d.ts +1 -0
- package/dist/patterns/Repeat.d.ts +1 -0
- package/dist/patterns/Sequence.d.ts +2 -0
- package/package.json +1 -1
- package/src/patterns/Context.ts +4 -0
- package/src/patterns/ExpressionPattern.ts +129 -47
- package/src/patterns/FiniteRepeat.ts +8 -0
- package/src/patterns/InfiniteRepeat.ts +4 -0
- package/src/patterns/Literal.ts +4 -0
- package/src/patterns/Not.ts +4 -0
- package/src/patterns/Optional.ts +4 -0
- package/src/patterns/Options.ts +23 -13
- package/src/patterns/Pattern.ts +1 -0
- package/src/patterns/Reference.ts +7 -0
- package/src/patterns/Regex.ts +6 -2
- package/src/patterns/Repeat.ts +4 -0
- package/src/patterns/RightAssociatedPattern.ts +4 -0
- package/src/patterns/Sequence.ts +23 -8
- package/src/patterns/DepthCache.ts +0 -26
package/src/patterns/Options.ts
CHANGED
|
@@ -4,14 +4,8 @@ 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';
|
|
8
7
|
import { isRecursivePattern } from "./isRecursivePattern";
|
|
9
8
|
|
|
10
|
-
/*
|
|
11
|
-
The following is created to reduce the overhead of recursion check.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const depthCache = new DepthCache();
|
|
15
9
|
let idIndex = 0;
|
|
16
10
|
|
|
17
11
|
export class Options implements Pattern {
|
|
@@ -49,6 +43,10 @@ export class Options implements Pattern {
|
|
|
49
43
|
return this._children;
|
|
50
44
|
}
|
|
51
45
|
|
|
46
|
+
get startedOnIndex() {
|
|
47
|
+
return this._firstIndex;
|
|
48
|
+
}
|
|
49
|
+
|
|
52
50
|
constructor(name: string, options: Pattern[], isGreedy = false) {
|
|
53
51
|
if (options.length === 0) {
|
|
54
52
|
throw new Error("Need at least one pattern with an 'options' pattern.");
|
|
@@ -92,15 +90,9 @@ export class Options implements Pattern {
|
|
|
92
90
|
}
|
|
93
91
|
|
|
94
92
|
parse(cursor: Cursor): Node | null {
|
|
95
|
-
// This is a cache to help with speed
|
|
96
|
-
this._firstIndex = cursor.index;
|
|
97
|
-
depthCache.incrementDepth(this._id, this._firstIndex);
|
|
98
|
-
|
|
99
93
|
this._firstIndex = cursor.index;
|
|
100
94
|
const node = this._tryToParse(cursor);
|
|
101
95
|
|
|
102
|
-
depthCache.decrementDepth(this._id, this._firstIndex);
|
|
103
|
-
|
|
104
96
|
if (node != null) {
|
|
105
97
|
cursor.moveTo(node.lastIndex);
|
|
106
98
|
cursor.resolveError();
|
|
@@ -117,7 +109,7 @@ export class Options implements Pattern {
|
|
|
117
109
|
}
|
|
118
110
|
|
|
119
111
|
private _tryToParse(cursor: Cursor): Node | null {
|
|
120
|
-
if (
|
|
112
|
+
if (this._isBeyondRecursiveAllowance()) {
|
|
121
113
|
return null;
|
|
122
114
|
}
|
|
123
115
|
|
|
@@ -146,6 +138,24 @@ export class Options implements Pattern {
|
|
|
146
138
|
return nonNullResults[0] || null;
|
|
147
139
|
}
|
|
148
140
|
|
|
141
|
+
private _isBeyondRecursiveAllowance() {
|
|
142
|
+
let depth = 0;
|
|
143
|
+
let pattern: Pattern | null = this;
|
|
144
|
+
|
|
145
|
+
while (pattern != null) {
|
|
146
|
+
if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
|
|
147
|
+
depth++;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (depth > 2) {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
pattern = pattern.parent;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
|
|
149
159
|
getTokens(): string[] {
|
|
150
160
|
const tokens: string[] = [];
|
|
151
161
|
|
package/src/patterns/Pattern.ts
CHANGED
|
@@ -15,6 +15,7 @@ export class Reference implements Pattern {
|
|
|
15
15
|
private _cachedPattern: Pattern | null;
|
|
16
16
|
private _pattern: Pattern | null;
|
|
17
17
|
private _children: Pattern[];
|
|
18
|
+
private _firstIndex: number;
|
|
18
19
|
|
|
19
20
|
shouldCompactAst = false;
|
|
20
21
|
|
|
@@ -42,6 +43,10 @@ export class Reference implements Pattern {
|
|
|
42
43
|
return this._children;
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
get startedOnIndex() {
|
|
47
|
+
return this._firstIndex;
|
|
48
|
+
}
|
|
49
|
+
|
|
45
50
|
constructor(name: string) {
|
|
46
51
|
this._id = `reference-${idIndex++}`;
|
|
47
52
|
this._type = "reference";
|
|
@@ -50,6 +55,7 @@ export class Reference implements Pattern {
|
|
|
50
55
|
this._pattern = null;
|
|
51
56
|
this._cachedPattern = null;
|
|
52
57
|
this._children = [];
|
|
58
|
+
this._firstIndex = 0;
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
test(text: string) {
|
|
@@ -72,6 +78,7 @@ export class Reference implements Pattern {
|
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
parse(cursor: Cursor): Node | null {
|
|
81
|
+
this._firstIndex = cursor.index;
|
|
75
82
|
return this.getReferencePatternSafely().parse(cursor);
|
|
76
83
|
}
|
|
77
84
|
|
package/src/patterns/Regex.ts
CHANGED
|
@@ -14,7 +14,7 @@ export class Regex implements Pattern {
|
|
|
14
14
|
private _regex: RegExp;
|
|
15
15
|
private _node: Node | null = null;
|
|
16
16
|
private _cursor: Cursor | null = null;
|
|
17
|
-
private _firstIndex =
|
|
17
|
+
private _firstIndex = 0;
|
|
18
18
|
private _substring = "";
|
|
19
19
|
private _tokens: string[] = [];
|
|
20
20
|
|
|
@@ -48,6 +48,10 @@ export class Regex implements Pattern {
|
|
|
48
48
|
return [];
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
get startedOnIndex() {
|
|
52
|
+
return this._firstIndex;
|
|
53
|
+
}
|
|
54
|
+
|
|
51
55
|
constructor(name: string, regex: string) {
|
|
52
56
|
this._id = `regex-${idIndex++}`;
|
|
53
57
|
this._type = "regex";
|
|
@@ -149,7 +153,7 @@ export class Regex implements Pattern {
|
|
|
149
153
|
clone._tokens = this._tokens.slice();
|
|
150
154
|
clone._id = this._id;
|
|
151
155
|
clone.shouldCompactAst = this.shouldCompactAst;
|
|
152
|
-
|
|
156
|
+
|
|
153
157
|
return clone;
|
|
154
158
|
}
|
|
155
159
|
|
package/src/patterns/Repeat.ts
CHANGED
|
@@ -70,6 +70,10 @@ export class Repeat implements Pattern {
|
|
|
70
70
|
return this._options.max;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
get startedOnIndex(){
|
|
74
|
+
return this._repeatPattern.startedOnIndex;
|
|
75
|
+
}
|
|
76
|
+
|
|
73
77
|
constructor(name: string, pattern: Pattern, options: RepeatOptions = {}) {
|
|
74
78
|
this._id = `repeat-${idIndex++}`;
|
|
75
79
|
this._pattern = pattern;
|
|
@@ -38,6 +38,10 @@ export class RightAssociatedPattern implements Pattern {
|
|
|
38
38
|
return this._children;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
get startedOnIndex() {
|
|
42
|
+
return this._children[0].startedOnIndex;
|
|
43
|
+
}
|
|
44
|
+
|
|
41
45
|
constructor(pattern: Pattern) {
|
|
42
46
|
this._id = `right-associated-${indexId++}`;
|
|
43
47
|
this._type = "right-associated";
|
package/src/patterns/Sequence.ts
CHANGED
|
@@ -4,10 +4,8 @@ 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";
|
|
8
7
|
import { isRecursivePattern } from "./isRecursivePattern";
|
|
9
8
|
|
|
10
|
-
const depthCache = new DepthCache();
|
|
11
9
|
let idIndex = 0;
|
|
12
10
|
|
|
13
11
|
export class Sequence implements Pattern {
|
|
@@ -45,6 +43,10 @@ export class Sequence implements Pattern {
|
|
|
45
43
|
return this._children;
|
|
46
44
|
}
|
|
47
45
|
|
|
46
|
+
get startedOnIndex() {
|
|
47
|
+
return this._firstIndex;
|
|
48
|
+
}
|
|
49
|
+
|
|
48
50
|
constructor(name: string, sequence: Pattern[]) {
|
|
49
51
|
if (sequence.length === 0) {
|
|
50
52
|
throw new Error("Need at least one pattern with a 'sequence' pattern.");
|
|
@@ -88,14 +90,9 @@ export class Sequence implements Pattern {
|
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
parse(cursor: Cursor): Node | null {
|
|
91
|
-
// This is a cache to help with speed
|
|
92
93
|
this._firstIndex = cursor.index;
|
|
93
|
-
depthCache.incrementDepth(this._id, this._firstIndex);
|
|
94
|
-
|
|
95
94
|
this._nodes = [];
|
|
96
|
-
|
|
97
95
|
const passed = this.tryToParse(cursor);
|
|
98
|
-
depthCache.decrementDepth(this._id, this._firstIndex);
|
|
99
96
|
|
|
100
97
|
if (passed) {
|
|
101
98
|
const node = this.createNode(cursor);
|
|
@@ -115,7 +112,7 @@ export class Sequence implements Pattern {
|
|
|
115
112
|
}
|
|
116
113
|
|
|
117
114
|
private tryToParse(cursor: Cursor): boolean {
|
|
118
|
-
if (
|
|
115
|
+
if (this._isBeyondRecursiveAllowance()) {
|
|
119
116
|
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
120
117
|
return false;
|
|
121
118
|
}
|
|
@@ -190,6 +187,24 @@ export class Sequence implements Pattern {
|
|
|
190
187
|
return nodes[nodes.length - 1];
|
|
191
188
|
}
|
|
192
189
|
|
|
190
|
+
private _isBeyondRecursiveAllowance() {
|
|
191
|
+
let depth = 0;
|
|
192
|
+
let pattern: Pattern | null = this;
|
|
193
|
+
|
|
194
|
+
while (pattern != null) {
|
|
195
|
+
if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
|
|
196
|
+
depth++;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (depth > 1) {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
pattern = pattern.parent;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
|
|
193
208
|
private areRemainingPatternsOptional(fromIndex: number): boolean {
|
|
194
209
|
const startOnIndex = fromIndex + 1;
|
|
195
210
|
const length = this._children.length;
|
|
@@ -1,26 +0,0 @@
|
|
|
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
|
-
}
|