clarity-pattern-parser 10.0.6 → 10.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.browser.js +53 -45
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +53 -45
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +53 -45
- package/dist/index.js.map +1 -1
- package/dist/patterns/DepthCache.d.ts +6 -0
- package/dist/patterns/Options.d.ts +0 -1
- package/dist/patterns/Reference.d.ts +1 -0
- package/dist/patterns/Sequence.d.ts +0 -1
- package/package.json +1 -1
- package/src/patterns/DepthCache.ts +26 -0
- package/src/patterns/Options.ts +14 -29
- package/src/patterns/Reference.ts +15 -1
- package/src/patterns/Sequence.ts +10 -32
package/dist/index.browser.js
CHANGED
|
@@ -784,6 +784,7 @@
|
|
|
784
784
|
this._name = name;
|
|
785
785
|
this._parent = null;
|
|
786
786
|
this._pattern = null;
|
|
787
|
+
this._cachedPattern = null;
|
|
787
788
|
this._children = [];
|
|
788
789
|
}
|
|
789
790
|
test(text) {
|
|
@@ -805,7 +806,13 @@
|
|
|
805
806
|
}
|
|
806
807
|
_getPatternSafely() {
|
|
807
808
|
if (this._pattern === null) {
|
|
808
|
-
|
|
809
|
+
let pattern = null;
|
|
810
|
+
if (this._cachedPattern == null) {
|
|
811
|
+
pattern = this._findPattern();
|
|
812
|
+
}
|
|
813
|
+
else {
|
|
814
|
+
pattern = this._cachedPattern;
|
|
815
|
+
}
|
|
809
816
|
if (pattern === null) {
|
|
810
817
|
throw new Error(`Couldn't find '${this._name}' pattern within tree.`);
|
|
811
818
|
}
|
|
@@ -871,6 +878,10 @@
|
|
|
871
878
|
clone(name = this._name) {
|
|
872
879
|
const clone = new Reference(name);
|
|
873
880
|
clone._id = this._id;
|
|
881
|
+
// Optimize future clones, by caching the pattern we already found.
|
|
882
|
+
if (this._pattern != null) {
|
|
883
|
+
clone._cachedPattern = this._pattern;
|
|
884
|
+
}
|
|
874
885
|
return clone;
|
|
875
886
|
}
|
|
876
887
|
isEqual(pattern) {
|
|
@@ -882,6 +893,33 @@
|
|
|
882
893
|
return patterns.map(p => p.clone());
|
|
883
894
|
}
|
|
884
895
|
|
|
896
|
+
class DepthCache {
|
|
897
|
+
constructor() {
|
|
898
|
+
this._depthMap = {};
|
|
899
|
+
}
|
|
900
|
+
getDepth(name, cursorIndex) {
|
|
901
|
+
if (this._depthMap[name] == null) {
|
|
902
|
+
this._depthMap[name] = {};
|
|
903
|
+
}
|
|
904
|
+
if (this._depthMap[name][cursorIndex] == null) {
|
|
905
|
+
this._depthMap[name][cursorIndex] = 0;
|
|
906
|
+
}
|
|
907
|
+
return this._depthMap[name][cursorIndex];
|
|
908
|
+
}
|
|
909
|
+
incrementDepth(name, cursorIndex) {
|
|
910
|
+
const depth = this.getDepth(name, cursorIndex);
|
|
911
|
+
this._depthMap[name][cursorIndex] = depth + 1;
|
|
912
|
+
}
|
|
913
|
+
decrementDepth(name, cursorIndex) {
|
|
914
|
+
const depth = this.getDepth(name, cursorIndex);
|
|
915
|
+
this._depthMap[name][cursorIndex] = depth - 1;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/*
|
|
920
|
+
The following is created to reduce the overhead of recursion check.
|
|
921
|
+
*/
|
|
922
|
+
const depthCache$1 = new DepthCache();
|
|
885
923
|
let idIndex$6 = 0;
|
|
886
924
|
class Options {
|
|
887
925
|
get id() {
|
|
@@ -936,8 +974,12 @@
|
|
|
936
974
|
};
|
|
937
975
|
}
|
|
938
976
|
parse(cursor) {
|
|
977
|
+
// This is a cache to help with speed
|
|
978
|
+
this._firstIndex = cursor.index;
|
|
979
|
+
depthCache$1.incrementDepth(this._id, this._firstIndex);
|
|
939
980
|
this._firstIndex = cursor.index;
|
|
940
981
|
const node = this._tryToParse(cursor);
|
|
982
|
+
depthCache$1.decrementDepth(this._id, this._firstIndex);
|
|
941
983
|
if (node != null) {
|
|
942
984
|
cursor.moveTo(node.lastIndex);
|
|
943
985
|
cursor.resolveError();
|
|
@@ -947,8 +989,8 @@
|
|
|
947
989
|
return null;
|
|
948
990
|
}
|
|
949
991
|
_tryToParse(cursor) {
|
|
950
|
-
if (this.
|
|
951
|
-
cursor.recordErrorAt(
|
|
992
|
+
if (depthCache$1.getDepth(this._id, this._firstIndex) > 2) {
|
|
993
|
+
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
952
994
|
return null;
|
|
953
995
|
}
|
|
954
996
|
const results = [];
|
|
@@ -968,25 +1010,6 @@
|
|
|
968
1010
|
nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
|
|
969
1011
|
return nonNullResults[0] || null;
|
|
970
1012
|
}
|
|
971
|
-
_isBeyondRecursiveLimit() {
|
|
972
|
-
let pattern = this;
|
|
973
|
-
const matches = [];
|
|
974
|
-
while (pattern.parent != null) {
|
|
975
|
-
if (pattern.type !== "options") {
|
|
976
|
-
pattern = pattern.parent;
|
|
977
|
-
continue;
|
|
978
|
-
}
|
|
979
|
-
const optionsPattern = pattern;
|
|
980
|
-
if (pattern.id === this.id && optionsPattern._firstIndex === this._firstIndex) {
|
|
981
|
-
matches.push(pattern);
|
|
982
|
-
if (matches.length > 2) {
|
|
983
|
-
return true;
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
pattern = pattern.parent;
|
|
987
|
-
}
|
|
988
|
-
return false;
|
|
989
|
-
}
|
|
990
1013
|
getTokens() {
|
|
991
1014
|
const tokens = [];
|
|
992
1015
|
for (const child of this._children) {
|
|
@@ -1579,6 +1602,7 @@
|
|
|
1579
1602
|
return filteredNodes;
|
|
1580
1603
|
}
|
|
1581
1604
|
|
|
1605
|
+
const depthCache = new DepthCache();
|
|
1582
1606
|
let idIndex$2 = 0;
|
|
1583
1607
|
class Sequence {
|
|
1584
1608
|
get id() {
|
|
@@ -1633,13 +1657,12 @@
|
|
|
1633
1657
|
};
|
|
1634
1658
|
}
|
|
1635
1659
|
parse(cursor) {
|
|
1660
|
+
// This is a cache to help with speed
|
|
1636
1661
|
this._firstIndex = cursor.index;
|
|
1662
|
+
depthCache.incrementDepth(this._id, this._firstIndex);
|
|
1637
1663
|
this._nodes = [];
|
|
1638
|
-
if (this._isBeyondRecursiveLimit()) {
|
|
1639
|
-
cursor.recordErrorAt(cursor.index, cursor.index, this);
|
|
1640
|
-
return null;
|
|
1641
|
-
}
|
|
1642
1664
|
const passed = this.tryToParse(cursor);
|
|
1665
|
+
depthCache.decrementDepth(this._id, this._firstIndex);
|
|
1643
1666
|
if (passed) {
|
|
1644
1667
|
const node = this.createNode(cursor);
|
|
1645
1668
|
if (node !== null) {
|
|
@@ -1650,6 +1673,10 @@
|
|
|
1650
1673
|
return null;
|
|
1651
1674
|
}
|
|
1652
1675
|
tryToParse(cursor) {
|
|
1676
|
+
if (depthCache.getDepth(this._id, this._firstIndex) > 1) {
|
|
1677
|
+
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
1678
|
+
return false;
|
|
1679
|
+
}
|
|
1653
1680
|
let passed = false;
|
|
1654
1681
|
for (let i = 0; i < this._children.length; i++) {
|
|
1655
1682
|
const runningCursorIndex = cursor.index;
|
|
@@ -1706,25 +1733,6 @@
|
|
|
1706
1733
|
}
|
|
1707
1734
|
return passed;
|
|
1708
1735
|
}
|
|
1709
|
-
_isBeyondRecursiveLimit() {
|
|
1710
|
-
let pattern = this;
|
|
1711
|
-
const matches = [];
|
|
1712
|
-
while (pattern.parent != null) {
|
|
1713
|
-
if (pattern.type !== "sequence") {
|
|
1714
|
-
pattern = pattern.parent;
|
|
1715
|
-
continue;
|
|
1716
|
-
}
|
|
1717
|
-
const sequencePattern = pattern;
|
|
1718
|
-
if (pattern.id === this.id && sequencePattern._firstIndex === this._firstIndex) {
|
|
1719
|
-
matches.push(pattern);
|
|
1720
|
-
if (matches.length > 1) {
|
|
1721
|
-
return true;
|
|
1722
|
-
}
|
|
1723
|
-
}
|
|
1724
|
-
pattern = pattern.parent;
|
|
1725
|
-
}
|
|
1726
|
-
return false;
|
|
1727
|
-
}
|
|
1728
1736
|
getLastValidNode() {
|
|
1729
1737
|
const nodes = filterOutNull(this._nodes);
|
|
1730
1738
|
if (nodes.length === 0) {
|