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.esm.js
CHANGED
|
@@ -778,6 +778,7 @@ class Reference {
|
|
|
778
778
|
this._name = name;
|
|
779
779
|
this._parent = null;
|
|
780
780
|
this._pattern = null;
|
|
781
|
+
this._cachedPattern = null;
|
|
781
782
|
this._children = [];
|
|
782
783
|
}
|
|
783
784
|
test(text) {
|
|
@@ -799,7 +800,13 @@ class Reference {
|
|
|
799
800
|
}
|
|
800
801
|
_getPatternSafely() {
|
|
801
802
|
if (this._pattern === null) {
|
|
802
|
-
|
|
803
|
+
let pattern = null;
|
|
804
|
+
if (this._cachedPattern == null) {
|
|
805
|
+
pattern = this._findPattern();
|
|
806
|
+
}
|
|
807
|
+
else {
|
|
808
|
+
pattern = this._cachedPattern;
|
|
809
|
+
}
|
|
803
810
|
if (pattern === null) {
|
|
804
811
|
throw new Error(`Couldn't find '${this._name}' pattern within tree.`);
|
|
805
812
|
}
|
|
@@ -865,6 +872,10 @@ class Reference {
|
|
|
865
872
|
clone(name = this._name) {
|
|
866
873
|
const clone = new Reference(name);
|
|
867
874
|
clone._id = this._id;
|
|
875
|
+
// Optimize future clones, by caching the pattern we already found.
|
|
876
|
+
if (this._pattern != null) {
|
|
877
|
+
clone._cachedPattern = this._pattern;
|
|
878
|
+
}
|
|
868
879
|
return clone;
|
|
869
880
|
}
|
|
870
881
|
isEqual(pattern) {
|
|
@@ -876,6 +887,33 @@ function clonePatterns(patterns) {
|
|
|
876
887
|
return patterns.map(p => p.clone());
|
|
877
888
|
}
|
|
878
889
|
|
|
890
|
+
class DepthCache {
|
|
891
|
+
constructor() {
|
|
892
|
+
this._depthMap = {};
|
|
893
|
+
}
|
|
894
|
+
getDepth(name, cursorIndex) {
|
|
895
|
+
if (this._depthMap[name] == null) {
|
|
896
|
+
this._depthMap[name] = {};
|
|
897
|
+
}
|
|
898
|
+
if (this._depthMap[name][cursorIndex] == null) {
|
|
899
|
+
this._depthMap[name][cursorIndex] = 0;
|
|
900
|
+
}
|
|
901
|
+
return this._depthMap[name][cursorIndex];
|
|
902
|
+
}
|
|
903
|
+
incrementDepth(name, cursorIndex) {
|
|
904
|
+
const depth = this.getDepth(name, cursorIndex);
|
|
905
|
+
this._depthMap[name][cursorIndex] = depth + 1;
|
|
906
|
+
}
|
|
907
|
+
decrementDepth(name, cursorIndex) {
|
|
908
|
+
const depth = this.getDepth(name, cursorIndex);
|
|
909
|
+
this._depthMap[name][cursorIndex] = depth - 1;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
/*
|
|
914
|
+
The following is created to reduce the overhead of recursion check.
|
|
915
|
+
*/
|
|
916
|
+
const depthCache$1 = new DepthCache();
|
|
879
917
|
let idIndex$6 = 0;
|
|
880
918
|
class Options {
|
|
881
919
|
get id() {
|
|
@@ -930,8 +968,12 @@ class Options {
|
|
|
930
968
|
};
|
|
931
969
|
}
|
|
932
970
|
parse(cursor) {
|
|
971
|
+
// This is a cache to help with speed
|
|
972
|
+
this._firstIndex = cursor.index;
|
|
973
|
+
depthCache$1.incrementDepth(this._id, this._firstIndex);
|
|
933
974
|
this._firstIndex = cursor.index;
|
|
934
975
|
const node = this._tryToParse(cursor);
|
|
976
|
+
depthCache$1.decrementDepth(this._id, this._firstIndex);
|
|
935
977
|
if (node != null) {
|
|
936
978
|
cursor.moveTo(node.lastIndex);
|
|
937
979
|
cursor.resolveError();
|
|
@@ -941,8 +983,8 @@ class Options {
|
|
|
941
983
|
return null;
|
|
942
984
|
}
|
|
943
985
|
_tryToParse(cursor) {
|
|
944
|
-
if (this.
|
|
945
|
-
cursor.recordErrorAt(
|
|
986
|
+
if (depthCache$1.getDepth(this._id, this._firstIndex) > 2) {
|
|
987
|
+
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
946
988
|
return null;
|
|
947
989
|
}
|
|
948
990
|
const results = [];
|
|
@@ -962,25 +1004,6 @@ class Options {
|
|
|
962
1004
|
nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
|
|
963
1005
|
return nonNullResults[0] || null;
|
|
964
1006
|
}
|
|
965
|
-
_isBeyondRecursiveLimit() {
|
|
966
|
-
let pattern = this;
|
|
967
|
-
const matches = [];
|
|
968
|
-
while (pattern.parent != null) {
|
|
969
|
-
if (pattern.type !== "options") {
|
|
970
|
-
pattern = pattern.parent;
|
|
971
|
-
continue;
|
|
972
|
-
}
|
|
973
|
-
const optionsPattern = pattern;
|
|
974
|
-
if (pattern.id === this.id && optionsPattern._firstIndex === this._firstIndex) {
|
|
975
|
-
matches.push(pattern);
|
|
976
|
-
if (matches.length > 2) {
|
|
977
|
-
return true;
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
pattern = pattern.parent;
|
|
981
|
-
}
|
|
982
|
-
return false;
|
|
983
|
-
}
|
|
984
1007
|
getTokens() {
|
|
985
1008
|
const tokens = [];
|
|
986
1009
|
for (const child of this._children) {
|
|
@@ -1573,6 +1596,7 @@ function filterOutNull(nodes) {
|
|
|
1573
1596
|
return filteredNodes;
|
|
1574
1597
|
}
|
|
1575
1598
|
|
|
1599
|
+
const depthCache = new DepthCache();
|
|
1576
1600
|
let idIndex$2 = 0;
|
|
1577
1601
|
class Sequence {
|
|
1578
1602
|
get id() {
|
|
@@ -1627,13 +1651,12 @@ class Sequence {
|
|
|
1627
1651
|
};
|
|
1628
1652
|
}
|
|
1629
1653
|
parse(cursor) {
|
|
1654
|
+
// This is a cache to help with speed
|
|
1630
1655
|
this._firstIndex = cursor.index;
|
|
1656
|
+
depthCache.incrementDepth(this._id, this._firstIndex);
|
|
1631
1657
|
this._nodes = [];
|
|
1632
|
-
if (this._isBeyondRecursiveLimit()) {
|
|
1633
|
-
cursor.recordErrorAt(cursor.index, cursor.index, this);
|
|
1634
|
-
return null;
|
|
1635
|
-
}
|
|
1636
1658
|
const passed = this.tryToParse(cursor);
|
|
1659
|
+
depthCache.decrementDepth(this._id, this._firstIndex);
|
|
1637
1660
|
if (passed) {
|
|
1638
1661
|
const node = this.createNode(cursor);
|
|
1639
1662
|
if (node !== null) {
|
|
@@ -1644,6 +1667,10 @@ class Sequence {
|
|
|
1644
1667
|
return null;
|
|
1645
1668
|
}
|
|
1646
1669
|
tryToParse(cursor) {
|
|
1670
|
+
if (depthCache.getDepth(this._id, this._firstIndex) > 1) {
|
|
1671
|
+
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
1672
|
+
return false;
|
|
1673
|
+
}
|
|
1647
1674
|
let passed = false;
|
|
1648
1675
|
for (let i = 0; i < this._children.length; i++) {
|
|
1649
1676
|
const runningCursorIndex = cursor.index;
|
|
@@ -1700,25 +1727,6 @@ class Sequence {
|
|
|
1700
1727
|
}
|
|
1701
1728
|
return passed;
|
|
1702
1729
|
}
|
|
1703
|
-
_isBeyondRecursiveLimit() {
|
|
1704
|
-
let pattern = this;
|
|
1705
|
-
const matches = [];
|
|
1706
|
-
while (pattern.parent != null) {
|
|
1707
|
-
if (pattern.type !== "sequence") {
|
|
1708
|
-
pattern = pattern.parent;
|
|
1709
|
-
continue;
|
|
1710
|
-
}
|
|
1711
|
-
const sequencePattern = pattern;
|
|
1712
|
-
if (pattern.id === this.id && sequencePattern._firstIndex === this._firstIndex) {
|
|
1713
|
-
matches.push(pattern);
|
|
1714
|
-
if (matches.length > 1) {
|
|
1715
|
-
return true;
|
|
1716
|
-
}
|
|
1717
|
-
}
|
|
1718
|
-
pattern = pattern.parent;
|
|
1719
|
-
}
|
|
1720
|
-
return false;
|
|
1721
|
-
}
|
|
1722
1730
|
getLastValidNode() {
|
|
1723
1731
|
const nodes = filterOutNull(this._nodes);
|
|
1724
1732
|
if (nodes.length === 0) {
|