clarity-pattern-parser 5.0.0 → 6.0.2
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/README.md +328 -38
- package/TODO.md +63 -7
- package/dist/ast/Node.d.ts +8 -2
- package/dist/index.browser.js +520 -205
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.esm.js +519 -206
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +520 -205
- package/dist/index.js.map +1 -1
- package/dist/intellisense/AutoComplete.d.ts +34 -0
- package/dist/intellisense/Suggestion.d.ts +10 -0
- package/dist/intellisense/SuggestionOption.d.ts +4 -0
- package/dist/patterns/And.d.ts +8 -7
- package/dist/patterns/Cursor.d.ts +6 -4
- package/dist/patterns/CursorHistory.d.ts +2 -2
- package/dist/patterns/Literal.d.ts +8 -8
- package/dist/patterns/Not.d.ts +9 -5
- package/dist/patterns/Or.d.ts +8 -5
- package/dist/patterns/Pattern.d.ts +8 -4
- package/dist/patterns/Reference.d.ts +11 -7
- package/dist/patterns/Regex.d.ts +8 -8
- package/dist/patterns/Repeat.d.ts +8 -7
- package/package.json +1 -1
- package/src/ast/Node.test.ts +116 -0
- package/src/ast/Node.ts +71 -5
- package/src/index.ts +14 -3
- package/src/intellisense/AutoComplete.test.ts +168 -23
- package/src/intellisense/AutoComplete.ts +102 -21
- package/src/intellisense/Suggestion.ts +3 -4
- package/src/intellisense/javascript/Javascript.test.ts +86 -62
- package/src/intellisense/javascript/{expressionStatement.ts → assignment.ts} +7 -8
- package/src/intellisense/javascript/escapedCharacter.ts +0 -1
- package/src/intellisense/javascript/exponent.ts +0 -2
- package/src/intellisense/javascript/expression.ts +44 -26
- package/src/intellisense/javascript/fraction.ts +0 -2
- package/src/intellisense/javascript/infixOperator.ts +6 -2
- package/src/intellisense/javascript/keywords.ts +3 -0
- package/src/intellisense/javascript/objectAccess.ts +9 -0
- package/src/intellisense/javascript/objectLiteral.ts +3 -3
- package/src/intellisense/javascript/propertyAccess.ts +8 -3
- package/src/intellisense/javascript/stringLiteral.ts +16 -8
- package/src/patterns/And.test.ts +74 -50
- package/src/patterns/And.ts +72 -36
- package/src/patterns/Cursor.ts +17 -14
- package/src/patterns/CursorHistory.ts +8 -8
- package/src/patterns/Literal.test.ts +79 -38
- package/src/patterns/Literal.ts +34 -41
- package/src/patterns/Not.test.ts +99 -8
- package/src/patterns/Not.ts +58 -14
- package/src/patterns/Or.test.ts +128 -13
- package/src/patterns/Or.ts +46 -13
- package/src/patterns/Pattern.ts +8 -4
- package/src/patterns/Reference.test.ts +127 -28
- package/src/patterns/Reference.ts +62 -32
- package/src/patterns/Regex.test.ts +76 -35
- package/src/patterns/Regex.ts +35 -43
- package/src/patterns/Repeat.test.ts +72 -41
- package/src/patterns/Repeat.ts +55 -38
- package/src/patterns/getNextPattern.test.ts +0 -39
- package/src/patterns/getNextPattern.ts +0 -18
package/dist/index.browser.js
CHANGED
|
@@ -29,6 +29,9 @@
|
|
|
29
29
|
get children() {
|
|
30
30
|
return this._children;
|
|
31
31
|
}
|
|
32
|
+
get hasChildren() {
|
|
33
|
+
return this._children.length > 0;
|
|
34
|
+
}
|
|
32
35
|
get value() {
|
|
33
36
|
return this.toString();
|
|
34
37
|
}
|
|
@@ -78,22 +81,54 @@
|
|
|
78
81
|
}
|
|
79
82
|
spliceChildren(index, deleteCount, ...items) {
|
|
80
83
|
const removedItems = this._children.splice(index, deleteCount, ...items);
|
|
81
|
-
items.forEach(i => i._parent = this);
|
|
82
84
|
removedItems.forEach(i => i._parent = null);
|
|
85
|
+
items.forEach(i => i._parent = this);
|
|
83
86
|
return removedItems;
|
|
84
87
|
}
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
nextSibling() {
|
|
89
|
+
if (this._parent == null) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
const children = this._parent._children;
|
|
93
|
+
const index = children.indexOf(this);
|
|
94
|
+
if (index > -1 && index < children.length - 1) {
|
|
95
|
+
return children[index + 1];
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
87
98
|
}
|
|
88
|
-
|
|
99
|
+
previousSibling() {
|
|
100
|
+
if (this._parent == null) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const children = this._parent._children;
|
|
104
|
+
const index = children.indexOf(this);
|
|
105
|
+
if (index > -1 && index > 0) {
|
|
106
|
+
return children[index - 1];
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
find(predicate) {
|
|
111
|
+
return this.findAll(predicate)[0] || null;
|
|
112
|
+
}
|
|
113
|
+
findAll(predicate) {
|
|
89
114
|
const matches = [];
|
|
90
115
|
this.walkUp(n => {
|
|
91
|
-
if (
|
|
116
|
+
if (predicate(n)) {
|
|
92
117
|
matches.push(n);
|
|
93
118
|
}
|
|
94
119
|
});
|
|
95
120
|
return matches;
|
|
96
121
|
}
|
|
122
|
+
findAncester(predicate) {
|
|
123
|
+
let parent = this._parent;
|
|
124
|
+
while (parent != null) {
|
|
125
|
+
if (predicate(parent)) {
|
|
126
|
+
return parent;
|
|
127
|
+
}
|
|
128
|
+
parent = parent._parent;
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
97
132
|
walkUp(callback) {
|
|
98
133
|
this.children.forEach(c => c.walkUp(callback));
|
|
99
134
|
callback(this);
|
|
@@ -102,6 +137,20 @@
|
|
|
102
137
|
callback(this);
|
|
103
138
|
this.children.forEach(c => c.walkDown(callback));
|
|
104
139
|
}
|
|
140
|
+
flatten() {
|
|
141
|
+
const nodes = [];
|
|
142
|
+
this.walkDown((node) => {
|
|
143
|
+
if (!node.hasChildren) {
|
|
144
|
+
nodes.push(node);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
return nodes;
|
|
148
|
+
}
|
|
149
|
+
reduce() {
|
|
150
|
+
const value = this.toString();
|
|
151
|
+
this.removeAllChildren();
|
|
152
|
+
this._value = value;
|
|
153
|
+
}
|
|
105
154
|
clone() {
|
|
106
155
|
return new Node(this._type, this._name, this._firstIndex, this._lastIndex, this._children.map((c) => c.clone()), this._value);
|
|
107
156
|
}
|
|
@@ -146,15 +195,18 @@
|
|
|
146
195
|
this._nodes = [];
|
|
147
196
|
this._errors = [];
|
|
148
197
|
}
|
|
198
|
+
get isRecording() {
|
|
199
|
+
return this._isRecording;
|
|
200
|
+
}
|
|
201
|
+
get rootMatch() {
|
|
202
|
+
return this._rootMatch;
|
|
203
|
+
}
|
|
149
204
|
get leafMatch() {
|
|
150
205
|
return this._leafMatch;
|
|
151
206
|
}
|
|
152
207
|
get furthestError() {
|
|
153
208
|
return this._furthestError;
|
|
154
209
|
}
|
|
155
|
-
get isRecording() {
|
|
156
|
-
return this._isRecording;
|
|
157
|
-
}
|
|
158
210
|
get errors() {
|
|
159
211
|
return this._errors;
|
|
160
212
|
}
|
|
@@ -167,9 +219,6 @@
|
|
|
167
219
|
get patterns() {
|
|
168
220
|
return this._patterns;
|
|
169
221
|
}
|
|
170
|
-
get rootMatch() {
|
|
171
|
-
return this._rootMatch;
|
|
172
|
-
}
|
|
173
222
|
recordMatch(pattern, node) {
|
|
174
223
|
if (this._isRecording) {
|
|
175
224
|
this._patterns.push(pattern);
|
|
@@ -212,17 +261,17 @@
|
|
|
212
261
|
return this._index === 0;
|
|
213
262
|
}
|
|
214
263
|
get isOnLast() {
|
|
215
|
-
return this._index === this.
|
|
264
|
+
return this._index === this.getLastIndex();
|
|
216
265
|
}
|
|
217
266
|
get isRecording() {
|
|
218
267
|
return this._history.isRecording;
|
|
219
268
|
}
|
|
220
|
-
get leafMatch() {
|
|
221
|
-
return this._history.leafMatch;
|
|
222
|
-
}
|
|
223
269
|
get rootMatch() {
|
|
224
270
|
return this._history.rootMatch;
|
|
225
271
|
}
|
|
272
|
+
get leafMatch() {
|
|
273
|
+
return this._history.leafMatch;
|
|
274
|
+
}
|
|
226
275
|
get furthestError() {
|
|
227
276
|
return this._history.furthestError;
|
|
228
277
|
}
|
|
@@ -253,14 +302,14 @@
|
|
|
253
302
|
hasNext() {
|
|
254
303
|
return this._index + 1 < this._length;
|
|
255
304
|
}
|
|
256
|
-
hasPrevious() {
|
|
257
|
-
return this._index - 1 >= 0;
|
|
258
|
-
}
|
|
259
305
|
next() {
|
|
260
306
|
if (this.hasNext()) {
|
|
261
307
|
this._index++;
|
|
262
308
|
}
|
|
263
309
|
}
|
|
310
|
+
hasPrevious() {
|
|
311
|
+
return this._index - 1 >= 0;
|
|
312
|
+
}
|
|
264
313
|
previous() {
|
|
265
314
|
if (this.hasPrevious()) {
|
|
266
315
|
this._index--;
|
|
@@ -275,7 +324,10 @@
|
|
|
275
324
|
this._index = 0;
|
|
276
325
|
}
|
|
277
326
|
moveToLastChar() {
|
|
278
|
-
this._index = this.
|
|
327
|
+
this._index = this.getLastIndex();
|
|
328
|
+
}
|
|
329
|
+
getLastIndex() {
|
|
330
|
+
return this._length - 1;
|
|
279
331
|
}
|
|
280
332
|
getChars(first, last) {
|
|
281
333
|
return this._text.slice(first, last + 1);
|
|
@@ -295,22 +347,6 @@
|
|
|
295
347
|
stopRecording() {
|
|
296
348
|
this._history.stopRecording();
|
|
297
349
|
}
|
|
298
|
-
_getLastIndex() {
|
|
299
|
-
return this._length - 1;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
function getNextPattern(pattern) {
|
|
304
|
-
const parent = pattern.parent;
|
|
305
|
-
if (parent == null) {
|
|
306
|
-
return null;
|
|
307
|
-
}
|
|
308
|
-
const patternIndex = parent.children.indexOf(pattern);
|
|
309
|
-
const nextPattern = parent.children[patternIndex + 1] || null;
|
|
310
|
-
if (nextPattern == null) {
|
|
311
|
-
return parent.getNextPattern();
|
|
312
|
-
}
|
|
313
|
-
return nextPattern;
|
|
314
350
|
}
|
|
315
351
|
|
|
316
352
|
class Regex {
|
|
@@ -337,8 +373,6 @@
|
|
|
337
373
|
this._cursor = null;
|
|
338
374
|
this._substring = "";
|
|
339
375
|
this._tokens = [];
|
|
340
|
-
this._hasContextualTokenAggregation = false;
|
|
341
|
-
this._isRetrievingContextualTokens = false;
|
|
342
376
|
this._type = "regex";
|
|
343
377
|
this._name = name;
|
|
344
378
|
this._isOptional = isOptional;
|
|
@@ -358,11 +392,16 @@
|
|
|
358
392
|
throw new Error("Invalid Arguments: The regex string cannot end with a '$' because it is expected to be in the middle of a string.");
|
|
359
393
|
}
|
|
360
394
|
}
|
|
361
|
-
|
|
395
|
+
test(text) {
|
|
396
|
+
const cursor = new Cursor(text);
|
|
397
|
+
const ast = this.parse(cursor);
|
|
398
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
399
|
+
}
|
|
400
|
+
exec(text) {
|
|
362
401
|
const cursor = new Cursor(text);
|
|
363
402
|
const ast = this.parse(cursor);
|
|
364
403
|
return {
|
|
365
|
-
ast,
|
|
404
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
366
405
|
cursor
|
|
367
406
|
};
|
|
368
407
|
}
|
|
@@ -389,7 +428,7 @@
|
|
|
389
428
|
processResult(cursor, result) {
|
|
390
429
|
const currentIndex = cursor.index;
|
|
391
430
|
const newIndex = currentIndex + result[0].length - 1;
|
|
392
|
-
this._node = new Node("regex", this._name, currentIndex, newIndex,
|
|
431
|
+
this._node = new Node("regex", this._name, currentIndex, newIndex, undefined, result[0]);
|
|
393
432
|
cursor.moveTo(newIndex);
|
|
394
433
|
cursor.recordMatch(this, this._node);
|
|
395
434
|
}
|
|
@@ -402,47 +441,38 @@
|
|
|
402
441
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
403
442
|
const pattern = new Regex(name, this._originalRegexString, isOptional);
|
|
404
443
|
pattern._tokens = this._tokens.slice();
|
|
405
|
-
pattern._hasContextualTokenAggregation =
|
|
406
|
-
this._hasContextualTokenAggregation;
|
|
407
444
|
return pattern;
|
|
408
445
|
}
|
|
409
446
|
getTokens() {
|
|
410
|
-
const parent = this._parent;
|
|
411
|
-
if (this._hasContextualTokenAggregation &&
|
|
412
|
-
parent != null &&
|
|
413
|
-
!this._isRetrievingContextualTokens) {
|
|
414
|
-
this._isRetrievingContextualTokens = true;
|
|
415
|
-
const tokens = this._tokens;
|
|
416
|
-
const aggregateTokens = [];
|
|
417
|
-
const nextTokens = parent.getNextTokens(this);
|
|
418
|
-
for (let nextToken of nextTokens) {
|
|
419
|
-
for (let token of tokens) {
|
|
420
|
-
aggregateTokens.push(token + nextToken);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
this._isRetrievingContextualTokens = false;
|
|
424
|
-
return aggregateTokens;
|
|
425
|
-
}
|
|
426
447
|
return this._tokens;
|
|
427
448
|
}
|
|
428
|
-
|
|
449
|
+
getTokensAfter(_childReference) {
|
|
429
450
|
return [];
|
|
430
451
|
}
|
|
431
|
-
|
|
432
|
-
|
|
452
|
+
getNextTokens() {
|
|
453
|
+
if (this.parent == null) {
|
|
454
|
+
return [];
|
|
455
|
+
}
|
|
456
|
+
return this.parent.getTokensAfter(this);
|
|
457
|
+
}
|
|
458
|
+
getPatterns() {
|
|
459
|
+
return [this];
|
|
433
460
|
}
|
|
434
|
-
|
|
461
|
+
getPatternsAfter(_childReference) {
|
|
462
|
+
return [];
|
|
463
|
+
}
|
|
464
|
+
getNextPatterns() {
|
|
465
|
+
if (this.parent == null) {
|
|
466
|
+
return [];
|
|
467
|
+
}
|
|
468
|
+
return this.parent.getPatternsAfter(this);
|
|
469
|
+
}
|
|
470
|
+
findPattern(_predicate) {
|
|
435
471
|
return null;
|
|
436
472
|
}
|
|
437
473
|
setTokens(tokens) {
|
|
438
474
|
this._tokens = tokens;
|
|
439
475
|
}
|
|
440
|
-
enableContextualTokenAggregation() {
|
|
441
|
-
this._hasContextualTokenAggregation = true;
|
|
442
|
-
}
|
|
443
|
-
disableContextualTokenAggregation() {
|
|
444
|
-
this._hasContextualTokenAggregation = false;
|
|
445
|
-
}
|
|
446
476
|
}
|
|
447
477
|
|
|
448
478
|
function clonePatterns(patterns, isOptional) {
|
|
@@ -512,7 +542,6 @@
|
|
|
512
542
|
this._parent = null;
|
|
513
543
|
this._children = children;
|
|
514
544
|
this._firstIndex = -1;
|
|
515
|
-
this._shouldReduceAst = false;
|
|
516
545
|
this._nodes = [];
|
|
517
546
|
}
|
|
518
547
|
_assignChildrenToParent(children) {
|
|
@@ -520,11 +549,16 @@
|
|
|
520
549
|
child.parent = this;
|
|
521
550
|
}
|
|
522
551
|
}
|
|
523
|
-
|
|
552
|
+
test(text) {
|
|
553
|
+
const cursor = new Cursor(text);
|
|
554
|
+
const ast = this.parse(cursor);
|
|
555
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
556
|
+
}
|
|
557
|
+
exec(text) {
|
|
524
558
|
const cursor = new Cursor(text);
|
|
525
559
|
const ast = this.parse(cursor);
|
|
526
560
|
return {
|
|
527
|
-
ast,
|
|
561
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
528
562
|
cursor
|
|
529
563
|
};
|
|
530
564
|
}
|
|
@@ -558,34 +592,43 @@
|
|
|
558
592
|
if (hasMorePatterns) {
|
|
559
593
|
if (hadMatch) {
|
|
560
594
|
if (cursor.hasNext()) {
|
|
595
|
+
// We had a match. Increment the cursor and use the next pattern.
|
|
561
596
|
cursor.next();
|
|
562
597
|
continue;
|
|
563
598
|
}
|
|
564
599
|
else {
|
|
600
|
+
// We are at the end of the text, it may still be valid, if all the
|
|
601
|
+
// following patterns are optional.
|
|
565
602
|
if (this.areRemainingPatternsOptional(i)) {
|
|
566
603
|
passed = true;
|
|
567
604
|
break;
|
|
568
605
|
}
|
|
606
|
+
// We didn't finish the parsing sequence.
|
|
569
607
|
cursor.recordErrorAt(cursor.index + 1, this);
|
|
570
608
|
break;
|
|
571
609
|
}
|
|
572
610
|
}
|
|
573
611
|
else {
|
|
612
|
+
// An optional pattern did not matched, try from the same spot on the next
|
|
613
|
+
// pattern.
|
|
574
614
|
cursor.moveTo(runningCursorIndex);
|
|
575
615
|
continue;
|
|
576
616
|
}
|
|
577
617
|
}
|
|
578
618
|
else {
|
|
619
|
+
// If we don't have any results from what we parsed then record error.
|
|
579
620
|
const lastNode = this.getLastValidNode();
|
|
580
621
|
if (lastNode === null) {
|
|
581
622
|
cursor.recordErrorAt(cursor.index, this);
|
|
582
623
|
break;
|
|
583
624
|
}
|
|
625
|
+
// The sequence was parsed fully.
|
|
584
626
|
passed = true;
|
|
585
627
|
break;
|
|
586
628
|
}
|
|
587
629
|
}
|
|
588
630
|
else {
|
|
631
|
+
// The pattern failed.
|
|
589
632
|
cursor.moveTo(this._firstIndex);
|
|
590
633
|
break;
|
|
591
634
|
}
|
|
@@ -613,18 +656,9 @@
|
|
|
613
656
|
createNode(cursor) {
|
|
614
657
|
const children = filterOutNull(this._nodes);
|
|
615
658
|
const lastIndex = children[children.length - 1].lastIndex;
|
|
616
|
-
|
|
659
|
+
cursor.getChars(this._firstIndex, lastIndex);
|
|
617
660
|
cursor.moveTo(lastIndex);
|
|
618
|
-
|
|
619
|
-
children.length = 0;
|
|
620
|
-
}
|
|
621
|
-
return new Node("and", this._name, this._firstIndex, lastIndex, children, this._shouldReduceAst ? value : undefined);
|
|
622
|
-
}
|
|
623
|
-
enableAstReduction() {
|
|
624
|
-
this._shouldReduceAst = true;
|
|
625
|
-
}
|
|
626
|
-
disableAstReduction() {
|
|
627
|
-
this._shouldReduceAst = false;
|
|
661
|
+
return new Node("and", this._name, this._firstIndex, lastIndex, children);
|
|
628
662
|
}
|
|
629
663
|
getTokens() {
|
|
630
664
|
const tokens = [];
|
|
@@ -636,13 +670,35 @@
|
|
|
636
670
|
}
|
|
637
671
|
return tokens;
|
|
638
672
|
}
|
|
639
|
-
|
|
673
|
+
getTokensAfter(childReference) {
|
|
674
|
+
const patterns = this.getPatternsAfter(childReference);
|
|
675
|
+
const tokens = [];
|
|
676
|
+
patterns.forEach(p => tokens.push(...p.getTokens()));
|
|
677
|
+
return tokens;
|
|
678
|
+
}
|
|
679
|
+
getNextTokens() {
|
|
680
|
+
if (this.parent == null) {
|
|
681
|
+
return [];
|
|
682
|
+
}
|
|
683
|
+
return this.parent.getTokensAfter(this);
|
|
684
|
+
}
|
|
685
|
+
getPatterns() {
|
|
686
|
+
const patterns = [];
|
|
687
|
+
for (const pattern of this._children) {
|
|
688
|
+
patterns.push(...pattern.getPatterns());
|
|
689
|
+
if (!pattern.isOptional) {
|
|
690
|
+
break;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return patterns;
|
|
694
|
+
}
|
|
695
|
+
getPatternsAfter(childReference) {
|
|
640
696
|
let nextSibling = null;
|
|
641
697
|
let nextSiblingIndex = -1;
|
|
642
698
|
let index = -1;
|
|
643
|
-
const
|
|
699
|
+
const patterns = [];
|
|
644
700
|
for (let i = 0; i < this._children.length; i++) {
|
|
645
|
-
if (this._children[i] ===
|
|
701
|
+
if (this._children[i] === childReference) {
|
|
646
702
|
if (i + 1 < this._children.length) {
|
|
647
703
|
nextSibling = this._children[i + 1];
|
|
648
704
|
}
|
|
@@ -651,39 +707,44 @@
|
|
|
651
707
|
break;
|
|
652
708
|
}
|
|
653
709
|
}
|
|
710
|
+
// The child reference isn't one of the child patterns.
|
|
654
711
|
if (index === -1) {
|
|
655
712
|
return [];
|
|
656
713
|
}
|
|
714
|
+
// The reference pattern is the last child. So ask the parent for the next pattern.
|
|
657
715
|
if (nextSiblingIndex === this._children.length && this._parent !== null) {
|
|
658
|
-
return this._parent.
|
|
716
|
+
return this._parent.getPatternsAfter(this);
|
|
659
717
|
}
|
|
718
|
+
// Next pattern isn't optional so send it back as the next patterns.
|
|
660
719
|
if (nextSibling !== null && !nextSibling.isOptional) {
|
|
661
|
-
return nextSibling
|
|
720
|
+
return [nextSibling];
|
|
662
721
|
}
|
|
722
|
+
// Send back as many optional patterns as possible.
|
|
663
723
|
if (nextSibling !== null && nextSibling.isOptional) {
|
|
664
724
|
for (let i = nextSiblingIndex; i < this._children.length; i++) {
|
|
665
725
|
const child = this._children[i];
|
|
666
|
-
|
|
726
|
+
patterns.push(child);
|
|
667
727
|
if (!child.isOptional) {
|
|
668
728
|
break;
|
|
669
729
|
}
|
|
670
730
|
if (i === this._children.length - 1 && this._parent !== null) {
|
|
671
|
-
|
|
731
|
+
patterns.push(...this._parent.getPatternsAfter(this));
|
|
672
732
|
}
|
|
673
733
|
}
|
|
674
734
|
}
|
|
675
|
-
return
|
|
735
|
+
return patterns;
|
|
676
736
|
}
|
|
677
|
-
|
|
678
|
-
|
|
737
|
+
getNextPatterns() {
|
|
738
|
+
if (this.parent == null) {
|
|
739
|
+
return [];
|
|
740
|
+
}
|
|
741
|
+
return this.parent.getPatternsAfter(this);
|
|
679
742
|
}
|
|
680
|
-
findPattern(
|
|
681
|
-
return findPattern(this,
|
|
743
|
+
findPattern(predicate) {
|
|
744
|
+
return findPattern(this, predicate);
|
|
682
745
|
}
|
|
683
746
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
684
|
-
|
|
685
|
-
and._shouldReduceAst = this._shouldReduceAst;
|
|
686
|
-
return and;
|
|
747
|
+
return new And(name, this._children, isOptional);
|
|
687
748
|
}
|
|
688
749
|
}
|
|
689
750
|
|
|
@@ -718,14 +779,17 @@
|
|
|
718
779
|
this._parent = null;
|
|
719
780
|
this._firstIndex = 0;
|
|
720
781
|
this._lastIndex = 0;
|
|
721
|
-
this._hasContextualTokenAggregation = false;
|
|
722
|
-
this._isRetrievingContextualTokens = false;
|
|
723
782
|
}
|
|
724
|
-
|
|
783
|
+
test(text) {
|
|
784
|
+
const cursor = new Cursor(text);
|
|
785
|
+
const ast = this.parse(cursor);
|
|
786
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
787
|
+
}
|
|
788
|
+
exec(text) {
|
|
725
789
|
const cursor = new Cursor(text);
|
|
726
790
|
const ast = this.parse(cursor);
|
|
727
791
|
return {
|
|
728
|
-
ast,
|
|
792
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
729
793
|
cursor
|
|
730
794
|
};
|
|
731
795
|
}
|
|
@@ -768,45 +832,38 @@
|
|
|
768
832
|
return passed;
|
|
769
833
|
}
|
|
770
834
|
_createNode() {
|
|
771
|
-
return new Node("literal", this._name, this._firstIndex, this._lastIndex,
|
|
835
|
+
return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this._literal);
|
|
772
836
|
}
|
|
773
837
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
774
838
|
const clone = new Literal(name, this._literal, isOptional);
|
|
775
|
-
clone._hasContextualTokenAggregation = this._hasContextualTokenAggregation;
|
|
776
839
|
return clone;
|
|
777
840
|
}
|
|
778
841
|
getTokens() {
|
|
779
|
-
|
|
780
|
-
if (this._hasContextualTokenAggregation &&
|
|
781
|
-
parent != null &&
|
|
782
|
-
!this._isRetrievingContextualTokens) {
|
|
783
|
-
this._isRetrievingContextualTokens = true;
|
|
784
|
-
const aggregateTokens = [];
|
|
785
|
-
const nextTokens = parent.getNextTokens(this);
|
|
786
|
-
for (const nextToken of nextTokens) {
|
|
787
|
-
aggregateTokens.push(this._literal + nextToken);
|
|
788
|
-
}
|
|
789
|
-
this._isRetrievingContextualTokens = false;
|
|
790
|
-
return aggregateTokens;
|
|
791
|
-
}
|
|
792
|
-
else {
|
|
793
|
-
return [this._literal];
|
|
794
|
-
}
|
|
842
|
+
return [this._literal];
|
|
795
843
|
}
|
|
796
|
-
|
|
844
|
+
getTokensAfter(_lastMatched) {
|
|
797
845
|
return [];
|
|
798
846
|
}
|
|
799
|
-
|
|
800
|
-
|
|
847
|
+
getNextTokens() {
|
|
848
|
+
if (this.parent == null) {
|
|
849
|
+
return [];
|
|
850
|
+
}
|
|
851
|
+
return this.parent.getTokensAfter(this);
|
|
801
852
|
}
|
|
802
|
-
|
|
803
|
-
return
|
|
853
|
+
getPatterns() {
|
|
854
|
+
return [this];
|
|
855
|
+
}
|
|
856
|
+
getPatternsAfter() {
|
|
857
|
+
return [];
|
|
804
858
|
}
|
|
805
|
-
|
|
806
|
-
this.
|
|
859
|
+
getNextPatterns() {
|
|
860
|
+
if (this.parent == null) {
|
|
861
|
+
return [];
|
|
862
|
+
}
|
|
863
|
+
return this.parent.getPatternsAfter(this);
|
|
807
864
|
}
|
|
808
|
-
|
|
809
|
-
|
|
865
|
+
findPattern(_predicate) {
|
|
866
|
+
return null;
|
|
810
867
|
}
|
|
811
868
|
}
|
|
812
869
|
|
|
@@ -817,9 +874,6 @@
|
|
|
817
874
|
get name() {
|
|
818
875
|
return this._name;
|
|
819
876
|
}
|
|
820
|
-
get isOptional() {
|
|
821
|
-
return false;
|
|
822
|
-
}
|
|
823
877
|
get parent() {
|
|
824
878
|
return this._parent;
|
|
825
879
|
}
|
|
@@ -829,6 +883,9 @@
|
|
|
829
883
|
get children() {
|
|
830
884
|
return this._children;
|
|
831
885
|
}
|
|
886
|
+
get isOptional() {
|
|
887
|
+
return false;
|
|
888
|
+
}
|
|
832
889
|
constructor(name, pattern) {
|
|
833
890
|
this._type = "not";
|
|
834
891
|
this._name = name;
|
|
@@ -836,7 +893,12 @@
|
|
|
836
893
|
this._children = [pattern.clone(pattern.name, false)];
|
|
837
894
|
this._children[0].parent = this;
|
|
838
895
|
}
|
|
839
|
-
|
|
896
|
+
test(text) {
|
|
897
|
+
const cursor = new Cursor(text);
|
|
898
|
+
this.parse(cursor);
|
|
899
|
+
return !cursor.hasError;
|
|
900
|
+
}
|
|
901
|
+
exec(text) {
|
|
840
902
|
const cursor = new Cursor(text);
|
|
841
903
|
const ast = this.parse(cursor);
|
|
842
904
|
return {
|
|
@@ -862,17 +924,44 @@
|
|
|
862
924
|
const not = new Not(name, this._children[0]);
|
|
863
925
|
return not;
|
|
864
926
|
}
|
|
865
|
-
getNextPattern() {
|
|
866
|
-
return getNextPattern(this);
|
|
867
|
-
}
|
|
868
927
|
getTokens() {
|
|
928
|
+
const parent = this._parent;
|
|
929
|
+
if (parent != null) {
|
|
930
|
+
return parent.getTokensAfter(this);
|
|
931
|
+
}
|
|
932
|
+
return [];
|
|
933
|
+
}
|
|
934
|
+
getTokensAfter(_childReference) {
|
|
935
|
+
const parent = this._parent;
|
|
936
|
+
if (parent != null) {
|
|
937
|
+
return parent.getTokensAfter(this);
|
|
938
|
+
}
|
|
869
939
|
return [];
|
|
870
940
|
}
|
|
871
|
-
getNextTokens(
|
|
941
|
+
getNextTokens() {
|
|
942
|
+
if (this.parent == null) {
|
|
943
|
+
return [];
|
|
944
|
+
}
|
|
945
|
+
return this.parent.getTokensAfter(this);
|
|
946
|
+
}
|
|
947
|
+
getPatterns() {
|
|
948
|
+
return [...this.getNextPatterns().map(p => p.getPatterns()).flat()];
|
|
949
|
+
}
|
|
950
|
+
getPatternsAfter(_childReference) {
|
|
951
|
+
const parent = this._parent;
|
|
952
|
+
if (parent != null) {
|
|
953
|
+
return parent.getPatternsAfter(this);
|
|
954
|
+
}
|
|
872
955
|
return [];
|
|
873
956
|
}
|
|
874
|
-
|
|
875
|
-
|
|
957
|
+
getNextPatterns() {
|
|
958
|
+
if (this.parent == null) {
|
|
959
|
+
return [];
|
|
960
|
+
}
|
|
961
|
+
return this.parent.getPatternsAfter(this);
|
|
962
|
+
}
|
|
963
|
+
findPattern(predicate) {
|
|
964
|
+
return predicate(this._children[0]) ? this._children[0] : null;
|
|
876
965
|
}
|
|
877
966
|
}
|
|
878
967
|
|
|
@@ -906,7 +995,6 @@
|
|
|
906
995
|
this._parent = null;
|
|
907
996
|
this._children = children;
|
|
908
997
|
this._isOptional = isOptional;
|
|
909
|
-
this._node = null;
|
|
910
998
|
this._firstIndex = 0;
|
|
911
999
|
}
|
|
912
1000
|
_assignChildrenToParent(children) {
|
|
@@ -914,17 +1002,21 @@
|
|
|
914
1002
|
child.parent = this;
|
|
915
1003
|
}
|
|
916
1004
|
}
|
|
917
|
-
|
|
1005
|
+
test(text) {
|
|
1006
|
+
const cursor = new Cursor(text);
|
|
1007
|
+
const ast = this.parse(cursor);
|
|
1008
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1009
|
+
}
|
|
1010
|
+
exec(text) {
|
|
918
1011
|
const cursor = new Cursor(text);
|
|
919
1012
|
const ast = this.parse(cursor);
|
|
920
1013
|
return {
|
|
921
|
-
ast,
|
|
1014
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
922
1015
|
cursor
|
|
923
1016
|
};
|
|
924
1017
|
}
|
|
925
1018
|
parse(cursor) {
|
|
926
1019
|
this._firstIndex = cursor.index;
|
|
927
|
-
this._node = null;
|
|
928
1020
|
const node = this._tryToParse(cursor);
|
|
929
1021
|
if (node != null) {
|
|
930
1022
|
cursor.resolveError();
|
|
@@ -956,17 +1048,39 @@
|
|
|
956
1048
|
}
|
|
957
1049
|
return tokens;
|
|
958
1050
|
}
|
|
959
|
-
|
|
1051
|
+
getTokensAfter(_childReference) {
|
|
1052
|
+
if (this._parent === null) {
|
|
1053
|
+
return [];
|
|
1054
|
+
}
|
|
1055
|
+
return this._parent.getTokensAfter(this);
|
|
1056
|
+
}
|
|
1057
|
+
getNextTokens() {
|
|
1058
|
+
if (this._parent == null) {
|
|
1059
|
+
return [];
|
|
1060
|
+
}
|
|
1061
|
+
return this._parent.getTokensAfter(this);
|
|
1062
|
+
}
|
|
1063
|
+
getPatterns() {
|
|
1064
|
+
const patterns = [];
|
|
1065
|
+
for (const pattern of this._children) {
|
|
1066
|
+
patterns.push(...pattern.getPatterns());
|
|
1067
|
+
}
|
|
1068
|
+
return patterns;
|
|
1069
|
+
}
|
|
1070
|
+
getPatternsAfter(_childReference) {
|
|
960
1071
|
if (this._parent === null) {
|
|
961
1072
|
return [];
|
|
962
1073
|
}
|
|
963
|
-
return this._parent.
|
|
1074
|
+
return this._parent.getPatternsAfter(this);
|
|
964
1075
|
}
|
|
965
|
-
|
|
966
|
-
|
|
1076
|
+
getNextPatterns() {
|
|
1077
|
+
if (this.parent == null) {
|
|
1078
|
+
return [];
|
|
1079
|
+
}
|
|
1080
|
+
return this.parent.getPatternsAfter(this);
|
|
967
1081
|
}
|
|
968
|
-
findPattern(
|
|
969
|
-
return findPattern(this,
|
|
1082
|
+
findPattern(predicate) {
|
|
1083
|
+
return findPattern(this, predicate);
|
|
970
1084
|
}
|
|
971
1085
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
972
1086
|
const or = new Or(name, this._children, isOptional);
|
|
@@ -1005,7 +1119,6 @@
|
|
|
1005
1119
|
this._pattern = children[0];
|
|
1006
1120
|
this._divider = children[1];
|
|
1007
1121
|
this._firstIndex = -1;
|
|
1008
|
-
this._shouldReduceAst = false;
|
|
1009
1122
|
this._nodes = [];
|
|
1010
1123
|
}
|
|
1011
1124
|
_assignChildrenToParent(children) {
|
|
@@ -1013,11 +1126,16 @@
|
|
|
1013
1126
|
child.parent = this;
|
|
1014
1127
|
}
|
|
1015
1128
|
}
|
|
1016
|
-
|
|
1129
|
+
test(text) {
|
|
1130
|
+
const cursor = new Cursor(text);
|
|
1131
|
+
const ast = this.parse(cursor);
|
|
1132
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1133
|
+
}
|
|
1134
|
+
exec(text) {
|
|
1017
1135
|
const cursor = new Cursor(text);
|
|
1018
1136
|
const ast = this.parse(cursor);
|
|
1019
1137
|
return {
|
|
1020
|
-
ast,
|
|
1138
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
1021
1139
|
cursor
|
|
1022
1140
|
};
|
|
1023
1141
|
}
|
|
@@ -1028,7 +1146,7 @@
|
|
|
1028
1146
|
if (passed) {
|
|
1029
1147
|
cursor.resolveError();
|
|
1030
1148
|
const node = this.createNode(cursor);
|
|
1031
|
-
if (node) {
|
|
1149
|
+
if (node != null) {
|
|
1032
1150
|
cursor.recordMatch(this, node);
|
|
1033
1151
|
}
|
|
1034
1152
|
return node;
|
|
@@ -1047,7 +1165,7 @@
|
|
|
1047
1165
|
const repeatedNode = this._pattern.parse(cursor);
|
|
1048
1166
|
if (cursor.hasError) {
|
|
1049
1167
|
const lastValidNode = this.getLastValidNode();
|
|
1050
|
-
if (lastValidNode) {
|
|
1168
|
+
if (lastValidNode != null) {
|
|
1051
1169
|
passed = true;
|
|
1052
1170
|
}
|
|
1053
1171
|
else {
|
|
@@ -1064,13 +1182,13 @@
|
|
|
1064
1182
|
break;
|
|
1065
1183
|
}
|
|
1066
1184
|
cursor.next();
|
|
1067
|
-
if (this._divider) {
|
|
1185
|
+
if (this._divider != null) {
|
|
1068
1186
|
const dividerNode = this._divider.parse(cursor);
|
|
1069
1187
|
if (cursor.hasError) {
|
|
1070
1188
|
passed = true;
|
|
1071
1189
|
break;
|
|
1072
1190
|
}
|
|
1073
|
-
else if (dividerNode) {
|
|
1191
|
+
else if (dividerNode != null) {
|
|
1074
1192
|
this._nodes.push(dividerNode);
|
|
1075
1193
|
if (!cursor.hasNext()) {
|
|
1076
1194
|
passed = true;
|
|
@@ -1099,12 +1217,9 @@
|
|
|
1099
1217
|
}
|
|
1100
1218
|
}
|
|
1101
1219
|
const lastIndex = children[children.length - 1].lastIndex;
|
|
1102
|
-
|
|
1220
|
+
cursor.getChars(this._firstIndex, lastIndex);
|
|
1103
1221
|
cursor.moveTo(lastIndex);
|
|
1104
|
-
|
|
1105
|
-
children = [];
|
|
1106
|
-
}
|
|
1107
|
-
return new Node("repeat", this._name, this._firstIndex, lastIndex, children, this._shouldReduceAst ? value : undefined);
|
|
1222
|
+
return new Node("repeat", this._name, this._firstIndex, lastIndex, children, undefined);
|
|
1108
1223
|
}
|
|
1109
1224
|
getLastValidNode() {
|
|
1110
1225
|
const nodes = this._nodes.filter((node) => node !== null);
|
|
@@ -1113,51 +1228,64 @@
|
|
|
1113
1228
|
}
|
|
1114
1229
|
return nodes[nodes.length - 1];
|
|
1115
1230
|
}
|
|
1116
|
-
enableAstReduction() {
|
|
1117
|
-
this._shouldReduceAst = true;
|
|
1118
|
-
}
|
|
1119
|
-
disableAstReduction() {
|
|
1120
|
-
this._shouldReduceAst = false;
|
|
1121
|
-
}
|
|
1122
1231
|
getTokens() {
|
|
1123
1232
|
return this._pattern.getTokens();
|
|
1124
1233
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1234
|
+
getTokensAfter(childReference) {
|
|
1235
|
+
const patterns = this.getPatternsAfter(childReference);
|
|
1127
1236
|
const tokens = [];
|
|
1237
|
+
patterns.forEach(p => tokens.push(...p.getTokens()));
|
|
1238
|
+
return tokens;
|
|
1239
|
+
}
|
|
1240
|
+
getNextTokens() {
|
|
1241
|
+
if (this.parent == null) {
|
|
1242
|
+
return [];
|
|
1243
|
+
}
|
|
1244
|
+
return this.parent.getTokensAfter(this);
|
|
1245
|
+
}
|
|
1246
|
+
getPatterns() {
|
|
1247
|
+
return this._pattern.getPatterns();
|
|
1248
|
+
}
|
|
1249
|
+
getPatternsAfter(childReference) {
|
|
1250
|
+
let index = -1;
|
|
1251
|
+
const patterns = [];
|
|
1128
1252
|
for (let i = 0; i < this._children.length; i++) {
|
|
1129
|
-
if (this._children[i] ===
|
|
1253
|
+
if (this._children[i] === childReference) {
|
|
1130
1254
|
index = i;
|
|
1131
1255
|
}
|
|
1132
1256
|
}
|
|
1257
|
+
// If the last match isn't a child of this pattern.
|
|
1133
1258
|
if (index === -1) {
|
|
1134
1259
|
return [];
|
|
1135
1260
|
}
|
|
1261
|
+
// If the last match was the repeated patterns, then suggest the divider.
|
|
1136
1262
|
if (index === 0 && this._divider) {
|
|
1137
|
-
|
|
1263
|
+
patterns.push(this._children[1]);
|
|
1138
1264
|
if (this._parent) {
|
|
1139
|
-
|
|
1265
|
+
patterns.push(...this._parent.getPatternsAfter(this));
|
|
1140
1266
|
}
|
|
1141
1267
|
}
|
|
1268
|
+
// Suggest the pattern because the divider was the last match.
|
|
1142
1269
|
if (index === 1) {
|
|
1143
|
-
|
|
1270
|
+
patterns.push(this._children[0]);
|
|
1144
1271
|
}
|
|
1145
1272
|
if (index === 0 && !this._divider && this._parent) {
|
|
1146
|
-
|
|
1147
|
-
|
|
1273
|
+
patterns.push(this._children[0]);
|
|
1274
|
+
patterns.push(...this._parent.getPatternsAfter(this));
|
|
1148
1275
|
}
|
|
1149
|
-
return
|
|
1276
|
+
return patterns;
|
|
1150
1277
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1278
|
+
getNextPatterns() {
|
|
1279
|
+
if (this.parent == null) {
|
|
1280
|
+
return [];
|
|
1281
|
+
}
|
|
1282
|
+
return this.parent.getPatternsAfter(this);
|
|
1153
1283
|
}
|
|
1154
|
-
findPattern(
|
|
1155
|
-
return findPattern(this,
|
|
1284
|
+
findPattern(predicate) {
|
|
1285
|
+
return findPattern(this, predicate);
|
|
1156
1286
|
}
|
|
1157
1287
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
1158
|
-
|
|
1159
|
-
repeat._shouldReduceAst = this._shouldReduceAst;
|
|
1160
|
-
return repeat;
|
|
1288
|
+
return new Repeat(name, this._pattern, this._divider, isOptional);
|
|
1161
1289
|
}
|
|
1162
1290
|
}
|
|
1163
1291
|
|
|
@@ -1168,9 +1296,6 @@
|
|
|
1168
1296
|
get name() {
|
|
1169
1297
|
return this._name;
|
|
1170
1298
|
}
|
|
1171
|
-
get isOptional() {
|
|
1172
|
-
return this._isOptional;
|
|
1173
|
-
}
|
|
1174
1299
|
get parent() {
|
|
1175
1300
|
return this._parent;
|
|
1176
1301
|
}
|
|
@@ -1180,6 +1305,9 @@
|
|
|
1180
1305
|
get children() {
|
|
1181
1306
|
return this._children;
|
|
1182
1307
|
}
|
|
1308
|
+
get isOptional() {
|
|
1309
|
+
return this._isOptional;
|
|
1310
|
+
}
|
|
1183
1311
|
constructor(name, isOptional = false) {
|
|
1184
1312
|
this._type = "reference";
|
|
1185
1313
|
this._name = name;
|
|
@@ -1188,35 +1316,22 @@
|
|
|
1188
1316
|
this._pattern = null;
|
|
1189
1317
|
this._children = [];
|
|
1190
1318
|
}
|
|
1191
|
-
|
|
1319
|
+
test(text) {
|
|
1320
|
+
const cursor = new Cursor(text);
|
|
1321
|
+
const ast = this.parse(cursor);
|
|
1322
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1323
|
+
}
|
|
1324
|
+
exec(text) {
|
|
1192
1325
|
const cursor = new Cursor(text);
|
|
1193
1326
|
const ast = this.parse(cursor);
|
|
1194
1327
|
return {
|
|
1195
|
-
ast,
|
|
1328
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
1196
1329
|
cursor
|
|
1197
1330
|
};
|
|
1198
1331
|
}
|
|
1199
1332
|
parse(cursor) {
|
|
1200
1333
|
return this._getPatternSafely().parse(cursor);
|
|
1201
1334
|
}
|
|
1202
|
-
clone(name = this._name, isOptional = this._isOptional) {
|
|
1203
|
-
return new Reference(name, isOptional);
|
|
1204
|
-
}
|
|
1205
|
-
getTokens() {
|
|
1206
|
-
return this._getPatternSafely().getTokens();
|
|
1207
|
-
}
|
|
1208
|
-
getNextTokens(_lastMatched) {
|
|
1209
|
-
if (this.parent == null) {
|
|
1210
|
-
return [];
|
|
1211
|
-
}
|
|
1212
|
-
return this.parent.getNextTokens(this);
|
|
1213
|
-
}
|
|
1214
|
-
getNextPattern() {
|
|
1215
|
-
return getNextPattern(this);
|
|
1216
|
-
}
|
|
1217
|
-
findPattern(_isMatch) {
|
|
1218
|
-
return null;
|
|
1219
|
-
}
|
|
1220
1335
|
_getPatternSafely() {
|
|
1221
1336
|
if (this._pattern === null) {
|
|
1222
1337
|
const pattern = this._findPattern();
|
|
@@ -1249,10 +1364,210 @@
|
|
|
1249
1364
|
}
|
|
1250
1365
|
return node;
|
|
1251
1366
|
}
|
|
1367
|
+
getTokens() {
|
|
1368
|
+
return this._getPatternSafely().getTokens();
|
|
1369
|
+
}
|
|
1370
|
+
getTokensAfter(_lastMatched) {
|
|
1371
|
+
if (this._parent == null) {
|
|
1372
|
+
return [];
|
|
1373
|
+
}
|
|
1374
|
+
return this._parent.getTokensAfter(this);
|
|
1375
|
+
}
|
|
1376
|
+
getNextTokens() {
|
|
1377
|
+
if (this.parent == null) {
|
|
1378
|
+
return [];
|
|
1379
|
+
}
|
|
1380
|
+
return this.parent.getTokensAfter(this);
|
|
1381
|
+
}
|
|
1382
|
+
getPatterns() {
|
|
1383
|
+
return this._getPatternSafely().getPatterns();
|
|
1384
|
+
}
|
|
1385
|
+
getPatternsAfter(_childReference) {
|
|
1386
|
+
if (this._parent == null) {
|
|
1387
|
+
return [];
|
|
1388
|
+
}
|
|
1389
|
+
return this._parent.getPatternsAfter(this);
|
|
1390
|
+
}
|
|
1391
|
+
getNextPatterns() {
|
|
1392
|
+
if (this.parent == null) {
|
|
1393
|
+
return [];
|
|
1394
|
+
}
|
|
1395
|
+
return this.parent.getPatternsAfter(this);
|
|
1396
|
+
}
|
|
1397
|
+
findPattern(_predicate) {
|
|
1398
|
+
return null;
|
|
1399
|
+
}
|
|
1400
|
+
clone(name = this._name, isOptional = this._isOptional) {
|
|
1401
|
+
return new Reference(name, isOptional);
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
const defaultOptions = { greedyPatternNames: [], customTokens: {} };
|
|
1406
|
+
class AutoComplete {
|
|
1407
|
+
constructor(pattern, options = defaultOptions) {
|
|
1408
|
+
this._pattern = pattern;
|
|
1409
|
+
this._options = options;
|
|
1410
|
+
this._text = "";
|
|
1411
|
+
}
|
|
1412
|
+
/**
|
|
1413
|
+
* @deprecated Use suggestFor instead.
|
|
1414
|
+
* @param text The text to suggest for.
|
|
1415
|
+
*/
|
|
1416
|
+
suggest(text) {
|
|
1417
|
+
return this.suggestFor(text);
|
|
1418
|
+
}
|
|
1419
|
+
suggestFor(text) {
|
|
1420
|
+
if (text.length === 0) {
|
|
1421
|
+
return {
|
|
1422
|
+
isComplete: false,
|
|
1423
|
+
options: this._createSuggestionsFromRoot(),
|
|
1424
|
+
errorAtIndex: 0,
|
|
1425
|
+
cursor: null,
|
|
1426
|
+
ast: null
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
this._text = text;
|
|
1430
|
+
this._cursor = new Cursor(text);
|
|
1431
|
+
const ast = this._pattern.parse(this._cursor);
|
|
1432
|
+
const leafPattern = this._cursor.leafMatch.pattern;
|
|
1433
|
+
const isComplete = (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1434
|
+
const options = this._createSuggestionsFromTokens();
|
|
1435
|
+
[this._pattern];
|
|
1436
|
+
let errorAtIndex = null;
|
|
1437
|
+
if (leafPattern != null) {
|
|
1438
|
+
leafPattern.getNextPatterns();
|
|
1439
|
+
}
|
|
1440
|
+
if (this._cursor.hasError && this._cursor.furthestError != null) {
|
|
1441
|
+
errorAtIndex = this._cursor.furthestError.index;
|
|
1442
|
+
errorAtIndex = options.reduce((errorAtIndex, option) => Math.max(errorAtIndex, option.startIndex), errorAtIndex);
|
|
1443
|
+
}
|
|
1444
|
+
return {
|
|
1445
|
+
isComplete: isComplete,
|
|
1446
|
+
options: options,
|
|
1447
|
+
errorAtIndex,
|
|
1448
|
+
cursor: this._cursor,
|
|
1449
|
+
ast,
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
_createSuggestionsFromRoot() {
|
|
1453
|
+
const suggestions = [];
|
|
1454
|
+
const tokens = this._pattern.getTokens();
|
|
1455
|
+
for (const token of tokens) {
|
|
1456
|
+
suggestions.push(this._createSuggestion("", token));
|
|
1457
|
+
}
|
|
1458
|
+
return suggestions;
|
|
1459
|
+
}
|
|
1460
|
+
_createSuggestionsFromTokens() {
|
|
1461
|
+
const leafMatch = this._cursor.leafMatch;
|
|
1462
|
+
if (!leafMatch.pattern) {
|
|
1463
|
+
return this._createSuggestions(-1, this._getTokensForPattern(this._pattern));
|
|
1464
|
+
}
|
|
1465
|
+
const leafPattern = leafMatch.pattern;
|
|
1466
|
+
const parent = leafMatch.pattern.parent;
|
|
1467
|
+
if (parent !== null && leafMatch.node != null) {
|
|
1468
|
+
const patterns = leafPattern.getNextPatterns();
|
|
1469
|
+
const tokens = patterns.reduce((acc, pattern) => {
|
|
1470
|
+
acc.push(...this._getTokensForPattern(pattern));
|
|
1471
|
+
return acc;
|
|
1472
|
+
}, []);
|
|
1473
|
+
return this._createSuggestions(leafMatch.node.lastIndex, tokens);
|
|
1474
|
+
}
|
|
1475
|
+
else {
|
|
1476
|
+
return [];
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
_getTokensForPattern(pattern) {
|
|
1480
|
+
const augmentedTokens = this._getAugmentedTokens(pattern);
|
|
1481
|
+
if (this._options.greedyPatternNames != null && this._options.greedyPatternNames.includes(pattern.name)) {
|
|
1482
|
+
const nextPatterns = pattern.getNextPatterns();
|
|
1483
|
+
const tokens = [];
|
|
1484
|
+
const nextPatternTokens = nextPatterns.reduce((acc, pattern) => {
|
|
1485
|
+
acc.push(...this._getTokensForPattern(pattern));
|
|
1486
|
+
return acc;
|
|
1487
|
+
}, []);
|
|
1488
|
+
for (let token of augmentedTokens) {
|
|
1489
|
+
for (let nextPatternToken of nextPatternTokens) {
|
|
1490
|
+
tokens.push(token + nextPatternToken);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
return tokens;
|
|
1494
|
+
}
|
|
1495
|
+
else {
|
|
1496
|
+
return augmentedTokens;
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
_getAugmentedTokens(pattern) {
|
|
1500
|
+
const customTokensMap = this._options.customTokens || {};
|
|
1501
|
+
const leafPatterns = pattern.getPatterns();
|
|
1502
|
+
const tokens = customTokensMap[pattern.name] || [];
|
|
1503
|
+
leafPatterns.forEach(p => {
|
|
1504
|
+
const augmentedTokens = customTokensMap[p.name] || [];
|
|
1505
|
+
tokens.push(...p.getTokens(), ...augmentedTokens);
|
|
1506
|
+
});
|
|
1507
|
+
return tokens;
|
|
1508
|
+
}
|
|
1509
|
+
_createSuggestions(lastIndex, tokens) {
|
|
1510
|
+
let substring = lastIndex === -1 ? "" : this._cursor.getChars(0, lastIndex);
|
|
1511
|
+
const suggestionStrings = [];
|
|
1512
|
+
const options = [];
|
|
1513
|
+
for (const token of tokens) {
|
|
1514
|
+
const suggestion = substring + token;
|
|
1515
|
+
const startsWith = suggestion.startsWith(substring);
|
|
1516
|
+
const alreadyExist = suggestionStrings.includes(suggestion);
|
|
1517
|
+
const isSameAsText = suggestion === this._text;
|
|
1518
|
+
if (startsWith && !alreadyExist && !isSameAsText) {
|
|
1519
|
+
suggestionStrings.push(suggestion);
|
|
1520
|
+
options.push(this._createSuggestion(this._cursor.text, suggestion));
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
const reducedOptions = getFurthestOptions(options);
|
|
1524
|
+
reducedOptions.sort((a, b) => a.text.localeCompare(b.text));
|
|
1525
|
+
return reducedOptions;
|
|
1526
|
+
}
|
|
1527
|
+
_createSuggestion(fullText, suggestion) {
|
|
1528
|
+
const furthestMatch = findMatchIndex(suggestion, fullText);
|
|
1529
|
+
const text = suggestion.slice(furthestMatch);
|
|
1530
|
+
return {
|
|
1531
|
+
text: text,
|
|
1532
|
+
startIndex: furthestMatch,
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
function findMatchIndex(str1, str2) {
|
|
1537
|
+
let matchCount = 0;
|
|
1538
|
+
let minLength = str1.length;
|
|
1539
|
+
if (str2.length < minLength) {
|
|
1540
|
+
minLength = str2.length;
|
|
1541
|
+
}
|
|
1542
|
+
for (let i = 0; i < minLength; i++) {
|
|
1543
|
+
if (str1[i] === str2[i]) {
|
|
1544
|
+
matchCount++;
|
|
1545
|
+
}
|
|
1546
|
+
else {
|
|
1547
|
+
break;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
return matchCount;
|
|
1551
|
+
}
|
|
1552
|
+
function getFurthestOptions(options) {
|
|
1553
|
+
let furthestOptions = [];
|
|
1554
|
+
let furthestIndex = -1;
|
|
1555
|
+
for (const option of options) {
|
|
1556
|
+
if (option.startIndex > furthestIndex) {
|
|
1557
|
+
furthestIndex = option.startIndex;
|
|
1558
|
+
furthestOptions = [];
|
|
1559
|
+
}
|
|
1560
|
+
if (option.startIndex === furthestIndex) {
|
|
1561
|
+
furthestOptions.push(option);
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
return furthestOptions;
|
|
1252
1565
|
}
|
|
1253
1566
|
|
|
1254
1567
|
exports.And = And;
|
|
1568
|
+
exports.AutoComplete = AutoComplete;
|
|
1255
1569
|
exports.Cursor = Cursor;
|
|
1570
|
+
exports.CursorHistory = CursorHistory;
|
|
1256
1571
|
exports.Literal = Literal;
|
|
1257
1572
|
exports.Node = Node;
|
|
1258
1573
|
exports.Not = Not;
|