clarity-pattern-parser 8.2.0 → 8.3.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/.vscode/settings.json +5 -1
- package/README.md +2 -2
- package/dist/grammar/Grammar.d.ts +22 -3
- package/dist/grammar/patterns/import.d.ts +2 -0
- package/dist/index.browser.js +325 -193
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +323 -191
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +323 -191
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/ast/Node.ts +1 -1
- package/src/grammar/Grammar.test.ts +67 -21
- package/src/grammar/Grammar.ts +120 -13
- package/src/grammar/patterns/grammar.ts +9 -6
- package/src/grammar/patterns/import.ts +29 -0
- package/src/grammar/spec.md +26 -2
- package/src/patterns/And.ts +1 -5
- package/src/patterns/FiniteRepeat.ts +2 -1
- package/src/patterns/InfiniteRepeat.test.ts +9 -23
- package/src/patterns/InfiniteRepeat.ts +7 -2
- package/src/patterns/Or.ts +2 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
1
|
class Node {
|
|
2
|
-
constructor(type, name, firstIndex, lastIndex, children = [], value = "") {
|
|
3
|
-
this._type = type;
|
|
4
|
-
this._name = name;
|
|
5
|
-
this._firstIndex = firstIndex;
|
|
6
|
-
this._lastIndex = lastIndex;
|
|
7
|
-
this._parent = null;
|
|
8
|
-
this._children = children;
|
|
9
|
-
this._value = value;
|
|
10
|
-
this._children.forEach(c => c._parent = this);
|
|
11
|
-
}
|
|
12
2
|
get type() {
|
|
13
3
|
return this._type;
|
|
14
4
|
}
|
|
@@ -39,6 +29,16 @@ class Node {
|
|
|
39
29
|
get value() {
|
|
40
30
|
return this.toString();
|
|
41
31
|
}
|
|
32
|
+
constructor(type, name, firstIndex, lastIndex, children = [], value = "") {
|
|
33
|
+
this._type = type;
|
|
34
|
+
this._name = name;
|
|
35
|
+
this._firstIndex = firstIndex;
|
|
36
|
+
this._lastIndex = lastIndex;
|
|
37
|
+
this._parent = null;
|
|
38
|
+
this._children = children;
|
|
39
|
+
this._value = value;
|
|
40
|
+
this._children.forEach(c => c._parent = this);
|
|
41
|
+
}
|
|
42
42
|
removeChild(node) {
|
|
43
43
|
const index = this._children.indexOf(node);
|
|
44
44
|
if (index > -1) {
|
|
@@ -176,6 +176,36 @@ class Node {
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
/******************************************************************************
|
|
180
|
+
Copyright (c) Microsoft Corporation.
|
|
181
|
+
|
|
182
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
183
|
+
purpose with or without fee is hereby granted.
|
|
184
|
+
|
|
185
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
186
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
187
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
188
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
189
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
190
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
191
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
192
|
+
***************************************************************************** */
|
|
193
|
+
|
|
194
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
195
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
196
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
197
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
198
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
199
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
200
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
205
|
+
var e = new Error(message);
|
|
206
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
207
|
+
};
|
|
208
|
+
|
|
179
209
|
class ParseError {
|
|
180
210
|
constructor(startIndex, endIndex, pattern) {
|
|
181
211
|
this.startIndex = startIndex;
|
|
@@ -279,12 +309,6 @@ class CursorHistory {
|
|
|
279
309
|
}
|
|
280
310
|
|
|
281
311
|
class Cursor {
|
|
282
|
-
constructor(text) {
|
|
283
|
-
this._text = text;
|
|
284
|
-
this._index = 0;
|
|
285
|
-
this._length = text.length;
|
|
286
|
-
this._history = new CursorHistory();
|
|
287
|
-
}
|
|
288
312
|
get text() {
|
|
289
313
|
return this._text;
|
|
290
314
|
}
|
|
@@ -327,6 +351,12 @@ class Cursor {
|
|
|
327
351
|
get currentChar() {
|
|
328
352
|
return this._text[this._index];
|
|
329
353
|
}
|
|
354
|
+
constructor(text) {
|
|
355
|
+
this._text = text;
|
|
356
|
+
this._index = 0;
|
|
357
|
+
this._length = text.length;
|
|
358
|
+
this._history = new CursorHistory();
|
|
359
|
+
}
|
|
330
360
|
hasNext() {
|
|
331
361
|
return this._index + 1 < this._length;
|
|
332
362
|
}
|
|
@@ -378,20 +408,6 @@ class Cursor {
|
|
|
378
408
|
}
|
|
379
409
|
|
|
380
410
|
class Literal {
|
|
381
|
-
constructor(name, value, isOptional = false) {
|
|
382
|
-
if (value.length === 0) {
|
|
383
|
-
throw new Error("Value Cannot be empty.");
|
|
384
|
-
}
|
|
385
|
-
this._type = "literal";
|
|
386
|
-
this._name = name;
|
|
387
|
-
this._literal = value;
|
|
388
|
-
this._runes = Array.from(value);
|
|
389
|
-
this._isOptional = isOptional;
|
|
390
|
-
this._parent = null;
|
|
391
|
-
this._firstIndex = 0;
|
|
392
|
-
this._lastIndex = 0;
|
|
393
|
-
this._endIndex = 0;
|
|
394
|
-
}
|
|
395
411
|
get type() {
|
|
396
412
|
return this._type;
|
|
397
413
|
}
|
|
@@ -410,6 +426,20 @@ class Literal {
|
|
|
410
426
|
get isOptional() {
|
|
411
427
|
return this._isOptional;
|
|
412
428
|
}
|
|
429
|
+
constructor(name, value, isOptional = false) {
|
|
430
|
+
if (value.length === 0) {
|
|
431
|
+
throw new Error("Value Cannot be empty.");
|
|
432
|
+
}
|
|
433
|
+
this._type = "literal";
|
|
434
|
+
this._name = name;
|
|
435
|
+
this._literal = value;
|
|
436
|
+
this._runes = Array.from(value);
|
|
437
|
+
this._isOptional = isOptional;
|
|
438
|
+
this._parent = null;
|
|
439
|
+
this._firstIndex = 0;
|
|
440
|
+
this._lastIndex = 0;
|
|
441
|
+
this._endIndex = 0;
|
|
442
|
+
}
|
|
413
443
|
test(text) {
|
|
414
444
|
const cursor = new Cursor(text);
|
|
415
445
|
const ast = this.parse(cursor);
|
|
@@ -500,20 +530,6 @@ class Literal {
|
|
|
500
530
|
}
|
|
501
531
|
|
|
502
532
|
class Regex {
|
|
503
|
-
constructor(name, regex, isOptional = false) {
|
|
504
|
-
this._node = null;
|
|
505
|
-
this._cursor = null;
|
|
506
|
-
this._firstIndex = -1;
|
|
507
|
-
this._substring = "";
|
|
508
|
-
this._tokens = [];
|
|
509
|
-
this._type = "regex";
|
|
510
|
-
this._name = name;
|
|
511
|
-
this._isOptional = isOptional;
|
|
512
|
-
this._parent = null;
|
|
513
|
-
this._originalRegexString = regex;
|
|
514
|
-
this._regex = new RegExp(`^${regex}`, "g");
|
|
515
|
-
this.assertArguments();
|
|
516
|
-
}
|
|
517
533
|
get type() {
|
|
518
534
|
return this._type;
|
|
519
535
|
}
|
|
@@ -532,6 +548,20 @@ class Regex {
|
|
|
532
548
|
get isOptional() {
|
|
533
549
|
return this._isOptional;
|
|
534
550
|
}
|
|
551
|
+
constructor(name, regex, isOptional = false) {
|
|
552
|
+
this._node = null;
|
|
553
|
+
this._cursor = null;
|
|
554
|
+
this._firstIndex = -1;
|
|
555
|
+
this._substring = "";
|
|
556
|
+
this._tokens = [];
|
|
557
|
+
this._type = "regex";
|
|
558
|
+
this._name = name;
|
|
559
|
+
this._isOptional = isOptional;
|
|
560
|
+
this._parent = null;
|
|
561
|
+
this._originalRegexString = regex;
|
|
562
|
+
this._regex = new RegExp(`^${regex}`, "g");
|
|
563
|
+
this.assertArguments();
|
|
564
|
+
}
|
|
535
565
|
assertArguments() {
|
|
536
566
|
if (this._originalRegexString.length < 1) {
|
|
537
567
|
throw new Error("Invalid Arguments: The regex string argument needs to be at least one character long.");
|
|
@@ -650,14 +680,6 @@ function findPattern(pattern, predicate) {
|
|
|
650
680
|
}
|
|
651
681
|
|
|
652
682
|
class Reference {
|
|
653
|
-
constructor(name, isOptional = false) {
|
|
654
|
-
this._type = "reference";
|
|
655
|
-
this._name = name;
|
|
656
|
-
this._parent = null;
|
|
657
|
-
this._isOptional = isOptional;
|
|
658
|
-
this._pattern = null;
|
|
659
|
-
this._children = [];
|
|
660
|
-
}
|
|
661
683
|
get type() {
|
|
662
684
|
return this._type;
|
|
663
685
|
}
|
|
@@ -676,6 +698,14 @@ class Reference {
|
|
|
676
698
|
get isOptional() {
|
|
677
699
|
return this._isOptional;
|
|
678
700
|
}
|
|
701
|
+
constructor(name, isOptional = false) {
|
|
702
|
+
this._type = "reference";
|
|
703
|
+
this._name = name;
|
|
704
|
+
this._parent = null;
|
|
705
|
+
this._isOptional = isOptional;
|
|
706
|
+
this._pattern = null;
|
|
707
|
+
this._children = [];
|
|
708
|
+
}
|
|
679
709
|
test(text) {
|
|
680
710
|
const cursor = new Cursor(text);
|
|
681
711
|
const ast = this.parse(cursor);
|
|
@@ -767,20 +797,6 @@ function clonePatterns(patterns, isOptional) {
|
|
|
767
797
|
}
|
|
768
798
|
|
|
769
799
|
class Or {
|
|
770
|
-
constructor(name, options, isOptional = false, isGreedy = false) {
|
|
771
|
-
if (options.length === 0) {
|
|
772
|
-
throw new Error("Need at least one pattern with an 'or' pattern.");
|
|
773
|
-
}
|
|
774
|
-
const children = clonePatterns(options, false);
|
|
775
|
-
this._assignChildrenToParent(children);
|
|
776
|
-
this._type = "or";
|
|
777
|
-
this._name = name;
|
|
778
|
-
this._parent = null;
|
|
779
|
-
this._children = children;
|
|
780
|
-
this._isOptional = isOptional;
|
|
781
|
-
this._firstIndex = 0;
|
|
782
|
-
this._isGreedy = isGreedy;
|
|
783
|
-
}
|
|
784
800
|
get type() {
|
|
785
801
|
return this._type;
|
|
786
802
|
}
|
|
@@ -799,6 +815,20 @@ class Or {
|
|
|
799
815
|
get isOptional() {
|
|
800
816
|
return this._isOptional;
|
|
801
817
|
}
|
|
818
|
+
constructor(name, options, isOptional = false, isGreedy = false) {
|
|
819
|
+
if (options.length === 0) {
|
|
820
|
+
throw new Error("Need at least one pattern with an 'or' pattern.");
|
|
821
|
+
}
|
|
822
|
+
const children = clonePatterns(options, false);
|
|
823
|
+
this._assignChildrenToParent(children);
|
|
824
|
+
this._type = "or";
|
|
825
|
+
this._name = name;
|
|
826
|
+
this._parent = null;
|
|
827
|
+
this._children = children;
|
|
828
|
+
this._isOptional = isOptional;
|
|
829
|
+
this._firstIndex = 0;
|
|
830
|
+
this._isGreedy = isGreedy;
|
|
831
|
+
}
|
|
802
832
|
_assignChildrenToParent(children) {
|
|
803
833
|
for (const child of children) {
|
|
804
834
|
child.parent = this;
|
|
@@ -821,6 +851,7 @@ class Or {
|
|
|
821
851
|
this._firstIndex = cursor.index;
|
|
822
852
|
const node = this._tryToParse(cursor);
|
|
823
853
|
if (node != null) {
|
|
854
|
+
cursor.moveTo(node.lastIndex);
|
|
824
855
|
cursor.resolveError();
|
|
825
856
|
return node;
|
|
826
857
|
}
|
|
@@ -891,28 +922,12 @@ class Or {
|
|
|
891
922
|
return findPattern(this, predicate);
|
|
892
923
|
}
|
|
893
924
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
894
|
-
const or = new Or(name, this._children, isOptional);
|
|
925
|
+
const or = new Or(name, this._children, isOptional, this._isGreedy);
|
|
895
926
|
return or;
|
|
896
927
|
}
|
|
897
928
|
}
|
|
898
929
|
|
|
899
930
|
class FiniteRepeat {
|
|
900
|
-
constructor(name, pattern, repeatAmount, options = {}) {
|
|
901
|
-
this._type = "finite-repeat";
|
|
902
|
-
this._name = name;
|
|
903
|
-
this._parent = null;
|
|
904
|
-
this._children = [];
|
|
905
|
-
this._hasDivider = options.divider != null;
|
|
906
|
-
this._min = options.min != null ? options.min : 1;
|
|
907
|
-
this._max = repeatAmount;
|
|
908
|
-
this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
|
|
909
|
-
for (let i = 0; i < repeatAmount; i++) {
|
|
910
|
-
this._children.push(pattern.clone(pattern.name));
|
|
911
|
-
if (options.divider != null && (i < repeatAmount - 1 || !this._trimDivider)) {
|
|
912
|
-
this._children.push(options.divider.clone(options.divider.name, false));
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
931
|
get type() {
|
|
917
932
|
return this._type;
|
|
918
933
|
}
|
|
@@ -937,6 +952,22 @@ class FiniteRepeat {
|
|
|
937
952
|
get max() {
|
|
938
953
|
return this._max;
|
|
939
954
|
}
|
|
955
|
+
constructor(name, pattern, repeatAmount, options = {}) {
|
|
956
|
+
this._type = "finite-repeat";
|
|
957
|
+
this._name = name;
|
|
958
|
+
this._parent = null;
|
|
959
|
+
this._children = [];
|
|
960
|
+
this._hasDivider = options.divider != null;
|
|
961
|
+
this._min = options.min != null ? options.min : 1;
|
|
962
|
+
this._max = repeatAmount;
|
|
963
|
+
this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
|
|
964
|
+
for (let i = 0; i < repeatAmount; i++) {
|
|
965
|
+
this._children.push(pattern.clone(pattern.name));
|
|
966
|
+
if (options.divider != null && (i < repeatAmount - 1 || !this._trimDivider)) {
|
|
967
|
+
this._children.push(options.divider.clone(options.divider.name, false));
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
}
|
|
940
971
|
parse(cursor) {
|
|
941
972
|
const startIndex = cursor.index;
|
|
942
973
|
const nodes = [];
|
|
@@ -969,8 +1000,9 @@ class FiniteRepeat {
|
|
|
969
1000
|
}
|
|
970
1001
|
}
|
|
971
1002
|
if (matchCount < this._min) {
|
|
1003
|
+
const lastIndex = cursor.index;
|
|
972
1004
|
cursor.moveTo(startIndex);
|
|
973
|
-
cursor.recordErrorAt(startIndex,
|
|
1005
|
+
cursor.recordErrorAt(startIndex, lastIndex, this);
|
|
974
1006
|
return null;
|
|
975
1007
|
}
|
|
976
1008
|
else if (nodes.length === 0) {
|
|
@@ -1061,28 +1093,6 @@ class FiniteRepeat {
|
|
|
1061
1093
|
}
|
|
1062
1094
|
|
|
1063
1095
|
class InfiniteRepeat {
|
|
1064
|
-
constructor(name, pattern, options = {}) {
|
|
1065
|
-
const min = options.min != null ? options.min : 1;
|
|
1066
|
-
const divider = options.divider;
|
|
1067
|
-
let children;
|
|
1068
|
-
if (divider != null) {
|
|
1069
|
-
children = [pattern.clone(), divider.clone(divider.name, false)];
|
|
1070
|
-
}
|
|
1071
|
-
else {
|
|
1072
|
-
children = [pattern.clone()];
|
|
1073
|
-
}
|
|
1074
|
-
this._assignChildrenToParent(children);
|
|
1075
|
-
this._type = "infinite-repeat";
|
|
1076
|
-
this._name = name;
|
|
1077
|
-
this._min = min;
|
|
1078
|
-
this._parent = null;
|
|
1079
|
-
this._children = children;
|
|
1080
|
-
this._pattern = children[0];
|
|
1081
|
-
this._divider = children[1];
|
|
1082
|
-
this._firstIndex = -1;
|
|
1083
|
-
this._nodes = [];
|
|
1084
|
-
this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
|
|
1085
|
-
}
|
|
1086
1096
|
get type() {
|
|
1087
1097
|
return this._type;
|
|
1088
1098
|
}
|
|
@@ -1104,6 +1114,28 @@ class InfiniteRepeat {
|
|
|
1104
1114
|
get min() {
|
|
1105
1115
|
return this._min;
|
|
1106
1116
|
}
|
|
1117
|
+
constructor(name, pattern, options = {}) {
|
|
1118
|
+
const min = options.min != null ? options.min : 1;
|
|
1119
|
+
const divider = options.divider;
|
|
1120
|
+
let children;
|
|
1121
|
+
if (divider != null) {
|
|
1122
|
+
children = [pattern.clone(pattern.name, false), divider.clone(divider.name, false)];
|
|
1123
|
+
}
|
|
1124
|
+
else {
|
|
1125
|
+
children = [pattern.clone(pattern.name, false)];
|
|
1126
|
+
}
|
|
1127
|
+
this._assignChildrenToParent(children);
|
|
1128
|
+
this._type = "infinite-repeat";
|
|
1129
|
+
this._name = name;
|
|
1130
|
+
this._min = min;
|
|
1131
|
+
this._parent = null;
|
|
1132
|
+
this._children = children;
|
|
1133
|
+
this._pattern = children[0];
|
|
1134
|
+
this._divider = children[1];
|
|
1135
|
+
this._firstIndex = -1;
|
|
1136
|
+
this._nodes = [];
|
|
1137
|
+
this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
|
|
1138
|
+
}
|
|
1107
1139
|
_assignChildrenToParent(children) {
|
|
1108
1140
|
for (const child of children) {
|
|
1109
1141
|
child.parent = this;
|
|
@@ -1210,6 +1242,10 @@ class InfiniteRepeat {
|
|
|
1210
1242
|
const dividerNode = this._nodes.pop();
|
|
1211
1243
|
cursor.moveTo(dividerNode.firstIndex);
|
|
1212
1244
|
}
|
|
1245
|
+
// if (this._nodes.length === 0) {
|
|
1246
|
+
// cursor.moveTo(this._firstIndex);
|
|
1247
|
+
// return null;
|
|
1248
|
+
// }
|
|
1213
1249
|
const lastIndex = this._nodes[this._nodes.length - 1].lastIndex;
|
|
1214
1250
|
cursor.moveTo(lastIndex);
|
|
1215
1251
|
return new Node(this._type, this._name, this._firstIndex, lastIndex, this._nodes);
|
|
@@ -1297,19 +1333,6 @@ class InfiniteRepeat {
|
|
|
1297
1333
|
}
|
|
1298
1334
|
|
|
1299
1335
|
class Repeat {
|
|
1300
|
-
constructor(name, pattern, options = {}) {
|
|
1301
|
-
this._pattern = pattern;
|
|
1302
|
-
this._parent = null;
|
|
1303
|
-
this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
|
|
1304
|
-
if (this._options.max !== Infinity) {
|
|
1305
|
-
this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
|
|
1306
|
-
}
|
|
1307
|
-
else {
|
|
1308
|
-
this._repeatPattern = new InfiniteRepeat(name, pattern, this._options);
|
|
1309
|
-
}
|
|
1310
|
-
this._children = [this._repeatPattern];
|
|
1311
|
-
this._repeatPattern.parent = this;
|
|
1312
|
-
}
|
|
1313
1336
|
get type() {
|
|
1314
1337
|
return this._repeatPattern.type;
|
|
1315
1338
|
}
|
|
@@ -1328,6 +1351,19 @@ class Repeat {
|
|
|
1328
1351
|
get isOptional() {
|
|
1329
1352
|
return this._repeatPattern.isOptional;
|
|
1330
1353
|
}
|
|
1354
|
+
constructor(name, pattern, options = {}) {
|
|
1355
|
+
this._pattern = pattern;
|
|
1356
|
+
this._parent = null;
|
|
1357
|
+
this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
|
|
1358
|
+
if (this._options.max !== Infinity) {
|
|
1359
|
+
this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
|
|
1360
|
+
}
|
|
1361
|
+
else {
|
|
1362
|
+
this._repeatPattern = new InfiniteRepeat(name, pattern, this._options);
|
|
1363
|
+
}
|
|
1364
|
+
this._children = [this._repeatPattern];
|
|
1365
|
+
this._repeatPattern.parent = this;
|
|
1366
|
+
}
|
|
1331
1367
|
parse(cursor) {
|
|
1332
1368
|
return this._repeatPattern.parse(cursor);
|
|
1333
1369
|
}
|
|
@@ -1397,20 +1433,6 @@ function filterOutNull(nodes) {
|
|
|
1397
1433
|
}
|
|
1398
1434
|
|
|
1399
1435
|
class And {
|
|
1400
|
-
constructor(name, sequence, isOptional = false) {
|
|
1401
|
-
if (sequence.length === 0) {
|
|
1402
|
-
throw new Error("Need at least one pattern with an 'and' pattern.");
|
|
1403
|
-
}
|
|
1404
|
-
const children = clonePatterns(sequence);
|
|
1405
|
-
this._assignChildrenToParent(children);
|
|
1406
|
-
this._type = "and";
|
|
1407
|
-
this._name = name;
|
|
1408
|
-
this._isOptional = isOptional;
|
|
1409
|
-
this._parent = null;
|
|
1410
|
-
this._children = children;
|
|
1411
|
-
this._firstIndex = -1;
|
|
1412
|
-
this._nodes = [];
|
|
1413
|
-
}
|
|
1414
1436
|
get type() {
|
|
1415
1437
|
return this._type;
|
|
1416
1438
|
}
|
|
@@ -1429,6 +1451,20 @@ class And {
|
|
|
1429
1451
|
get isOptional() {
|
|
1430
1452
|
return this._isOptional;
|
|
1431
1453
|
}
|
|
1454
|
+
constructor(name, sequence, isOptional = false) {
|
|
1455
|
+
if (sequence.length === 0) {
|
|
1456
|
+
throw new Error("Need at least one pattern with an 'and' pattern.");
|
|
1457
|
+
}
|
|
1458
|
+
const children = clonePatterns(sequence);
|
|
1459
|
+
this._assignChildrenToParent(children);
|
|
1460
|
+
this._type = "and";
|
|
1461
|
+
this._name = name;
|
|
1462
|
+
this._isOptional = isOptional;
|
|
1463
|
+
this._parent = null;
|
|
1464
|
+
this._children = children;
|
|
1465
|
+
this._firstIndex = -1;
|
|
1466
|
+
this._nodes = [];
|
|
1467
|
+
}
|
|
1432
1468
|
_assignChildrenToParent(children) {
|
|
1433
1469
|
for (const child of children) {
|
|
1434
1470
|
child.parent = this;
|
|
@@ -1541,7 +1577,6 @@ class And {
|
|
|
1541
1577
|
createNode(cursor) {
|
|
1542
1578
|
const children = filterOutNull(this._nodes);
|
|
1543
1579
|
const lastIndex = children[children.length - 1].lastIndex;
|
|
1544
|
-
cursor.getChars(this._firstIndex, lastIndex);
|
|
1545
1580
|
cursor.moveTo(lastIndex);
|
|
1546
1581
|
return new Node("and", this._name, this._firstIndex, lastIndex, children);
|
|
1547
1582
|
}
|
|
@@ -1583,9 +1618,6 @@ class And {
|
|
|
1583
1618
|
let index = -1;
|
|
1584
1619
|
for (let i = 0; i < this._children.length; i++) {
|
|
1585
1620
|
if (this._children[i] === childReference) {
|
|
1586
|
-
if (i + 1 < this._children.length) {
|
|
1587
|
-
this._children[i + 1];
|
|
1588
|
-
}
|
|
1589
1621
|
nextSiblingIndex = i + 1;
|
|
1590
1622
|
index = i;
|
|
1591
1623
|
break;
|
|
@@ -1627,11 +1659,11 @@ class And {
|
|
|
1627
1659
|
}
|
|
1628
1660
|
}
|
|
1629
1661
|
|
|
1630
|
-
const name = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
|
|
1662
|
+
const name$1 = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
|
|
1631
1663
|
|
|
1632
1664
|
const optionalNot = new Literal("not", "!", true);
|
|
1633
1665
|
const optionalIsOptional$1 = new Literal("is-optional", "?", true);
|
|
1634
|
-
const patternName$1 = name.clone("pattern-name");
|
|
1666
|
+
const patternName$1 = name$1.clone("pattern-name");
|
|
1635
1667
|
const pattern$1 = new And("pattern", [
|
|
1636
1668
|
optionalNot,
|
|
1637
1669
|
patternName$1,
|
|
@@ -1644,44 +1676,44 @@ const andLiteral = new Repeat("and-literal", pattern$1, { divider: divider$1, mi
|
|
|
1644
1676
|
|
|
1645
1677
|
const divider = new Regex("or-divider", "\\s*[|]\\s*");
|
|
1646
1678
|
divider.setTokens([" | "]);
|
|
1647
|
-
const orLiteral = new Repeat("or-literal", name.clone("pattern-name"), { divider, min: 2 });
|
|
1679
|
+
const orLiteral = new Repeat("or-literal", name$1.clone("pattern-name"), { divider, min: 2 });
|
|
1648
1680
|
|
|
1649
1681
|
const regexLiteral = new Regex("regex-literal", "/(\\\\/|[^/\\n\\r])*/");
|
|
1650
1682
|
|
|
1651
|
-
const spaces = new Regex("spaces", "[ \\t]+");
|
|
1652
|
-
spaces.setTokens([" "]);
|
|
1683
|
+
const spaces$1 = new Regex("spaces", "[ \\t]+");
|
|
1684
|
+
spaces$1.setTokens([" "]);
|
|
1653
1685
|
|
|
1654
1686
|
const optionalIsOptional = new Literal("is-optional", "?", true);
|
|
1655
|
-
const patternName = name.clone("pattern-name");
|
|
1687
|
+
const patternName = name$1.clone("pattern-name");
|
|
1656
1688
|
const pattern = new And("pattern", [
|
|
1657
1689
|
patternName,
|
|
1658
1690
|
optionalIsOptional,
|
|
1659
1691
|
]);
|
|
1660
|
-
const optionalSpaces$
|
|
1661
|
-
const dividerPattern = name.clone("divider-pattern");
|
|
1662
|
-
const openBracket = new Literal("open-bracket", "{");
|
|
1663
|
-
const closeBracket = new Literal("close-bracket", "}");
|
|
1692
|
+
const optionalSpaces$2 = spaces$1.clone("optional-spaces", true);
|
|
1693
|
+
const dividerPattern = name$1.clone("divider-pattern");
|
|
1694
|
+
const openBracket$1 = new Literal("open-bracket", "{");
|
|
1695
|
+
const closeBracket$1 = new Literal("close-bracket", "}");
|
|
1664
1696
|
const comma = new Literal("comma", ",");
|
|
1665
1697
|
const integer = new Regex("integer", "([1-9][0-9]*)|0");
|
|
1666
1698
|
integer.setTokens(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
|
|
1667
1699
|
const optionalInteger = integer.clone("integer", true);
|
|
1668
1700
|
const bounds = new And("bounds", [
|
|
1669
|
-
openBracket,
|
|
1670
|
-
optionalSpaces$
|
|
1701
|
+
openBracket$1,
|
|
1702
|
+
optionalSpaces$2,
|
|
1671
1703
|
optionalInteger.clone("min"),
|
|
1672
|
-
optionalSpaces$
|
|
1704
|
+
optionalSpaces$2,
|
|
1673
1705
|
comma,
|
|
1674
|
-
optionalSpaces$
|
|
1706
|
+
optionalSpaces$2,
|
|
1675
1707
|
optionalInteger.clone("max"),
|
|
1676
|
-
optionalSpaces$
|
|
1677
|
-
closeBracket
|
|
1708
|
+
optionalSpaces$2,
|
|
1709
|
+
closeBracket$1
|
|
1678
1710
|
]);
|
|
1679
1711
|
const exactCount = new And("exact-count", [
|
|
1680
|
-
openBracket,
|
|
1681
|
-
optionalSpaces$
|
|
1712
|
+
openBracket$1,
|
|
1713
|
+
optionalSpaces$2,
|
|
1682
1714
|
integer,
|
|
1683
|
-
optionalSpaces$
|
|
1684
|
-
closeBracket,
|
|
1715
|
+
optionalSpaces$2,
|
|
1716
|
+
closeBracket$1,
|
|
1685
1717
|
]);
|
|
1686
1718
|
const quantifierShorthand = new Regex("quantifier-shorthand", "\\*|\\+");
|
|
1687
1719
|
quantifierShorthand.setTokens(["*", "+"]);
|
|
@@ -1698,19 +1730,19 @@ const dividerComma = new Regex("divider-comma", "\\s*,\\s*");
|
|
|
1698
1730
|
dividerComma.setTokens([", "]);
|
|
1699
1731
|
const repeatLiteral = new And("repeat-literal", [
|
|
1700
1732
|
openParen,
|
|
1701
|
-
optionalSpaces$
|
|
1733
|
+
optionalSpaces$2,
|
|
1702
1734
|
pattern,
|
|
1703
1735
|
optional,
|
|
1704
1736
|
new And("optional-divider-section", [dividerComma, dividerPattern], true),
|
|
1705
|
-
optionalSpaces$
|
|
1737
|
+
optionalSpaces$2,
|
|
1706
1738
|
closeParen,
|
|
1707
|
-
new And("quantifier-section", [optionalSpaces$
|
|
1708
|
-
new And("optional-trim-divider-section", [spaces, trimDivider], true)
|
|
1739
|
+
new And("quantifier-section", [optionalSpaces$2, quantifier]),
|
|
1740
|
+
new And("optional-trim-divider-section", [spaces$1, trimDivider], true)
|
|
1709
1741
|
]);
|
|
1710
1742
|
|
|
1711
1743
|
const literal = new Regex("literal", "\"(?:\\\\[\"\\\\]|[^\n\"\\\\])*\"");
|
|
1712
1744
|
|
|
1713
|
-
const optionalSpaces = spaces.clone("optional-spaces", true);
|
|
1745
|
+
const optionalSpaces$1 = spaces$1.clone("optional-spaces", true);
|
|
1714
1746
|
const assignOperator = new Literal("assign-operator", "=");
|
|
1715
1747
|
const optionalComment = comment.clone("inline-comment", true);
|
|
1716
1748
|
const statements = new Or("statements", [
|
|
@@ -1719,39 +1751,57 @@ const statements = new Or("statements", [
|
|
|
1719
1751
|
orLiteral,
|
|
1720
1752
|
andLiteral,
|
|
1721
1753
|
repeatLiteral,
|
|
1722
|
-
name.clone("alias-literal"),
|
|
1754
|
+
name$1.clone("alias-literal"),
|
|
1723
1755
|
]);
|
|
1724
1756
|
const statement = new And("statement", [
|
|
1725
|
-
optionalSpaces,
|
|
1726
|
-
name,
|
|
1727
|
-
optionalSpaces,
|
|
1757
|
+
optionalSpaces$1,
|
|
1758
|
+
name$1,
|
|
1759
|
+
optionalSpaces$1,
|
|
1728
1760
|
assignOperator,
|
|
1729
|
-
optionalSpaces,
|
|
1761
|
+
optionalSpaces$1,
|
|
1730
1762
|
statements,
|
|
1731
|
-
optionalSpaces,
|
|
1763
|
+
optionalSpaces$1,
|
|
1732
1764
|
optionalComment,
|
|
1765
|
+
optionalSpaces$1,
|
|
1766
|
+
]);
|
|
1767
|
+
|
|
1768
|
+
const spaces = new Regex("spaces", "\\s+", true);
|
|
1769
|
+
const importNameDivider = new Regex("import-name-divider", "(\\s+)?,(\\s+)?");
|
|
1770
|
+
const importKeyword = new Literal("import", "import");
|
|
1771
|
+
const fromKeyword = new Literal("from", "from");
|
|
1772
|
+
const openBracket = new Literal("open-bracket", "{");
|
|
1773
|
+
const closeBracket = new Literal("close-bracket", "}");
|
|
1774
|
+
const name = new Regex("import-name", "[^}\\s,]+");
|
|
1775
|
+
const importedNames = new Repeat("imported-names", name, { divider: importNameDivider });
|
|
1776
|
+
const optionalSpaces = spaces.clone("optional-spaces", true);
|
|
1777
|
+
const importStatement = new And("import-statement", [
|
|
1778
|
+
importKeyword,
|
|
1779
|
+
optionalSpaces,
|
|
1780
|
+
openBracket,
|
|
1781
|
+
optionalSpaces,
|
|
1782
|
+
importedNames,
|
|
1733
1783
|
optionalSpaces,
|
|
1784
|
+
closeBracket,
|
|
1785
|
+
optionalSpaces,
|
|
1786
|
+
fromKeyword,
|
|
1787
|
+
spaces,
|
|
1788
|
+
literal.clone("url"),
|
|
1734
1789
|
]);
|
|
1735
1790
|
|
|
1736
|
-
const whitespace = new Regex("whitespace", "[ \\t]+");
|
|
1791
|
+
const whitespace = new Regex("whitespace", "[ \\t]+((\\r?\\n)+)?");
|
|
1737
1792
|
const newLine = new Regex("new-line", "(\\r?\\n)+");
|
|
1738
1793
|
whitespace.setTokens([" "]);
|
|
1739
1794
|
newLine.setTokens(["\n"]);
|
|
1740
1795
|
const line = new Or("line", [
|
|
1796
|
+
newLine,
|
|
1797
|
+
whitespace,
|
|
1741
1798
|
comment,
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
]
|
|
1745
|
-
const grammar = new Repeat("
|
|
1799
|
+
importStatement,
|
|
1800
|
+
statement
|
|
1801
|
+
]);
|
|
1802
|
+
const grammar = new Repeat("grammer", line);
|
|
1746
1803
|
|
|
1747
1804
|
class Not {
|
|
1748
|
-
constructor(name, pattern) {
|
|
1749
|
-
this._type = "not";
|
|
1750
|
-
this._name = name;
|
|
1751
|
-
this._parent = null;
|
|
1752
|
-
this._children = [pattern.clone(pattern.name, false)];
|
|
1753
|
-
this._children[0].parent = this;
|
|
1754
|
-
}
|
|
1755
1805
|
get type() {
|
|
1756
1806
|
return this._type;
|
|
1757
1807
|
}
|
|
@@ -1770,6 +1820,13 @@ class Not {
|
|
|
1770
1820
|
get isOptional() {
|
|
1771
1821
|
return false;
|
|
1772
1822
|
}
|
|
1823
|
+
constructor(name, pattern) {
|
|
1824
|
+
this._type = "not";
|
|
1825
|
+
this._name = name;
|
|
1826
|
+
this._parent = null;
|
|
1827
|
+
this._children = [pattern.clone(pattern.name, false)];
|
|
1828
|
+
this._children[0].parent = this;
|
|
1829
|
+
}
|
|
1773
1830
|
test(text) {
|
|
1774
1831
|
const cursor = new Cursor(text);
|
|
1775
1832
|
this.parse(cursor);
|
|
@@ -2039,10 +2096,16 @@ function getFurthestOptions(options) {
|
|
|
2039
2096
|
class ParseContext {
|
|
2040
2097
|
constructor() {
|
|
2041
2098
|
this.patternsByName = new Map();
|
|
2099
|
+
this.importedPatternsByName = new Map();
|
|
2042
2100
|
}
|
|
2043
2101
|
}
|
|
2102
|
+
function defaultImportResolver(_path, _basePath) {
|
|
2103
|
+
throw new Error("No import resolver supplied.");
|
|
2104
|
+
}
|
|
2044
2105
|
class Grammar {
|
|
2045
|
-
constructor() {
|
|
2106
|
+
constructor(options = {}) {
|
|
2107
|
+
this._meta = options.meta == null ? null : options.meta;
|
|
2108
|
+
this._resolveImport = options.resolveImport == null ? defaultImportResolver : options.resolveImport;
|
|
2046
2109
|
this._parseContext = new ParseContext();
|
|
2047
2110
|
this._autoComplete = new AutoComplete(grammar, {
|
|
2048
2111
|
greedyPatternNames: ["spaces", "optional-spaces", "whitespace", "new-line"],
|
|
@@ -2054,9 +2117,31 @@ class Grammar {
|
|
|
2054
2117
|
}
|
|
2055
2118
|
});
|
|
2056
2119
|
}
|
|
2120
|
+
import(path) {
|
|
2121
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2122
|
+
const grammarFile = yield this._resolveImport(path, null);
|
|
2123
|
+
const grammar = new Grammar({ resolveImport: this._resolveImport, meta: { originPath: grammarFile.path } });
|
|
2124
|
+
return grammar.parse(grammarFile.expression);
|
|
2125
|
+
});
|
|
2126
|
+
}
|
|
2057
2127
|
parse(expression) {
|
|
2128
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2129
|
+
this._parseContext = new ParseContext();
|
|
2130
|
+
const ast = this._tryToParse(expression);
|
|
2131
|
+
yield this._resolveImports(ast);
|
|
2132
|
+
this._buildPatterns(ast);
|
|
2133
|
+
this._cleanAst(ast);
|
|
2134
|
+
return this._parseContext.patternsByName;
|
|
2135
|
+
});
|
|
2136
|
+
}
|
|
2137
|
+
parseString(expression) {
|
|
2058
2138
|
this._parseContext = new ParseContext();
|
|
2059
|
-
this._tryToParse(expression);
|
|
2139
|
+
const ast = this._tryToParse(expression);
|
|
2140
|
+
if (this._hasImports(ast)) {
|
|
2141
|
+
throw new Error("Cannot use imports on parseString, use parse instead.");
|
|
2142
|
+
}
|
|
2143
|
+
this._buildPatterns(ast);
|
|
2144
|
+
this._cleanAst(ast);
|
|
2060
2145
|
return this._parseContext.patternsByName;
|
|
2061
2146
|
}
|
|
2062
2147
|
_tryToParse(expression) {
|
|
@@ -2073,8 +2158,14 @@ class Grammar {
|
|
|
2073
2158
|
throw new Error(message);
|
|
2074
2159
|
}
|
|
2075
2160
|
// If it is complete it will always have a node. So we have to cast it.
|
|
2076
|
-
|
|
2077
|
-
|
|
2161
|
+
return ast;
|
|
2162
|
+
}
|
|
2163
|
+
_hasImports(ast) {
|
|
2164
|
+
const importBlock = ast.find(n => n.name === "import-block");
|
|
2165
|
+
if (importBlock == null) {
|
|
2166
|
+
return false;
|
|
2167
|
+
}
|
|
2168
|
+
return importBlock && importBlock.children.length > 0;
|
|
2078
2169
|
}
|
|
2079
2170
|
_cleanAst(ast) {
|
|
2080
2171
|
ast.findAll(n => n.name === "spaces" ||
|
|
@@ -2115,6 +2206,36 @@ class Grammar {
|
|
|
2115
2206
|
}
|
|
2116
2207
|
});
|
|
2117
2208
|
}
|
|
2209
|
+
_resolveImports(ast) {
|
|
2210
|
+
var _a;
|
|
2211
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2212
|
+
const parseContext = this._parseContext;
|
|
2213
|
+
const importStatements = ast.findAll(n => n.name === "import-statement");
|
|
2214
|
+
for (const importStatement of importStatements) {
|
|
2215
|
+
const urlNode = importStatement.find(n => n.name === "url");
|
|
2216
|
+
const url = urlNode.value.slice(1, -1);
|
|
2217
|
+
const grammarFile = yield this._resolveImport(url, ((_a = this._meta) === null || _a === void 0 ? void 0 : _a.originPath) || null);
|
|
2218
|
+
const grammar = new Grammar({ resolveImport: this._resolveImport, meta: { originPath: grammarFile.path } });
|
|
2219
|
+
try {
|
|
2220
|
+
const patterns = yield grammar.parse(grammarFile.expression);
|
|
2221
|
+
const importNames = importStatement.findAll(n => n.name === "import-name").map(n => n.value);
|
|
2222
|
+
importNames.forEach((importName) => {
|
|
2223
|
+
if (parseContext.importedPatternsByName.has(importName)) {
|
|
2224
|
+
throw new Error(`'${importName}' was already used within another import.`);
|
|
2225
|
+
}
|
|
2226
|
+
const pattern = patterns.get(importName);
|
|
2227
|
+
if (pattern == null) {
|
|
2228
|
+
throw new Error(`Couldn't find pattern with name: ${importName}, from import: ${url}.`);
|
|
2229
|
+
}
|
|
2230
|
+
parseContext.importedPatternsByName.set(importName, pattern);
|
|
2231
|
+
});
|
|
2232
|
+
}
|
|
2233
|
+
catch (e) {
|
|
2234
|
+
throw new Error(`Failed loading expression from: "${url}". Error details: "${e.message}"`);
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
});
|
|
2238
|
+
}
|
|
2118
2239
|
_buildLiteral(statementNode) {
|
|
2119
2240
|
const nameNode = statementNode.find(n => n.name === "name");
|
|
2120
2241
|
const literalNode = statementNode.find(n => n.name === "literal");
|
|
@@ -2134,14 +2255,17 @@ class Grammar {
|
|
|
2134
2255
|
_buildOr(statementNode) {
|
|
2135
2256
|
const nameNode = statementNode.find(n => n.name === "name");
|
|
2136
2257
|
const orNode = statementNode.find(n => n.name === "or-literal");
|
|
2137
|
-
const patternNodes = orNode.children.filter(n => n.name
|
|
2258
|
+
const patternNodes = orNode.children.filter(n => n.name === "pattern-name");
|
|
2138
2259
|
const name = nameNode.value;
|
|
2139
2260
|
const patterns = patternNodes.map(n => this._getPattern(n.value));
|
|
2140
|
-
const or = new Or(name, patterns);
|
|
2261
|
+
const or = new Or(name, patterns, false, true);
|
|
2141
2262
|
this._parseContext.patternsByName.set(name, or);
|
|
2142
2263
|
}
|
|
2143
2264
|
_getPattern(name) {
|
|
2144
|
-
|
|
2265
|
+
let pattern = this._parseContext.patternsByName.get(name);
|
|
2266
|
+
if (pattern == null) {
|
|
2267
|
+
pattern = this._parseContext.importedPatternsByName.get(name);
|
|
2268
|
+
}
|
|
2145
2269
|
if (pattern == null) {
|
|
2146
2270
|
return new Reference(name);
|
|
2147
2271
|
}
|
|
@@ -2150,7 +2274,7 @@ class Grammar {
|
|
|
2150
2274
|
_buildAnd(statementNode) {
|
|
2151
2275
|
const nameNode = statementNode.find(n => n.name === "name");
|
|
2152
2276
|
const andNode = statementNode.find(n => n.name === "and-literal");
|
|
2153
|
-
const patternNodes = andNode.children.filter(n => n.name
|
|
2277
|
+
const patternNodes = andNode.children.filter(n => n.name === "pattern");
|
|
2154
2278
|
const name = nameNode.value;
|
|
2155
2279
|
const patterns = patternNodes.map(n => {
|
|
2156
2280
|
const nameNode = n.find(n => n.name === "pattern-name");
|
|
@@ -2169,7 +2293,7 @@ class Grammar {
|
|
|
2169
2293
|
_buildRepeat(statementNode) {
|
|
2170
2294
|
const nameNode = statementNode.find(n => n.name === "name");
|
|
2171
2295
|
const repeatNode = statementNode.find(n => n.name === "repeat-literal");
|
|
2172
|
-
const patternNode = repeatNode.find(n => n.name
|
|
2296
|
+
const patternNode = repeatNode.find(n => n.name === "pattern");
|
|
2173
2297
|
const patternNameNode = patternNode.find(n => n.name === "pattern-name");
|
|
2174
2298
|
const dividerNode = repeatNode.find(n => n.name === "divider-pattern");
|
|
2175
2299
|
const bounds = repeatNode.find(n => n.name === "bounds");
|
|
@@ -2226,10 +2350,18 @@ class Grammar {
|
|
|
2226
2350
|
const alias = pattern.clone(name);
|
|
2227
2351
|
this._parseContext.patternsByName.set(name, alias);
|
|
2228
2352
|
}
|
|
2229
|
-
static parse(expression) {
|
|
2230
|
-
const grammar = new Grammar();
|
|
2353
|
+
static parse(expression, options) {
|
|
2354
|
+
const grammar = new Grammar(options);
|
|
2231
2355
|
return grammar.parse(expression);
|
|
2232
2356
|
}
|
|
2357
|
+
static import(path, options) {
|
|
2358
|
+
const grammar = new Grammar(options);
|
|
2359
|
+
return grammar.import(path);
|
|
2360
|
+
}
|
|
2361
|
+
static parseString(expression) {
|
|
2362
|
+
const grammar = new Grammar();
|
|
2363
|
+
return grammar.parseString(expression);
|
|
2364
|
+
}
|
|
2233
2365
|
}
|
|
2234
2366
|
|
|
2235
2367
|
export { And, AutoComplete, Cursor, CursorHistory, Grammar, Literal, Node, Not, Or, ParseError, Reference, Regex, Repeat };
|