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.js
CHANGED
|
@@ -782,6 +782,7 @@ class Reference {
|
|
|
782
782
|
this._name = name;
|
|
783
783
|
this._parent = null;
|
|
784
784
|
this._pattern = null;
|
|
785
|
+
this._cachedPattern = null;
|
|
785
786
|
this._children = [];
|
|
786
787
|
}
|
|
787
788
|
test(text) {
|
|
@@ -803,7 +804,13 @@ class Reference {
|
|
|
803
804
|
}
|
|
804
805
|
_getPatternSafely() {
|
|
805
806
|
if (this._pattern === null) {
|
|
806
|
-
|
|
807
|
+
let pattern = null;
|
|
808
|
+
if (this._cachedPattern == null) {
|
|
809
|
+
pattern = this._findPattern();
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
812
|
+
pattern = this._cachedPattern;
|
|
813
|
+
}
|
|
807
814
|
if (pattern === null) {
|
|
808
815
|
throw new Error(`Couldn't find '${this._name}' pattern within tree.`);
|
|
809
816
|
}
|
|
@@ -869,6 +876,10 @@ class Reference {
|
|
|
869
876
|
clone(name = this._name) {
|
|
870
877
|
const clone = new Reference(name);
|
|
871
878
|
clone._id = this._id;
|
|
879
|
+
// Optimize future clones, by caching the pattern we already found.
|
|
880
|
+
if (this._pattern != null) {
|
|
881
|
+
clone._cachedPattern = this._pattern;
|
|
882
|
+
}
|
|
872
883
|
return clone;
|
|
873
884
|
}
|
|
874
885
|
isEqual(pattern) {
|
|
@@ -880,6 +891,33 @@ function clonePatterns(patterns) {
|
|
|
880
891
|
return patterns.map(p => p.clone());
|
|
881
892
|
}
|
|
882
893
|
|
|
894
|
+
class DepthCache {
|
|
895
|
+
constructor() {
|
|
896
|
+
this._depthMap = {};
|
|
897
|
+
}
|
|
898
|
+
getDepth(name, cursorIndex) {
|
|
899
|
+
if (this._depthMap[name] == null) {
|
|
900
|
+
this._depthMap[name] = {};
|
|
901
|
+
}
|
|
902
|
+
if (this._depthMap[name][cursorIndex] == null) {
|
|
903
|
+
this._depthMap[name][cursorIndex] = 0;
|
|
904
|
+
}
|
|
905
|
+
return this._depthMap[name][cursorIndex];
|
|
906
|
+
}
|
|
907
|
+
incrementDepth(name, cursorIndex) {
|
|
908
|
+
const depth = this.getDepth(name, cursorIndex);
|
|
909
|
+
this._depthMap[name][cursorIndex] = depth + 1;
|
|
910
|
+
}
|
|
911
|
+
decrementDepth(name, cursorIndex) {
|
|
912
|
+
const depth = this.getDepth(name, cursorIndex);
|
|
913
|
+
this._depthMap[name][cursorIndex] = depth - 1;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
/*
|
|
918
|
+
The following is created to reduce the overhead of recursion check.
|
|
919
|
+
*/
|
|
920
|
+
const depthCache$1 = new DepthCache();
|
|
883
921
|
let idIndex$6 = 0;
|
|
884
922
|
class Options {
|
|
885
923
|
get id() {
|
|
@@ -934,8 +972,12 @@ class Options {
|
|
|
934
972
|
};
|
|
935
973
|
}
|
|
936
974
|
parse(cursor) {
|
|
975
|
+
// This is a cache to help with speed
|
|
976
|
+
this._firstIndex = cursor.index;
|
|
977
|
+
depthCache$1.incrementDepth(this._id, this._firstIndex);
|
|
937
978
|
this._firstIndex = cursor.index;
|
|
938
979
|
const node = this._tryToParse(cursor);
|
|
980
|
+
depthCache$1.decrementDepth(this._id, this._firstIndex);
|
|
939
981
|
if (node != null) {
|
|
940
982
|
cursor.moveTo(node.lastIndex);
|
|
941
983
|
cursor.resolveError();
|
|
@@ -945,8 +987,8 @@ class Options {
|
|
|
945
987
|
return null;
|
|
946
988
|
}
|
|
947
989
|
_tryToParse(cursor) {
|
|
948
|
-
if (this.
|
|
949
|
-
cursor.recordErrorAt(
|
|
990
|
+
if (depthCache$1.getDepth(this._id, this._firstIndex) > 2) {
|
|
991
|
+
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
950
992
|
return null;
|
|
951
993
|
}
|
|
952
994
|
const results = [];
|
|
@@ -966,25 +1008,6 @@ class Options {
|
|
|
966
1008
|
nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
|
|
967
1009
|
return nonNullResults[0] || null;
|
|
968
1010
|
}
|
|
969
|
-
_isBeyondRecursiveLimit() {
|
|
970
|
-
let pattern = this;
|
|
971
|
-
const matches = [];
|
|
972
|
-
while (pattern.parent != null) {
|
|
973
|
-
if (pattern.type !== "options") {
|
|
974
|
-
pattern = pattern.parent;
|
|
975
|
-
continue;
|
|
976
|
-
}
|
|
977
|
-
const optionsPattern = pattern;
|
|
978
|
-
if (pattern.id === this.id && optionsPattern._firstIndex === this._firstIndex) {
|
|
979
|
-
matches.push(pattern);
|
|
980
|
-
if (matches.length > 2) {
|
|
981
|
-
return true;
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
pattern = pattern.parent;
|
|
985
|
-
}
|
|
986
|
-
return false;
|
|
987
|
-
}
|
|
988
1011
|
getTokens() {
|
|
989
1012
|
const tokens = [];
|
|
990
1013
|
for (const child of this._children) {
|
|
@@ -1577,6 +1600,7 @@ function filterOutNull(nodes) {
|
|
|
1577
1600
|
return filteredNodes;
|
|
1578
1601
|
}
|
|
1579
1602
|
|
|
1603
|
+
const depthCache = new DepthCache();
|
|
1580
1604
|
let idIndex$2 = 0;
|
|
1581
1605
|
class Sequence {
|
|
1582
1606
|
get id() {
|
|
@@ -1631,13 +1655,12 @@ class Sequence {
|
|
|
1631
1655
|
};
|
|
1632
1656
|
}
|
|
1633
1657
|
parse(cursor) {
|
|
1658
|
+
// This is a cache to help with speed
|
|
1634
1659
|
this._firstIndex = cursor.index;
|
|
1660
|
+
depthCache.incrementDepth(this._id, this._firstIndex);
|
|
1635
1661
|
this._nodes = [];
|
|
1636
|
-
if (this._isBeyondRecursiveLimit()) {
|
|
1637
|
-
cursor.recordErrorAt(cursor.index, cursor.index, this);
|
|
1638
|
-
return null;
|
|
1639
|
-
}
|
|
1640
1662
|
const passed = this.tryToParse(cursor);
|
|
1663
|
+
depthCache.decrementDepth(this._id, this._firstIndex);
|
|
1641
1664
|
if (passed) {
|
|
1642
1665
|
const node = this.createNode(cursor);
|
|
1643
1666
|
if (node !== null) {
|
|
@@ -1648,6 +1671,10 @@ class Sequence {
|
|
|
1648
1671
|
return null;
|
|
1649
1672
|
}
|
|
1650
1673
|
tryToParse(cursor) {
|
|
1674
|
+
if (depthCache.getDepth(this._id, this._firstIndex) > 1) {
|
|
1675
|
+
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
1676
|
+
return false;
|
|
1677
|
+
}
|
|
1651
1678
|
let passed = false;
|
|
1652
1679
|
for (let i = 0; i < this._children.length; i++) {
|
|
1653
1680
|
const runningCursorIndex = cursor.index;
|
|
@@ -1704,25 +1731,6 @@ class Sequence {
|
|
|
1704
1731
|
}
|
|
1705
1732
|
return passed;
|
|
1706
1733
|
}
|
|
1707
|
-
_isBeyondRecursiveLimit() {
|
|
1708
|
-
let pattern = this;
|
|
1709
|
-
const matches = [];
|
|
1710
|
-
while (pattern.parent != null) {
|
|
1711
|
-
if (pattern.type !== "sequence") {
|
|
1712
|
-
pattern = pattern.parent;
|
|
1713
|
-
continue;
|
|
1714
|
-
}
|
|
1715
|
-
const sequencePattern = pattern;
|
|
1716
|
-
if (pattern.id === this.id && sequencePattern._firstIndex === this._firstIndex) {
|
|
1717
|
-
matches.push(pattern);
|
|
1718
|
-
if (matches.length > 1) {
|
|
1719
|
-
return true;
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
|
-
pattern = pattern.parent;
|
|
1723
|
-
}
|
|
1724
|
-
return false;
|
|
1725
|
-
}
|
|
1726
1734
|
getLastValidNode() {
|
|
1727
1735
|
const nodes = filterOutNull(this._nodes);
|
|
1728
1736
|
if (nodes.length === 0) {
|