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
|
@@ -17,6 +17,7 @@ export declare class Context implements Pattern {
|
|
|
17
17
|
get parent(): Pattern | null;
|
|
18
18
|
set parent(pattern: Pattern | null);
|
|
19
19
|
get children(): Pattern[];
|
|
20
|
+
get startedOnIndex(): number;
|
|
20
21
|
getPatternWithinContext(name: string): Pattern | null;
|
|
21
22
|
getPatternsWithinContext(): {
|
|
22
23
|
[x: string]: Pattern;
|
|
@@ -10,7 +10,9 @@ export declare class ExpressionPattern implements Pattern {
|
|
|
10
10
|
private _firstIndex;
|
|
11
11
|
private _originalPatterns;
|
|
12
12
|
private _patterns;
|
|
13
|
-
private
|
|
13
|
+
private _atomPatterns;
|
|
14
|
+
private _unaryPrefixPatterns;
|
|
15
|
+
private _unaryPrefixNames;
|
|
14
16
|
private _binaryPatterns;
|
|
15
17
|
private _recursivePatterns;
|
|
16
18
|
private _recursiveNames;
|
|
@@ -29,12 +31,16 @@ export declare class ExpressionPattern implements Pattern {
|
|
|
29
31
|
get unaryPatterns(): readonly Pattern[];
|
|
30
32
|
get binaryPatterns(): readonly Pattern[];
|
|
31
33
|
get recursivePatterns(): readonly Pattern[];
|
|
34
|
+
get startedOnIndex(): number;
|
|
32
35
|
constructor(name: string, patterns: Pattern[]);
|
|
33
36
|
private _organizePatterns;
|
|
34
37
|
private _isBinary;
|
|
35
38
|
private _isBinaryPattern;
|
|
36
39
|
private _extractDelimiter;
|
|
37
40
|
private _extractName;
|
|
41
|
+
private _isUnary;
|
|
42
|
+
private _isUnaryPattern;
|
|
43
|
+
private _extractUnaryPrefixPattern;
|
|
38
44
|
private _isRecursive;
|
|
39
45
|
private _isRecursivePattern;
|
|
40
46
|
private _extractRecursiveTail;
|
|
@@ -42,6 +48,7 @@ export declare class ExpressionPattern implements Pattern {
|
|
|
42
48
|
parse(cursor: Cursor): Node | null;
|
|
43
49
|
private _compactResult;
|
|
44
50
|
private _tryToParse;
|
|
51
|
+
private _isBeyondRecursiveAllowance;
|
|
45
52
|
test(text: string): boolean;
|
|
46
53
|
exec(text: string, record?: boolean): ParseResult;
|
|
47
54
|
getTokens(): string[];
|
|
@@ -18,6 +18,7 @@ export declare class FiniteRepeat implements Pattern {
|
|
|
18
18
|
private _min;
|
|
19
19
|
private _max;
|
|
20
20
|
private _trimDivider;
|
|
21
|
+
private _firstIndex;
|
|
21
22
|
shouldCompactAst: boolean;
|
|
22
23
|
get id(): string;
|
|
23
24
|
get type(): string;
|
|
@@ -27,6 +28,7 @@ export declare class FiniteRepeat implements Pattern {
|
|
|
27
28
|
get children(): Pattern[];
|
|
28
29
|
get min(): number;
|
|
29
30
|
get max(): number;
|
|
31
|
+
get startedOnIndex(): number;
|
|
30
32
|
constructor(name: string, pattern: Pattern, options?: FiniteRepeatOptions);
|
|
31
33
|
parse(cursor: Cursor): Node | null;
|
|
32
34
|
test(text: string): boolean;
|
|
@@ -27,6 +27,7 @@ export declare class InfiniteRepeat implements Pattern {
|
|
|
27
27
|
set parent(pattern: Pattern | null);
|
|
28
28
|
get children(): Pattern[];
|
|
29
29
|
get min(): number;
|
|
30
|
+
get startedOnIndex(): number;
|
|
30
31
|
constructor(name: string, pattern: Pattern, options?: InfiniteRepeatOptions);
|
|
31
32
|
private _assignChildrenToParent;
|
|
32
33
|
test(text: string): boolean;
|
|
@@ -20,6 +20,7 @@ export declare class Literal implements Pattern {
|
|
|
20
20
|
get parent(): Pattern | null;
|
|
21
21
|
set parent(pattern: Pattern | null);
|
|
22
22
|
get children(): Pattern[];
|
|
23
|
+
get startedOnIndex(): number;
|
|
23
24
|
constructor(name: string, value: string);
|
|
24
25
|
test(text: string, record?: boolean): boolean;
|
|
25
26
|
exec(text: string, record?: boolean): ParseResult;
|
package/dist/patterns/Not.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export declare class Not implements Pattern {
|
|
|
15
15
|
get parent(): Pattern | null;
|
|
16
16
|
set parent(pattern: Pattern | null);
|
|
17
17
|
get children(): Pattern[];
|
|
18
|
+
get startedOnIndex(): number;
|
|
18
19
|
constructor(name: string, pattern: Pattern);
|
|
19
20
|
test(text: string): boolean;
|
|
20
21
|
exec(text: string, record?: boolean): ParseResult;
|
|
@@ -15,6 +15,7 @@ export declare class Optional implements Pattern {
|
|
|
15
15
|
get parent(): Pattern | null;
|
|
16
16
|
set parent(pattern: Pattern | null);
|
|
17
17
|
get children(): Pattern[];
|
|
18
|
+
get startedOnIndex(): number;
|
|
18
19
|
constructor(name: string, pattern: Pattern);
|
|
19
20
|
test(text: string): boolean;
|
|
20
21
|
exec(text: string, record?: boolean): ParseResult;
|
|
@@ -17,12 +17,14 @@ export declare class Options implements Pattern {
|
|
|
17
17
|
get parent(): Pattern | null;
|
|
18
18
|
set parent(pattern: Pattern | null);
|
|
19
19
|
get children(): Pattern[];
|
|
20
|
+
get startedOnIndex(): number;
|
|
20
21
|
constructor(name: string, options: Pattern[], isGreedy?: boolean);
|
|
21
22
|
private _assignChildrenToParent;
|
|
22
23
|
test(text: string): boolean;
|
|
23
24
|
exec(text: string, record?: boolean): ParseResult;
|
|
24
25
|
parse(cursor: Cursor): Node | null;
|
|
25
26
|
private _tryToParse;
|
|
27
|
+
private _isBeyondRecursiveAllowance;
|
|
26
28
|
getTokens(): string[];
|
|
27
29
|
getTokensAfter(_childReference: Pattern): string[];
|
|
28
30
|
getNextTokens(): string[];
|
|
@@ -10,6 +10,7 @@ export declare class Reference implements Pattern {
|
|
|
10
10
|
private _cachedPattern;
|
|
11
11
|
private _pattern;
|
|
12
12
|
private _children;
|
|
13
|
+
private _firstIndex;
|
|
13
14
|
shouldCompactAst: boolean;
|
|
14
15
|
get id(): string;
|
|
15
16
|
get type(): string;
|
|
@@ -17,6 +18,7 @@ export declare class Reference implements Pattern {
|
|
|
17
18
|
get parent(): Pattern | null;
|
|
18
19
|
set parent(pattern: Pattern | null);
|
|
19
20
|
get children(): Pattern[];
|
|
21
|
+
get startedOnIndex(): number;
|
|
20
22
|
constructor(name: string);
|
|
21
23
|
test(text: string): boolean;
|
|
22
24
|
exec(text: string, record?: boolean): ParseResult;
|
package/dist/patterns/Regex.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export declare class Regex implements Pattern {
|
|
|
22
22
|
get parent(): Pattern | null;
|
|
23
23
|
set parent(pattern: Pattern | null);
|
|
24
24
|
get children(): Pattern[];
|
|
25
|
+
get startedOnIndex(): number;
|
|
25
26
|
constructor(name: string, regex: string);
|
|
26
27
|
private assertArguments;
|
|
27
28
|
test(text: string): boolean;
|
|
@@ -26,6 +26,7 @@ export declare class Repeat implements Pattern {
|
|
|
26
26
|
get children(): Pattern[];
|
|
27
27
|
get min(): number;
|
|
28
28
|
get max(): number;
|
|
29
|
+
get startedOnIndex(): number;
|
|
29
30
|
constructor(name: string, pattern: Pattern, options?: RepeatOptions);
|
|
30
31
|
parse(cursor: Cursor): Node | null;
|
|
31
32
|
exec(text: string): ParseResult;
|
|
@@ -16,6 +16,7 @@ export declare class Sequence implements Pattern {
|
|
|
16
16
|
get parent(): Pattern | null;
|
|
17
17
|
set parent(pattern: Pattern | null);
|
|
18
18
|
get children(): Pattern[];
|
|
19
|
+
get startedOnIndex(): number;
|
|
19
20
|
constructor(name: string, sequence: Pattern[]);
|
|
20
21
|
private _assignChildrenToParent;
|
|
21
22
|
test(text: string): boolean;
|
|
@@ -26,6 +27,7 @@ export declare class Sequence implements Pattern {
|
|
|
26
27
|
parse(cursor: Cursor): Node | null;
|
|
27
28
|
private tryToParse;
|
|
28
29
|
private getLastValidNode;
|
|
30
|
+
private _isBeyondRecursiveAllowance;
|
|
29
31
|
private areRemainingPatternsOptional;
|
|
30
32
|
private createNode;
|
|
31
33
|
getTokens(): string[];
|
package/package.json
CHANGED
package/src/patterns/Context.ts
CHANGED
|
@@ -40,6 +40,10 @@ export class Context implements Pattern {
|
|
|
40
40
|
return this._children;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
get startedOnIndex(){
|
|
44
|
+
return this.children[0].startedOnIndex;
|
|
45
|
+
}
|
|
46
|
+
|
|
43
47
|
getPatternWithinContext(name: string): Pattern | null {
|
|
44
48
|
return this._patterns[name] || null;
|
|
45
49
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { Node } from "../ast/Node";
|
|
2
2
|
import { Cursor } from "./Cursor";
|
|
3
|
-
import { DepthCache } from "./DepthCache";
|
|
4
3
|
import { ParseResult } from "./ParseResult";
|
|
5
4
|
import { Pattern } from "./Pattern";
|
|
6
5
|
import { findPattern } from "./findPattern";
|
|
7
6
|
import { Sequence } from "./Sequence";
|
|
8
7
|
|
|
9
8
|
let indexId = 0;
|
|
10
|
-
const depthCache = new DepthCache();
|
|
11
9
|
|
|
12
10
|
function createNode(name: string, children: Node[]) {
|
|
13
11
|
return new Node("expression", name, 0, 0, children, "");
|
|
@@ -26,7 +24,9 @@ export class ExpressionPattern implements Pattern {
|
|
|
26
24
|
private _firstIndex: number;
|
|
27
25
|
private _originalPatterns: Pattern[];
|
|
28
26
|
private _patterns: Pattern[];
|
|
29
|
-
private
|
|
27
|
+
private _atomPatterns: Pattern[];
|
|
28
|
+
private _unaryPrefixPatterns: Pattern[];
|
|
29
|
+
private _unaryPrefixNames: string[];
|
|
30
30
|
private _binaryPatterns: Pattern[];
|
|
31
31
|
private _recursivePatterns: Pattern[];
|
|
32
32
|
private _recursiveNames: string[];
|
|
@@ -63,7 +63,7 @@ export class ExpressionPattern implements Pattern {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
get unaryPatterns(): readonly Pattern[] {
|
|
66
|
-
return this.
|
|
66
|
+
return this._atomPatterns;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
get binaryPatterns(): readonly Pattern[] {
|
|
@@ -74,6 +74,10 @@ export class ExpressionPattern implements Pattern {
|
|
|
74
74
|
return this._recursivePatterns;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
get startedOnIndex() {
|
|
78
|
+
return this._firstIndex;
|
|
79
|
+
}
|
|
80
|
+
|
|
77
81
|
constructor(name: string, patterns: Pattern[]) {
|
|
78
82
|
if (patterns.length === 0) {
|
|
79
83
|
throw new Error("Need at least one pattern with an 'expression' pattern.");
|
|
@@ -84,7 +88,9 @@ export class ExpressionPattern implements Pattern {
|
|
|
84
88
|
this._name = name;
|
|
85
89
|
this._parent = null;
|
|
86
90
|
this._firstIndex = -1;
|
|
87
|
-
this.
|
|
91
|
+
this._atomPatterns = [];
|
|
92
|
+
this._unaryPrefixPatterns = [];
|
|
93
|
+
this._unaryPrefixNames = [];
|
|
88
94
|
this._binaryPatterns = [];
|
|
89
95
|
this._recursivePatterns = [];
|
|
90
96
|
this._recursiveNames = [];
|
|
@@ -96,7 +102,7 @@ export class ExpressionPattern implements Pattern {
|
|
|
96
102
|
this._shouldCompactPatternsMap = {};
|
|
97
103
|
this._patterns = this._organizePatterns(patterns);
|
|
98
104
|
|
|
99
|
-
if (this.
|
|
105
|
+
if (this._atomPatterns.length === 0) {
|
|
100
106
|
throw new Error("Need at least one operand pattern with an 'expression' pattern.");
|
|
101
107
|
}
|
|
102
108
|
}
|
|
@@ -106,7 +112,13 @@ export class ExpressionPattern implements Pattern {
|
|
|
106
112
|
patterns.forEach((pattern) => {
|
|
107
113
|
this._shouldCompactPatternsMap[pattern.name] = pattern.shouldCompactAst;
|
|
108
114
|
|
|
109
|
-
if (this.
|
|
115
|
+
if (this._isUnary(pattern)) {
|
|
116
|
+
const unaryPrefix = this._extractUnaryPrefixPattern(pattern).clone();
|
|
117
|
+
this._unaryPrefixPatterns.push(pattern);
|
|
118
|
+
this._unaryPrefixNames.push(pattern.name);
|
|
119
|
+
|
|
120
|
+
finalPatterns.push(unaryPrefix);
|
|
121
|
+
} else if (this._isBinary(pattern)) {
|
|
110
122
|
const binaryName = this._extractName(pattern);
|
|
111
123
|
const clone = this._extractDelimiter(pattern).clone();
|
|
112
124
|
clone.parent = this;
|
|
@@ -136,7 +148,7 @@ export class ExpressionPattern implements Pattern {
|
|
|
136
148
|
const clone = pattern.clone();
|
|
137
149
|
clone.parent = this;
|
|
138
150
|
|
|
139
|
-
this.
|
|
151
|
+
this._atomPatterns.push(clone);
|
|
140
152
|
finalPatterns.push(clone);
|
|
141
153
|
}
|
|
142
154
|
});
|
|
@@ -176,6 +188,31 @@ export class ExpressionPattern implements Pattern {
|
|
|
176
188
|
return pattern.name;
|
|
177
189
|
}
|
|
178
190
|
|
|
191
|
+
private _isUnary(pattern: Pattern) {
|
|
192
|
+
if (pattern.type === "right-associated" && this._isUnaryPattern(pattern.children[0])) {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return this._isUnaryPattern(pattern);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private _isUnaryPattern(pattern: Pattern) {
|
|
200
|
+
return pattern.type === "sequence" &&
|
|
201
|
+
pattern.children[0].type !== "reference" &&
|
|
202
|
+
pattern.children[0].name !== this.name &&
|
|
203
|
+
pattern.children[1].type === "reference" &&
|
|
204
|
+
pattern.children[1].name === this.name &&
|
|
205
|
+
pattern.children.length === 2;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private _extractUnaryPrefixPattern(pattern: Pattern) {
|
|
209
|
+
if (pattern.type === "right-associated") {
|
|
210
|
+
return pattern.children[0].children[0];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return pattern.children[0];
|
|
214
|
+
}
|
|
215
|
+
|
|
179
216
|
private _isRecursive(pattern: Pattern) {
|
|
180
217
|
if (pattern.type === "right-associated" && this._isRecursivePattern(pattern.children[0])) {
|
|
181
218
|
return true;
|
|
@@ -188,7 +225,7 @@ export class ExpressionPattern implements Pattern {
|
|
|
188
225
|
return pattern.type === "sequence" &&
|
|
189
226
|
pattern.children[0].type === "reference" &&
|
|
190
227
|
pattern.children[0].name === this.name &&
|
|
191
|
-
pattern.children.length >
|
|
228
|
+
pattern.children.length > 2;
|
|
192
229
|
}
|
|
193
230
|
|
|
194
231
|
private _extractRecursiveTail(pattern: Pattern) {
|
|
@@ -211,14 +248,9 @@ export class ExpressionPattern implements Pattern {
|
|
|
211
248
|
}
|
|
212
249
|
|
|
213
250
|
parse(cursor: Cursor): Node | null {
|
|
214
|
-
this._firstIndex = cursor.index;
|
|
215
|
-
depthCache.incrementDepth(this._id, this._firstIndex);
|
|
216
|
-
|
|
217
251
|
this._firstIndex = cursor.index;
|
|
218
252
|
const node = this._tryToParse(cursor);
|
|
219
253
|
|
|
220
|
-
depthCache.decrementDepth(this._id, this._firstIndex);
|
|
221
|
-
|
|
222
254
|
if (node != null) {
|
|
223
255
|
cursor.moveTo(node.lastIndex);
|
|
224
256
|
cursor.resolveError();
|
|
@@ -253,13 +285,12 @@ export class ExpressionPattern implements Pattern {
|
|
|
253
285
|
}
|
|
254
286
|
|
|
255
287
|
private _tryToParse(cursor: Cursor): Node | null {
|
|
256
|
-
if (
|
|
288
|
+
if (this._isBeyondRecursiveAllowance()) {
|
|
257
289
|
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
258
290
|
return null;
|
|
259
291
|
}
|
|
260
292
|
|
|
261
|
-
|
|
262
|
-
let lastUnaryNode: Node | null = null;
|
|
293
|
+
let lastAtomNode: Node | null = null;
|
|
263
294
|
let lastBinaryNode: Node | null = null;
|
|
264
295
|
let onIndex = cursor.index;
|
|
265
296
|
|
|
@@ -267,31 +298,57 @@ export class ExpressionPattern implements Pattern {
|
|
|
267
298
|
cursor.resolveError();
|
|
268
299
|
onIndex = cursor.index;
|
|
269
300
|
|
|
270
|
-
|
|
301
|
+
let prefix: Node | null = null;
|
|
302
|
+
let prefixName = "";
|
|
303
|
+
for (let i = 0; i < this._unaryPrefixPatterns.length; i++) {
|
|
271
304
|
cursor.moveTo(onIndex);
|
|
305
|
+
const pattern = this._unaryPrefixPatterns[i];
|
|
306
|
+
const node = pattern.parse(cursor);
|
|
307
|
+
|
|
308
|
+
if (node != null) {
|
|
309
|
+
prefix = node;
|
|
310
|
+
prefixName = this._unaryPrefixNames[i];
|
|
272
311
|
|
|
273
|
-
|
|
312
|
+
if (cursor.hasNext()) {
|
|
313
|
+
cursor.next();
|
|
314
|
+
} else {
|
|
315
|
+
break outer;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
break;
|
|
319
|
+
} else {
|
|
320
|
+
cursor.resolveError();
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
onIndex = cursor.index;
|
|
325
|
+
for (let i = 0; i < this._atomPatterns.length; i++) {
|
|
326
|
+
cursor.moveTo(onIndex);
|
|
327
|
+
const pattern = this._atomPatterns[i];
|
|
274
328
|
const node = pattern.parse(cursor);
|
|
275
329
|
|
|
276
330
|
if (node != null) {
|
|
277
|
-
|
|
331
|
+
lastAtomNode = node;
|
|
278
332
|
|
|
279
333
|
break;
|
|
280
334
|
} else {
|
|
281
|
-
|
|
335
|
+
lastAtomNode = null;
|
|
282
336
|
cursor.resolveError();
|
|
283
337
|
}
|
|
284
338
|
}
|
|
285
339
|
|
|
286
|
-
if (
|
|
340
|
+
if (lastAtomNode == null) {
|
|
287
341
|
break;
|
|
288
342
|
}
|
|
289
343
|
|
|
290
344
|
if (cursor.hasNext()) {
|
|
291
345
|
cursor.next();
|
|
292
346
|
} else {
|
|
293
|
-
if (lastBinaryNode != null &&
|
|
294
|
-
|
|
347
|
+
if (lastBinaryNode != null && lastAtomNode != null) {
|
|
348
|
+
if (prefix != null) {
|
|
349
|
+
lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
|
|
350
|
+
}
|
|
351
|
+
lastBinaryNode.appendChild(lastAtomNode);
|
|
295
352
|
}
|
|
296
353
|
break;
|
|
297
354
|
}
|
|
@@ -306,26 +363,33 @@ export class ExpressionPattern implements Pattern {
|
|
|
306
363
|
const name = this._recursiveNames[i];
|
|
307
364
|
|
|
308
365
|
if (this._endsInRecursion[i]) {
|
|
309
|
-
if (lastBinaryNode != null &&
|
|
310
|
-
|
|
366
|
+
if (lastBinaryNode != null && lastAtomNode != null) {
|
|
367
|
+
if (prefix != null) {
|
|
368
|
+
lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
|
|
369
|
+
}
|
|
370
|
+
lastBinaryNode.appendChild(lastAtomNode);
|
|
311
371
|
}
|
|
312
372
|
|
|
313
|
-
const frontExpression = lastBinaryNode == null ?
|
|
373
|
+
const frontExpression = lastBinaryNode == null ? lastAtomNode as Node : lastBinaryNode.findRoot();
|
|
314
374
|
const recursiveNode = createNode(name, [frontExpression, ...node.children]);
|
|
315
375
|
|
|
316
376
|
recursiveNode.normalize(this._firstIndex);
|
|
317
377
|
|
|
318
378
|
return recursiveNode;
|
|
319
379
|
} else {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
380
|
+
if (prefix != null) {
|
|
381
|
+
lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const recursiveNode = createNode(name, [lastAtomNode, ...node.children]);
|
|
385
|
+
recursiveNode.normalize(lastAtomNode.startIndex);
|
|
386
|
+
lastAtomNode = recursiveNode;
|
|
323
387
|
|
|
324
388
|
if (cursor.hasNext()) {
|
|
325
389
|
cursor.next();
|
|
326
390
|
} else {
|
|
327
|
-
if (lastBinaryNode != null) {
|
|
328
|
-
lastBinaryNode.appendChild(
|
|
391
|
+
if (lastBinaryNode != null && lastAtomNode != null) {
|
|
392
|
+
lastBinaryNode.appendChild(lastAtomNode);
|
|
329
393
|
}
|
|
330
394
|
break outer;
|
|
331
395
|
}
|
|
@@ -351,24 +415,24 @@ export class ExpressionPattern implements Pattern {
|
|
|
351
415
|
if (delimiterNode == null) {
|
|
352
416
|
if (i === this._binaryPatterns.length - 1) {
|
|
353
417
|
if (lastBinaryNode == null) {
|
|
354
|
-
return
|
|
355
|
-
} else if (
|
|
356
|
-
lastBinaryNode.appendChild(
|
|
418
|
+
return lastAtomNode;
|
|
419
|
+
} else if (lastAtomNode != null) {
|
|
420
|
+
lastBinaryNode.appendChild(lastAtomNode);
|
|
357
421
|
}
|
|
358
422
|
}
|
|
359
423
|
continue;
|
|
360
424
|
}
|
|
361
425
|
|
|
362
|
-
if (lastBinaryNode == null &&
|
|
363
|
-
const node = createNode(name, [
|
|
426
|
+
if (lastBinaryNode == null && lastAtomNode != null && delimiterNode != null) {
|
|
427
|
+
const node = createNode(name, [lastAtomNode, delimiterNode]);
|
|
364
428
|
lastBinaryNode = node;
|
|
365
|
-
} else if (lastBinaryNode != null &&
|
|
429
|
+
} else if (lastBinaryNode != null && lastAtomNode != null && delimiterNode != null) {
|
|
366
430
|
const precedence = this._precedenceMap[name];
|
|
367
431
|
const lastPrecendece = lastBinaryNode == null ? 0 : this._precedenceMap[lastBinaryNode.name] == null ? -1 : this._precedenceMap[lastBinaryNode.name];
|
|
368
432
|
const association = this._binaryAssociation[i];
|
|
369
433
|
|
|
370
434
|
if (precedence === lastPrecendece && association === Association.right) {
|
|
371
|
-
const node = createNode(name, [
|
|
435
|
+
const node = createNode(name, [lastAtomNode, delimiterNode]);
|
|
372
436
|
lastBinaryNode.appendChild(node);
|
|
373
437
|
|
|
374
438
|
lastBinaryNode = node;
|
|
@@ -376,7 +440,7 @@ export class ExpressionPattern implements Pattern {
|
|
|
376
440
|
const node = createNode(name, []);
|
|
377
441
|
|
|
378
442
|
lastBinaryNode.replaceWith(node);
|
|
379
|
-
lastBinaryNode.appendChild(
|
|
443
|
+
lastBinaryNode.appendChild(lastAtomNode);
|
|
380
444
|
|
|
381
445
|
node.append(lastBinaryNode, delimiterNode);
|
|
382
446
|
lastBinaryNode = node;
|
|
@@ -394,7 +458,7 @@ export class ExpressionPattern implements Pattern {
|
|
|
394
458
|
ancestor = ancestor.parent;
|
|
395
459
|
}
|
|
396
460
|
|
|
397
|
-
lastBinaryNode.appendChild(
|
|
461
|
+
lastBinaryNode.appendChild(lastAtomNode);
|
|
398
462
|
|
|
399
463
|
if (root != null) {
|
|
400
464
|
const node = createNode(name, []);
|
|
@@ -403,12 +467,12 @@ export class ExpressionPattern implements Pattern {
|
|
|
403
467
|
|
|
404
468
|
lastBinaryNode = node;
|
|
405
469
|
} else {
|
|
406
|
-
const node = createNode(name, [
|
|
470
|
+
const node = createNode(name, [lastAtomNode, delimiterNode]);
|
|
407
471
|
lastBinaryNode = node;
|
|
408
472
|
}
|
|
409
473
|
|
|
410
474
|
} else {
|
|
411
|
-
const node = createNode(name, [
|
|
475
|
+
const node = createNode(name, [lastAtomNode, delimiterNode]);
|
|
412
476
|
lastBinaryNode.appendChild(node);
|
|
413
477
|
|
|
414
478
|
lastBinaryNode = node;
|
|
@@ -431,14 +495,14 @@ export class ExpressionPattern implements Pattern {
|
|
|
431
495
|
}
|
|
432
496
|
|
|
433
497
|
if (lastBinaryNode == null) {
|
|
434
|
-
return
|
|
498
|
+
return lastAtomNode;
|
|
435
499
|
} else {
|
|
436
500
|
const root = lastBinaryNode.findAncestor(n => n.parent == null) as Node || lastBinaryNode;
|
|
437
501
|
if (lastBinaryNode.children.length < 3) {
|
|
438
502
|
lastBinaryNode.remove();
|
|
439
503
|
|
|
440
504
|
if (lastBinaryNode === root) {
|
|
441
|
-
return
|
|
505
|
+
return lastAtomNode;
|
|
442
506
|
}
|
|
443
507
|
}
|
|
444
508
|
|
|
@@ -447,6 +511,24 @@ export class ExpressionPattern implements Pattern {
|
|
|
447
511
|
}
|
|
448
512
|
}
|
|
449
513
|
|
|
514
|
+
private _isBeyondRecursiveAllowance() {
|
|
515
|
+
let depth = 0;
|
|
516
|
+
let pattern: Pattern | null = this;
|
|
517
|
+
|
|
518
|
+
while (pattern != null) {
|
|
519
|
+
if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
|
|
520
|
+
depth++;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
if (depth > 2) {
|
|
524
|
+
return true;
|
|
525
|
+
}
|
|
526
|
+
pattern = pattern.parent;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
return false;
|
|
530
|
+
}
|
|
531
|
+
|
|
450
532
|
test(text: string) {
|
|
451
533
|
const cursor = new Cursor(text);
|
|
452
534
|
const ast = this.parse(cursor);
|
|
@@ -483,7 +565,7 @@ export class ExpressionPattern implements Pattern {
|
|
|
483
565
|
}
|
|
484
566
|
|
|
485
567
|
if (this.binaryPatterns.indexOf(childReference)) {
|
|
486
|
-
const unaryTokens = this.
|
|
568
|
+
const unaryTokens = this._atomPatterns.map(p => p.getTokens()).flat();
|
|
487
569
|
|
|
488
570
|
if (this._parent != null) {
|
|
489
571
|
const nextTokens = this._parent.getTokensAfter(this);
|
|
@@ -521,7 +603,7 @@ export class ExpressionPattern implements Pattern {
|
|
|
521
603
|
}
|
|
522
604
|
|
|
523
605
|
if (this.binaryPatterns.indexOf(childReference)) {
|
|
524
|
-
const unaryPatterns = this.
|
|
606
|
+
const unaryPatterns = this._atomPatterns.map(p => p.getPatterns()).flat();
|
|
525
607
|
|
|
526
608
|
if (this._parent != null) {
|
|
527
609
|
const nextPatterns = this._parent.getPatternsAfter(this);
|
|
@@ -23,6 +23,7 @@ export class FiniteRepeat implements Pattern {
|
|
|
23
23
|
private _min: number;
|
|
24
24
|
private _max: number;
|
|
25
25
|
private _trimDivider: boolean;
|
|
26
|
+
private _firstIndex: number;
|
|
26
27
|
|
|
27
28
|
shouldCompactAst = false;
|
|
28
29
|
|
|
@@ -58,6 +59,10 @@ export class FiniteRepeat implements Pattern {
|
|
|
58
59
|
return this._max;
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
get startedOnIndex() {
|
|
63
|
+
return this._firstIndex;
|
|
64
|
+
}
|
|
65
|
+
|
|
61
66
|
constructor(name: string, pattern: Pattern, options: FiniteRepeatOptions = {}) {
|
|
62
67
|
this._id = `finite-repeat-${idIndex++}`;
|
|
63
68
|
this._type = "finite-repeat";
|
|
@@ -68,6 +73,7 @@ export class FiniteRepeat implements Pattern {
|
|
|
68
73
|
this._min = options.min != null ? Math.max(options.min, 1) : 1;
|
|
69
74
|
this._max = Math.max(this.min, options.max || this.min);
|
|
70
75
|
this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
|
|
76
|
+
this._firstIndex = 0;
|
|
71
77
|
|
|
72
78
|
for (let i = 0; i < this._max; i++) {
|
|
73
79
|
const child = pattern.clone();
|
|
@@ -85,6 +91,8 @@ export class FiniteRepeat implements Pattern {
|
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
parse(cursor: Cursor): Node | null {
|
|
94
|
+
this._firstIndex = cursor.index;
|
|
95
|
+
|
|
88
96
|
const startIndex = cursor.index;
|
|
89
97
|
const nodes: Node[] = [];
|
|
90
98
|
const modulo = this._hasDivider ? 2 : 1;
|
|
@@ -56,6 +56,10 @@ export class InfiniteRepeat implements Pattern {
|
|
|
56
56
|
return this._min;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
get startedOnIndex(){
|
|
60
|
+
return this._firstIndex;
|
|
61
|
+
}
|
|
62
|
+
|
|
59
63
|
constructor(name: string, pattern: Pattern, options: InfiniteRepeatOptions = {}) {
|
|
60
64
|
const min = options.min != null ? Math.max(options.min, 1) : 1;
|
|
61
65
|
const divider = options.divider;
|
package/src/patterns/Literal.ts
CHANGED
package/src/patterns/Not.ts
CHANGED
package/src/patterns/Optional.ts
CHANGED
|
@@ -38,6 +38,10 @@ export class Optional 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(name: string, pattern: Pattern) {
|
|
42
46
|
this._id = `optional-${idIndex++}`;
|
|
43
47
|
this._type = "optional";
|