clarity-pattern-parser 10.1.26 → 10.2.1
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/ast/Node.d.ts +1 -0
- package/dist/grammar/Grammar.d.ts +2 -0
- package/dist/index.browser.js +420 -10
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.js +420 -11
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +420 -10
- package/dist/index.js.map +1 -1
- package/dist/patterns/ExpressionPattern.d.ts +51 -0
- package/package.json +1 -1
- package/src/ast/Node.ts +12 -1
- package/src/grammar/Grammar.test.ts +15 -0
- package/src/grammar/Grammar.ts +25 -1
- package/src/index.ts +2 -0
- package/src/patterns/ExpressionPattern.test.ts +132 -0
- package/src/patterns/ExpressionPattern.ts +298 -57
- package/src/patterns/Options.ts +0 -1
- package/src/patterns/RightAssociatedPattern.ts +29 -11
|
@@ -3,10 +3,16 @@ import { Cursor } from "./Cursor";
|
|
|
3
3
|
import { DepthCache } from "./DepthCache";
|
|
4
4
|
import { ParseResult } from "./ParseResult";
|
|
5
5
|
import { Pattern } from "./Pattern";
|
|
6
|
+
import { findPattern } from "./findPattern";
|
|
7
|
+
import { Sequence } from "./Sequence";
|
|
6
8
|
|
|
7
9
|
let indexId = 0;
|
|
8
10
|
const depthCache = new DepthCache();
|
|
9
11
|
|
|
12
|
+
function createNode(name: string, children: Node[]) {
|
|
13
|
+
return new Node("expression", name, 0, 0, children, "");
|
|
14
|
+
}
|
|
15
|
+
|
|
10
16
|
enum Association {
|
|
11
17
|
left = 0,
|
|
12
18
|
right = 1,
|
|
@@ -17,13 +23,15 @@ export class ExpressionPattern implements Pattern {
|
|
|
17
23
|
private _type: string;
|
|
18
24
|
private _name: string;
|
|
19
25
|
private _parent: Pattern | null;
|
|
20
|
-
private _token: string;
|
|
21
26
|
private _firstIndex: number;
|
|
27
|
+
private _originalPatterns: Pattern[];
|
|
22
28
|
private _patterns: Pattern[];
|
|
23
29
|
private _unaryPatterns: Pattern[];
|
|
24
30
|
private _binaryPatterns: Pattern[];
|
|
31
|
+
private _recursivePatterns: Pattern[];
|
|
32
|
+
private _recursiveNames: string[];
|
|
25
33
|
private _binaryAssociation: Association[];
|
|
26
|
-
private _precedenceMap: Record<string, number>;
|
|
34
|
+
private _precedenceMap: Record<string, number>;
|
|
27
35
|
private _binaryNames: string[];
|
|
28
36
|
|
|
29
37
|
get id(): string {
|
|
@@ -38,10 +46,6 @@ export class ExpressionPattern implements Pattern {
|
|
|
38
46
|
return this._name;
|
|
39
47
|
}
|
|
40
48
|
|
|
41
|
-
get token(): string {
|
|
42
|
-
return this._token;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
49
|
get parent(): Pattern | null {
|
|
46
50
|
return this._parent;
|
|
47
51
|
}
|
|
@@ -54,6 +58,18 @@ export class ExpressionPattern implements Pattern {
|
|
|
54
58
|
return this._patterns;
|
|
55
59
|
}
|
|
56
60
|
|
|
61
|
+
get unaryPatterns(): readonly Pattern[] {
|
|
62
|
+
return this._unaryPatterns;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get binaryPatterns(): readonly Pattern[] {
|
|
66
|
+
return this._binaryPatterns;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get recursivePatterns(): readonly Pattern[] {
|
|
70
|
+
return this._recursivePatterns;
|
|
71
|
+
}
|
|
72
|
+
|
|
57
73
|
constructor(name: string, patterns: Pattern[]) {
|
|
58
74
|
if (patterns.length === 0) {
|
|
59
75
|
throw new Error("Need at least one pattern with an 'expression' pattern.");
|
|
@@ -62,19 +78,28 @@ export class ExpressionPattern implements Pattern {
|
|
|
62
78
|
this._id = `expression-${indexId++}`;
|
|
63
79
|
this._type = "expression";
|
|
64
80
|
this._name = name;
|
|
81
|
+
this._parent = null;
|
|
82
|
+
this._firstIndex = -1;
|
|
65
83
|
this._unaryPatterns = [];
|
|
66
84
|
this._binaryPatterns = [];
|
|
85
|
+
this._recursivePatterns = [];
|
|
86
|
+
this._recursiveNames = [];
|
|
87
|
+
this._binaryNames = [];
|
|
88
|
+
this._binaryAssociation = [];
|
|
67
89
|
this._precedenceMap = {};
|
|
68
|
-
|
|
69
|
-
this._patterns.forEach(p => p.parent = this);
|
|
90
|
+
this._originalPatterns = patterns;
|
|
70
91
|
this._patterns = this._organizePatterns(patterns);
|
|
92
|
+
|
|
93
|
+
if (this._unaryPatterns.length === 0) {
|
|
94
|
+
throw new Error("Need at least one operand pattern with an 'expression' pattern.");
|
|
95
|
+
}
|
|
71
96
|
}
|
|
72
97
|
|
|
73
98
|
private _organizePatterns(patterns: Pattern[]) {
|
|
74
99
|
const finalPatterns: Pattern[] = [];
|
|
75
100
|
patterns.forEach((pattern) => {
|
|
76
101
|
if (this._isBinary(pattern)) {
|
|
77
|
-
const binaryName = pattern
|
|
102
|
+
const binaryName = this._extractName(pattern);
|
|
78
103
|
const clone = this._extractDelimiter(pattern).clone();
|
|
79
104
|
clone.parent = this;
|
|
80
105
|
|
|
@@ -89,6 +114,14 @@ export class ExpressionPattern implements Pattern {
|
|
|
89
114
|
}
|
|
90
115
|
|
|
91
116
|
finalPatterns.push(clone);
|
|
117
|
+
} else if (this._isRecursive(pattern)) {
|
|
118
|
+
const name = this._extractName(pattern);
|
|
119
|
+
const tail = this._extractRecursiveTail(pattern);
|
|
120
|
+
tail.parent = this;
|
|
121
|
+
|
|
122
|
+
this._recursivePatterns.push(tail);
|
|
123
|
+
this._recursiveNames.push(name);
|
|
124
|
+
finalPatterns.push(tail);
|
|
92
125
|
} else {
|
|
93
126
|
const clone = pattern.clone();
|
|
94
127
|
clone.parent = this;
|
|
@@ -118,10 +151,43 @@ export class ExpressionPattern implements Pattern {
|
|
|
118
151
|
pattern.children.length === 3;
|
|
119
152
|
}
|
|
120
153
|
|
|
121
|
-
private _extractDelimiter(pattern) {
|
|
154
|
+
private _extractDelimiter(pattern: Pattern) {
|
|
155
|
+
if (pattern.type === "right-associated") {
|
|
156
|
+
return pattern.children[0].children[1];
|
|
157
|
+
}
|
|
122
158
|
return pattern.children[1];
|
|
123
159
|
}
|
|
124
160
|
|
|
161
|
+
private _extractName(pattern: Pattern) {
|
|
162
|
+
if (pattern.type === "right-associated") {
|
|
163
|
+
return pattern.children[0].name;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return pattern.name;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private _isRecursive(pattern: Pattern) {
|
|
170
|
+
if (pattern.type === "right-associated" && this._isRecursivePattern(pattern.children[0])) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return this._isRecursivePattern(pattern);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private _isRecursivePattern(pattern: Pattern) {
|
|
178
|
+
return pattern.type === "sequence" &&
|
|
179
|
+
pattern.children[0].type === "reference" &&
|
|
180
|
+
pattern.children[0].name === this.name &&
|
|
181
|
+
pattern.children.length > 2;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private _extractRecursiveTail(pattern: Pattern) {
|
|
185
|
+
if (pattern.type === "right-associated") {
|
|
186
|
+
return new Sequence(`${pattern.children[0].name}-tail`, pattern.children[0].children.slice(1));
|
|
187
|
+
}
|
|
188
|
+
return new Sequence(`${pattern.name}-tail`, pattern.children.slice(1));
|
|
189
|
+
}
|
|
190
|
+
|
|
125
191
|
parse(cursor: Cursor): Node | null {
|
|
126
192
|
// This is a cache to help with speed
|
|
127
193
|
this._firstIndex = cursor.index;
|
|
@@ -143,103 +209,278 @@ export class ExpressionPattern implements Pattern {
|
|
|
143
209
|
}
|
|
144
210
|
|
|
145
211
|
private _tryToParse(cursor: Cursor): Node | null {
|
|
212
|
+
if (depthCache.getDepth(this._id, this._firstIndex) > 2) {
|
|
213
|
+
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
|
|
146
217
|
let lastUnaryNode: Node | null = null;
|
|
147
218
|
let lastBinaryNode: Node | null = null;
|
|
148
219
|
let onIndex = cursor.index;
|
|
149
|
-
|
|
150
|
-
while (true) {
|
|
220
|
+
|
|
221
|
+
outer: while (true) {
|
|
151
222
|
onIndex = cursor.index;
|
|
152
223
|
|
|
153
224
|
for (let i = 0; i < this._unaryPatterns.length; i++) {
|
|
154
225
|
cursor.moveTo(onIndex);
|
|
155
226
|
|
|
156
227
|
const pattern = this._unaryPatterns[i];
|
|
157
|
-
|
|
228
|
+
const node = pattern.parse(cursor);
|
|
229
|
+
|
|
230
|
+
if (node != null) {
|
|
231
|
+
lastUnaryNode = node;
|
|
232
|
+
break;
|
|
233
|
+
} else {
|
|
234
|
+
lastUnaryNode = null;
|
|
235
|
+
cursor.resolveError();
|
|
236
|
+
}
|
|
158
237
|
}
|
|
159
|
-
|
|
160
|
-
const canContinue = cursor.hasNext();
|
|
161
238
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
239
|
+
if (lastUnaryNode == null) {
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (cursor.hasNext()) {
|
|
244
|
+
cursor.next();
|
|
245
|
+
} else {
|
|
246
|
+
if (lastBinaryNode != null && lastUnaryNode != null) {
|
|
247
|
+
lastBinaryNode.appendChild(lastUnaryNode);
|
|
248
|
+
}
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
169
251
|
|
|
170
252
|
onIndex = cursor.index;
|
|
171
253
|
|
|
254
|
+
for (let i = 0; i < this._recursivePatterns.length; i++) {
|
|
255
|
+
const pattern = this._recursivePatterns[i];
|
|
256
|
+
const node = pattern.parse(cursor);
|
|
257
|
+
|
|
258
|
+
if (node != null) {
|
|
259
|
+
if (lastBinaryNode != null && lastUnaryNode != null) {
|
|
260
|
+
lastBinaryNode.appendChild(lastUnaryNode);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const frontExpression = lastBinaryNode == null ? lastUnaryNode as Node : lastBinaryNode.findRoot();
|
|
264
|
+
const name = this._recursiveNames[i];
|
|
265
|
+
const recursiveNode = createNode(name, [frontExpression, ...node.children]);
|
|
266
|
+
|
|
267
|
+
recursiveNode.normalize(this._firstIndex);
|
|
268
|
+
return recursiveNode;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
cursor.moveTo(onIndex);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
onIndex = cursor.index;
|
|
172
275
|
for (let i = 0; i < this._binaryPatterns.length; i++) {
|
|
173
276
|
cursor.moveTo(onIndex);
|
|
174
|
-
const name = this._binaryNames[i];
|
|
175
|
-
const pattern = this._binaryPatterns[i];
|
|
176
277
|
|
|
177
|
-
const
|
|
278
|
+
const pattern = this._binaryPatterns[i];
|
|
279
|
+
const name = this._binaryNames[i];
|
|
280
|
+
const delimiterNode = pattern.parse(cursor);
|
|
281
|
+
|
|
282
|
+
if (delimiterNode == null) {
|
|
283
|
+
if (i === this._binaryPatterns.length - 1) {
|
|
284
|
+
if (lastBinaryNode == null) {
|
|
285
|
+
return lastUnaryNode;
|
|
286
|
+
} else if (lastUnaryNode != null) {
|
|
287
|
+
lastBinaryNode.appendChild(lastUnaryNode);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
178
292
|
|
|
179
|
-
|
|
180
|
-
|
|
293
|
+
if (lastBinaryNode == null && lastUnaryNode != null && delimiterNode != null) {
|
|
294
|
+
const node = createNode(name, [lastUnaryNode, delimiterNode]);
|
|
295
|
+
lastBinaryNode = node;
|
|
296
|
+
} else if (lastBinaryNode != null && lastUnaryNode != null && delimiterNode != null) {
|
|
297
|
+
const precedence = this._precedenceMap[name];
|
|
298
|
+
const lastPrecendece = lastBinaryNode == null ? 0 : this._precedenceMap[lastBinaryNode.name];
|
|
299
|
+
const association = this._binaryAssociation[i];
|
|
300
|
+
|
|
301
|
+
if (precedence === lastPrecendece && association === Association.right) {
|
|
302
|
+
const node = createNode(name, [lastUnaryNode, delimiterNode]);
|
|
303
|
+
lastBinaryNode.appendChild(node);
|
|
304
|
+
lastBinaryNode = node;
|
|
305
|
+
} else if (precedence === lastPrecendece) {
|
|
306
|
+
const node = createNode(name, []);
|
|
307
|
+
|
|
308
|
+
lastBinaryNode.replaceWith(node);
|
|
309
|
+
lastBinaryNode.appendChild(lastUnaryNode);
|
|
310
|
+
node.append(lastBinaryNode, delimiterNode);
|
|
311
|
+
lastBinaryNode = node;
|
|
312
|
+
} else if (precedence > lastPrecendece) {
|
|
313
|
+
let ancestor = lastBinaryNode.parent;
|
|
314
|
+
let root: Node | null = lastBinaryNode;
|
|
315
|
+
|
|
316
|
+
while(ancestor != null){
|
|
317
|
+
const nodePrecedence = this._precedenceMap[ancestor.name];
|
|
318
|
+
|
|
319
|
+
if (nodePrecedence > precedence){
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
root = ancestor;
|
|
323
|
+
ancestor = ancestor.parent;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
lastBinaryNode.appendChild(lastUnaryNode);
|
|
327
|
+
|
|
328
|
+
if (root != null) {
|
|
329
|
+
const node = createNode(name, []);
|
|
330
|
+
root.replaceWith(node);
|
|
331
|
+
node.append(root, delimiterNode);
|
|
332
|
+
|
|
333
|
+
lastBinaryNode = node;
|
|
334
|
+
} else {
|
|
335
|
+
const node = createNode(name, [lastUnaryNode, delimiterNode]);
|
|
336
|
+
lastBinaryNode = node;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
} else {
|
|
340
|
+
const node = createNode(name, [lastUnaryNode, delimiterNode]);
|
|
341
|
+
lastBinaryNode.appendChild(node);
|
|
342
|
+
lastBinaryNode = node;
|
|
343
|
+
}
|
|
181
344
|
|
|
182
|
-
|
|
183
|
-
// association = this._binaryAssociation[i];
|
|
345
|
+
}
|
|
184
346
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
// }
|
|
191
|
-
// } else {
|
|
347
|
+
if (cursor.hasNext()) {
|
|
348
|
+
cursor.next();
|
|
349
|
+
} else {
|
|
350
|
+
break outer;
|
|
351
|
+
}
|
|
192
352
|
|
|
193
|
-
|
|
194
|
-
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
195
355
|
|
|
356
|
+
if (lastBinaryNode == null){
|
|
357
|
+
break;
|
|
196
358
|
}
|
|
197
359
|
}
|
|
198
360
|
|
|
199
|
-
|
|
200
|
-
|
|
361
|
+
if (lastBinaryNode == null) {
|
|
362
|
+
return lastUnaryNode;
|
|
363
|
+
} else {
|
|
364
|
+
const root = lastBinaryNode.findAncestor(n => n.parent == null) as Node || lastBinaryNode;
|
|
365
|
+
if (lastBinaryNode.children.length < 3) {
|
|
366
|
+
lastBinaryNode.remove();
|
|
367
|
+
|
|
368
|
+
if (lastBinaryNode === root) {
|
|
369
|
+
return lastUnaryNode;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
201
372
|
|
|
202
|
-
|
|
203
|
-
|
|
373
|
+
root.normalize(this._firstIndex);
|
|
374
|
+
return root;
|
|
375
|
+
}
|
|
204
376
|
}
|
|
205
377
|
|
|
206
|
-
test(text: string
|
|
207
|
-
|
|
378
|
+
test(text: string) {
|
|
379
|
+
const cursor = new Cursor(text);
|
|
380
|
+
const ast = this.parse(cursor);
|
|
381
|
+
|
|
382
|
+
return ast?.value === text;
|
|
208
383
|
}
|
|
209
384
|
|
|
210
|
-
|
|
211
|
-
|
|
385
|
+
exec(text: string, record = false): ParseResult {
|
|
386
|
+
const cursor = new Cursor(text);
|
|
387
|
+
record && cursor.startRecording();
|
|
388
|
+
|
|
389
|
+
const ast = this.parse(cursor);
|
|
390
|
+
|
|
391
|
+
return {
|
|
392
|
+
ast: ast?.value === text ? ast : null,
|
|
393
|
+
cursor
|
|
394
|
+
};
|
|
212
395
|
}
|
|
213
396
|
|
|
214
397
|
getTokens(): string[] {
|
|
215
|
-
|
|
398
|
+
return this.unaryPatterns.map(p => p.getTokens()).flat();
|
|
216
399
|
}
|
|
217
400
|
|
|
218
401
|
getTokensAfter(childReference: Pattern): string[] {
|
|
219
|
-
|
|
402
|
+
if (this.unaryPatterns.indexOf(childReference)) {
|
|
403
|
+
const recursiveTokens = this._recursivePatterns.map(p => p.getTokens()).flat();
|
|
404
|
+
const binaryTokens = this._binaryPatterns.map(p => p.getTokens()).flat();
|
|
405
|
+
|
|
406
|
+
return [...recursiveTokens, ...binaryTokens];
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (this.recursivePatterns.indexOf(childReference)) {
|
|
410
|
+
return this._binaryPatterns.map(p => p.getTokens()).flat();
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (this.binaryPatterns.indexOf(childReference)) {
|
|
414
|
+
const unaryTokens = this._unaryPatterns.map(p => p.getTokens()).flat();
|
|
415
|
+
|
|
416
|
+
if (this._parent != null) {
|
|
417
|
+
const nextTokens = this._parent.getTokensAfter(this);
|
|
418
|
+
return [...unaryTokens, ...nextTokens];
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
return unaryTokens;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
return [];
|
|
220
425
|
}
|
|
221
426
|
|
|
222
427
|
getNextTokens(): string[] {
|
|
223
|
-
|
|
428
|
+
if (this._parent == null) {
|
|
429
|
+
return [];
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return this._parent.getTokensAfter(this);
|
|
224
433
|
}
|
|
225
434
|
|
|
226
435
|
getPatterns(): Pattern[] {
|
|
227
|
-
|
|
436
|
+
return this.unaryPatterns.map(p => p.getPatterns()).flat();
|
|
228
437
|
}
|
|
229
438
|
|
|
230
439
|
getPatternsAfter(childReference: Pattern): Pattern[] {
|
|
231
|
-
|
|
440
|
+
if (this.unaryPatterns.indexOf(childReference)) {
|
|
441
|
+
const recursivePatterns = this._recursivePatterns.map(p => p.getPatterns()).flat();
|
|
442
|
+
const binaryPatterns = this._binaryPatterns.map(p => p.getPatterns()).flat();
|
|
443
|
+
|
|
444
|
+
return [...recursivePatterns, ...binaryPatterns];
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (this.recursivePatterns.indexOf(childReference)) {
|
|
448
|
+
return this._binaryPatterns.map(p => p.getPatterns()).flat();
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (this.binaryPatterns.indexOf(childReference)) {
|
|
452
|
+
const unaryPatterns = this._unaryPatterns.map(p => p.getPatterns()).flat();
|
|
453
|
+
|
|
454
|
+
if (this._parent != null) {
|
|
455
|
+
const nextPatterns = this._parent.getPatternsAfter(this);
|
|
456
|
+
return [...unaryPatterns, ...nextPatterns];
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return unaryPatterns;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
return [];
|
|
232
463
|
}
|
|
233
464
|
|
|
234
465
|
getNextPatterns(): Pattern[] {
|
|
235
|
-
|
|
466
|
+
if (this._parent == null) {
|
|
467
|
+
return [];
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
return this._parent.getPatternsAfter(this);
|
|
236
471
|
}
|
|
237
472
|
|
|
238
|
-
find(predicate: (
|
|
239
|
-
|
|
473
|
+
find(predicate: (p: Pattern) => boolean): Pattern | null {
|
|
474
|
+
return findPattern(this, predicate);
|
|
240
475
|
}
|
|
241
476
|
|
|
242
|
-
|
|
243
|
-
|
|
477
|
+
clone(name = this._name): Pattern {
|
|
478
|
+
const clone = new ExpressionPattern(name, this._originalPatterns);
|
|
479
|
+
clone._id = this._id;
|
|
480
|
+
return clone;
|
|
244
481
|
}
|
|
245
|
-
|
|
482
|
+
|
|
483
|
+
isEqual(pattern: ExpressionPattern): boolean {
|
|
484
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
485
|
+
}
|
|
486
|
+
}
|
package/src/patterns/Options.ts
CHANGED
|
@@ -111,7 +111,6 @@ export class Options implements Pattern {
|
|
|
111
111
|
|
|
112
112
|
private _tryToParse(cursor: Cursor): Node | null {
|
|
113
113
|
if (depthCache.getDepth(this._id, this._firstIndex) > 2) {
|
|
114
|
-
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
115
114
|
return null;
|
|
116
115
|
}
|
|
117
116
|
|
|
@@ -6,13 +6,25 @@ import { Pattern } from "./Pattern";
|
|
|
6
6
|
let indexId = 0;
|
|
7
7
|
|
|
8
8
|
export class RightAssociatedPattern implements Pattern {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
private _id: string;
|
|
10
|
+
private _type: string;
|
|
11
|
+
private _name: string;
|
|
12
12
|
private _parent: Pattern | null;
|
|
13
|
-
|
|
13
|
+
private _children: Pattern[];
|
|
14
14
|
|
|
15
|
-
get
|
|
15
|
+
get id(): string {
|
|
16
|
+
return this._id;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get type(): string {
|
|
20
|
+
return this._type;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get name(): string {
|
|
24
|
+
return this._name;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get parent(): Pattern | null {
|
|
16
28
|
return this._parent;
|
|
17
29
|
}
|
|
18
30
|
|
|
@@ -20,12 +32,16 @@ export class RightAssociatedPattern implements Pattern {
|
|
|
20
32
|
this._parent = pattern;
|
|
21
33
|
}
|
|
22
34
|
|
|
35
|
+
get children(): Pattern[] {
|
|
36
|
+
return this._children;
|
|
37
|
+
}
|
|
38
|
+
|
|
23
39
|
constructor(pattern: Pattern) {
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
27
|
-
this.
|
|
28
|
-
this.
|
|
40
|
+
this._id = `right-associated-${indexId++}`;
|
|
41
|
+
this._type = "right-associated";
|
|
42
|
+
this._name = "";
|
|
43
|
+
this._parent = null;
|
|
44
|
+
this._children = [pattern.clone()];
|
|
29
45
|
}
|
|
30
46
|
|
|
31
47
|
parse(cursor: Cursor): Node | null {
|
|
@@ -41,7 +57,9 @@ export class RightAssociatedPattern implements Pattern {
|
|
|
41
57
|
}
|
|
42
58
|
|
|
43
59
|
clone(_name?: string | undefined): Pattern {
|
|
44
|
-
|
|
60
|
+
const clone = new RightAssociatedPattern(this.children[0]);
|
|
61
|
+
clone._id = this._id;
|
|
62
|
+
return clone;
|
|
45
63
|
}
|
|
46
64
|
|
|
47
65
|
getTokens(): string[] {
|