clarity-pattern-parser 10.1.26 → 10.2.0
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 +409 -10
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.js +409 -11
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +409 -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 +283 -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,263 @@ 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
|
+
const root = lastBinaryNode.findRoot();
|
|
314
|
+
lastBinaryNode.appendChild(lastUnaryNode);
|
|
315
|
+
|
|
316
|
+
if (root != null) {
|
|
317
|
+
const node = createNode(name, [root, delimiterNode]);
|
|
318
|
+
lastBinaryNode = node;
|
|
319
|
+
} else {
|
|
320
|
+
const node = createNode(name, [lastUnaryNode, delimiterNode]);
|
|
321
|
+
lastBinaryNode = node;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
} else {
|
|
325
|
+
const node = createNode(name, [lastUnaryNode, delimiterNode]);
|
|
326
|
+
lastBinaryNode.appendChild(node);
|
|
327
|
+
lastBinaryNode = node;
|
|
328
|
+
}
|
|
181
329
|
|
|
182
|
-
|
|
183
|
-
// association = this._binaryAssociation[i];
|
|
330
|
+
}
|
|
184
331
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
// }
|
|
191
|
-
// } else {
|
|
332
|
+
if (cursor.hasNext()) {
|
|
333
|
+
cursor.next();
|
|
334
|
+
} else {
|
|
335
|
+
break outer;
|
|
336
|
+
}
|
|
192
337
|
|
|
193
|
-
|
|
194
|
-
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
195
340
|
|
|
341
|
+
if (lastBinaryNode == null){
|
|
342
|
+
break;
|
|
196
343
|
}
|
|
197
344
|
}
|
|
198
345
|
|
|
199
|
-
|
|
200
|
-
|
|
346
|
+
if (lastBinaryNode == null) {
|
|
347
|
+
return lastUnaryNode;
|
|
348
|
+
} else {
|
|
349
|
+
const root = lastBinaryNode.findAncestor(n => n.parent == null) as Node || lastBinaryNode;
|
|
350
|
+
if (lastBinaryNode.children.length < 3) {
|
|
351
|
+
lastBinaryNode.remove();
|
|
352
|
+
|
|
353
|
+
if (lastBinaryNode === root) {
|
|
354
|
+
return lastUnaryNode;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
201
357
|
|
|
202
|
-
|
|
203
|
-
|
|
358
|
+
root.normalize(this._firstIndex);
|
|
359
|
+
return root;
|
|
360
|
+
}
|
|
204
361
|
}
|
|
205
362
|
|
|
206
|
-
test(text: string
|
|
207
|
-
|
|
363
|
+
test(text: string) {
|
|
364
|
+
const cursor = new Cursor(text);
|
|
365
|
+
const ast = this.parse(cursor);
|
|
366
|
+
|
|
367
|
+
return ast?.value === text;
|
|
208
368
|
}
|
|
209
369
|
|
|
210
|
-
|
|
211
|
-
|
|
370
|
+
exec(text: string, record = false): ParseResult {
|
|
371
|
+
const cursor = new Cursor(text);
|
|
372
|
+
record && cursor.startRecording();
|
|
373
|
+
|
|
374
|
+
const ast = this.parse(cursor);
|
|
375
|
+
|
|
376
|
+
return {
|
|
377
|
+
ast: ast?.value === text ? ast : null,
|
|
378
|
+
cursor
|
|
379
|
+
};
|
|
212
380
|
}
|
|
213
381
|
|
|
214
382
|
getTokens(): string[] {
|
|
215
|
-
|
|
383
|
+
return this.unaryPatterns.map(p => p.getTokens()).flat();
|
|
216
384
|
}
|
|
217
385
|
|
|
218
386
|
getTokensAfter(childReference: Pattern): string[] {
|
|
219
|
-
|
|
387
|
+
if (this.unaryPatterns.indexOf(childReference)) {
|
|
388
|
+
const recursiveTokens = this._recursivePatterns.map(p => p.getTokens()).flat();
|
|
389
|
+
const binaryTokens = this._binaryPatterns.map(p => p.getTokens()).flat();
|
|
390
|
+
|
|
391
|
+
return [...recursiveTokens, ...binaryTokens];
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (this.recursivePatterns.indexOf(childReference)) {
|
|
395
|
+
return this._binaryPatterns.map(p => p.getTokens()).flat();
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (this.binaryPatterns.indexOf(childReference)) {
|
|
399
|
+
const unaryTokens = this._unaryPatterns.map(p => p.getTokens()).flat();
|
|
400
|
+
|
|
401
|
+
if (this._parent != null) {
|
|
402
|
+
const nextTokens = this._parent.getTokensAfter(this);
|
|
403
|
+
return [...unaryTokens, ...nextTokens];
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return unaryTokens;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
return [];
|
|
220
410
|
}
|
|
221
411
|
|
|
222
412
|
getNextTokens(): string[] {
|
|
223
|
-
|
|
413
|
+
if (this._parent == null) {
|
|
414
|
+
return [];
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return this._parent.getTokensAfter(this);
|
|
224
418
|
}
|
|
225
419
|
|
|
226
420
|
getPatterns(): Pattern[] {
|
|
227
|
-
|
|
421
|
+
return this.unaryPatterns.map(p => p.getPatterns()).flat();
|
|
228
422
|
}
|
|
229
423
|
|
|
230
424
|
getPatternsAfter(childReference: Pattern): Pattern[] {
|
|
231
|
-
|
|
425
|
+
if (this.unaryPatterns.indexOf(childReference)) {
|
|
426
|
+
const recursivePatterns = this._recursivePatterns.map(p => p.getPatterns()).flat();
|
|
427
|
+
const binaryPatterns = this._binaryPatterns.map(p => p.getPatterns()).flat();
|
|
428
|
+
|
|
429
|
+
return [...recursivePatterns, ...binaryPatterns];
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (this.recursivePatterns.indexOf(childReference)) {
|
|
433
|
+
return this._binaryPatterns.map(p => p.getPatterns()).flat();
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (this.binaryPatterns.indexOf(childReference)) {
|
|
437
|
+
const unaryPatterns = this._unaryPatterns.map(p => p.getPatterns()).flat();
|
|
438
|
+
|
|
439
|
+
if (this._parent != null) {
|
|
440
|
+
const nextPatterns = this._parent.getPatternsAfter(this);
|
|
441
|
+
return [...unaryPatterns, ...nextPatterns];
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return unaryPatterns;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return [];
|
|
232
448
|
}
|
|
233
449
|
|
|
234
450
|
getNextPatterns(): Pattern[] {
|
|
235
|
-
|
|
451
|
+
if (this._parent == null) {
|
|
452
|
+
return [];
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
return this._parent.getPatternsAfter(this);
|
|
236
456
|
}
|
|
237
457
|
|
|
238
|
-
find(predicate: (
|
|
239
|
-
|
|
458
|
+
find(predicate: (p: Pattern) => boolean): Pattern | null {
|
|
459
|
+
return findPattern(this, predicate);
|
|
240
460
|
}
|
|
241
461
|
|
|
242
|
-
|
|
243
|
-
|
|
462
|
+
clone(name = this._name): Pattern {
|
|
463
|
+
const clone = new ExpressionPattern(name, this._originalPatterns);
|
|
464
|
+
clone._id = this._id;
|
|
465
|
+
return clone;
|
|
244
466
|
}
|
|
245
|
-
|
|
467
|
+
|
|
468
|
+
isEqual(pattern: ExpressionPattern): boolean {
|
|
469
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
470
|
+
}
|
|
471
|
+
}
|
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[] {
|