clarity-pattern-parser 10.1.26 → 10.2.1

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.d.ts CHANGED
@@ -19,4 +19,5 @@ import { ParseResult } from "./patterns/ParseResult";
19
19
  import { grammar } from "./grammar/patterns/grammar";
20
20
  import { patterns } from "./grammar/patterns";
21
21
  import { Context } from "./patterns/Context";
22
- export { Node, Grammar, AutoComplete, AutoCompleteOptions, Suggestion, SuggestionOption, Sequence, Cursor, CursorHistory, Match, Context, Literal, Not, Options, Optional, ParseError, ParseResult, Pattern, Reference, Regex, Repeat, grammar, patterns, };
22
+ import { ExpressionPattern } from "./patterns/ExpressionPattern";
23
+ export { Node, Grammar, AutoComplete, AutoCompleteOptions, Suggestion, SuggestionOption, Sequence, Cursor, CursorHistory, Match, Context, ExpressionPattern, Literal, Not, Options, Optional, ParseError, ParseResult, Pattern, Reference, Regex, Repeat, grammar, patterns, };
package/dist/index.esm.js CHANGED
@@ -120,6 +120,15 @@ class Node {
120
120
  find(predicate) {
121
121
  return this.findAll(predicate)[0] || null;
122
122
  }
123
+ findRoot() {
124
+ let pattern = this;
125
+ while (true) {
126
+ if (pattern.parent == null) {
127
+ return pattern;
128
+ }
129
+ pattern = pattern.parent;
130
+ }
131
+ }
123
132
  findAll(predicate) {
124
133
  const matches = [];
125
134
  this.walkUp(n => {
@@ -194,7 +203,7 @@ class Node {
194
203
  length = this._value.length;
195
204
  }
196
205
  else {
197
- length = this.children.reduce((acc, c) => acc + c.normalize(acc + startIndex), startIndex);
206
+ length = this.children.reduce((acc, c) => acc + c.normalize(acc + startIndex), startIndex) - startIndex;
198
207
  }
199
208
  this._firstIndex = startIndex;
200
209
  this._lastIndex = Math.max(startIndex + length - 1, 0);
@@ -968,7 +977,7 @@ function isRecursivePattern(pattern) {
968
977
  /*
969
978
  The following is created to reduce the overhead of recursion check.
970
979
  */
971
- const depthCache$1 = new DepthCache();
980
+ const depthCache$2 = new DepthCache();
972
981
  let idIndex$6 = 0;
973
982
  class Options {
974
983
  get id() {
@@ -1025,10 +1034,10 @@ class Options {
1025
1034
  parse(cursor) {
1026
1035
  // This is a cache to help with speed
1027
1036
  this._firstIndex = cursor.index;
1028
- depthCache$1.incrementDepth(this._id, this._firstIndex);
1037
+ depthCache$2.incrementDepth(this._id, this._firstIndex);
1029
1038
  this._firstIndex = cursor.index;
1030
1039
  const node = this._tryToParse(cursor);
1031
- depthCache$1.decrementDepth(this._id, this._firstIndex);
1040
+ depthCache$2.decrementDepth(this._id, this._firstIndex);
1032
1041
  if (node != null) {
1033
1042
  cursor.moveTo(node.lastIndex);
1034
1043
  cursor.resolveError();
@@ -1038,8 +1047,7 @@ class Options {
1038
1047
  return null;
1039
1048
  }
1040
1049
  _tryToParse(cursor) {
1041
- if (depthCache$1.getDepth(this._id, this._firstIndex) > 2) {
1042
- cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
1050
+ if (depthCache$2.getDepth(this._id, this._firstIndex) > 2) {
1043
1051
  return null;
1044
1052
  }
1045
1053
  const results = [];
@@ -1657,7 +1665,7 @@ function filterOutNull(nodes) {
1657
1665
  return filteredNodes;
1658
1666
  }
1659
1667
 
1660
- const depthCache = new DepthCache();
1668
+ const depthCache$1 = new DepthCache();
1661
1669
  let idIndex$2 = 0;
1662
1670
  class Sequence {
1663
1671
  get id() {
@@ -1714,10 +1722,10 @@ class Sequence {
1714
1722
  parse(cursor) {
1715
1723
  // This is a cache to help with speed
1716
1724
  this._firstIndex = cursor.index;
1717
- depthCache.incrementDepth(this._id, this._firstIndex);
1725
+ depthCache$1.incrementDepth(this._id, this._firstIndex);
1718
1726
  this._nodes = [];
1719
1727
  const passed = this.tryToParse(cursor);
1720
- depthCache.decrementDepth(this._id, this._firstIndex);
1728
+ depthCache$1.decrementDepth(this._id, this._firstIndex);
1721
1729
  if (passed) {
1722
1730
  const node = this.createNode(cursor);
1723
1731
  if (node !== null) {
@@ -1728,7 +1736,7 @@ class Sequence {
1728
1736
  return null;
1729
1737
  }
1730
1738
  tryToParse(cursor) {
1731
- if (depthCache.getDepth(this._id, this._firstIndex) > 1) {
1739
+ if (depthCache$1.getDepth(this._id, this._firstIndex) > 1) {
1732
1740
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
1733
1741
  return false;
1734
1742
  }
@@ -2673,6 +2681,387 @@ class Context {
2673
2681
  }
2674
2682
  }
2675
2683
 
2684
+ let indexId = 0;
2685
+ const depthCache = new DepthCache();
2686
+ function createNode(name, children) {
2687
+ return new Node("expression", name, 0, 0, children, "");
2688
+ }
2689
+ var Association;
2690
+ (function (Association) {
2691
+ Association[Association["left"] = 0] = "left";
2692
+ Association[Association["right"] = 1] = "right";
2693
+ })(Association || (Association = {}));
2694
+ class ExpressionPattern {
2695
+ get id() {
2696
+ return this._id;
2697
+ }
2698
+ get type() {
2699
+ return this._type;
2700
+ }
2701
+ get name() {
2702
+ return this._name;
2703
+ }
2704
+ get parent() {
2705
+ return this._parent;
2706
+ }
2707
+ set parent(pattern) {
2708
+ this._parent = pattern;
2709
+ }
2710
+ get children() {
2711
+ return this._patterns;
2712
+ }
2713
+ get unaryPatterns() {
2714
+ return this._unaryPatterns;
2715
+ }
2716
+ get binaryPatterns() {
2717
+ return this._binaryPatterns;
2718
+ }
2719
+ get recursivePatterns() {
2720
+ return this._recursivePatterns;
2721
+ }
2722
+ constructor(name, patterns) {
2723
+ if (patterns.length === 0) {
2724
+ throw new Error("Need at least one pattern with an 'expression' pattern.");
2725
+ }
2726
+ this._id = `expression-${indexId++}`;
2727
+ this._type = "expression";
2728
+ this._name = name;
2729
+ this._parent = null;
2730
+ this._firstIndex = -1;
2731
+ this._unaryPatterns = [];
2732
+ this._binaryPatterns = [];
2733
+ this._recursivePatterns = [];
2734
+ this._recursiveNames = [];
2735
+ this._binaryNames = [];
2736
+ this._binaryAssociation = [];
2737
+ this._precedenceMap = {};
2738
+ this._originalPatterns = patterns;
2739
+ this._patterns = this._organizePatterns(patterns);
2740
+ if (this._unaryPatterns.length === 0) {
2741
+ throw new Error("Need at least one operand pattern with an 'expression' pattern.");
2742
+ }
2743
+ }
2744
+ _organizePatterns(patterns) {
2745
+ const finalPatterns = [];
2746
+ patterns.forEach((pattern) => {
2747
+ if (this._isBinary(pattern)) {
2748
+ const binaryName = this._extractName(pattern);
2749
+ const clone = this._extractDelimiter(pattern).clone();
2750
+ clone.parent = this;
2751
+ this._precedenceMap[binaryName] = this._binaryPatterns.length;
2752
+ this._binaryPatterns.push(clone);
2753
+ this._binaryNames.push(binaryName);
2754
+ if (pattern.type === "right-associated") {
2755
+ this._binaryAssociation.push(Association.right);
2756
+ }
2757
+ else {
2758
+ this._binaryAssociation.push(Association.left);
2759
+ }
2760
+ finalPatterns.push(clone);
2761
+ }
2762
+ else if (this._isRecursive(pattern)) {
2763
+ const name = this._extractName(pattern);
2764
+ const tail = this._extractRecursiveTail(pattern);
2765
+ tail.parent = this;
2766
+ this._recursivePatterns.push(tail);
2767
+ this._recursiveNames.push(name);
2768
+ finalPatterns.push(tail);
2769
+ }
2770
+ else {
2771
+ const clone = pattern.clone();
2772
+ clone.parent = this;
2773
+ this._unaryPatterns.push(clone);
2774
+ finalPatterns.push(clone);
2775
+ }
2776
+ });
2777
+ return finalPatterns;
2778
+ }
2779
+ _isBinary(pattern) {
2780
+ if (pattern.type === "right-associated" && this._isBinaryPattern(pattern.children[0])) {
2781
+ return true;
2782
+ }
2783
+ return this._isBinaryPattern(pattern);
2784
+ }
2785
+ _isBinaryPattern(pattern) {
2786
+ return pattern.type === "sequence" &&
2787
+ pattern.children[0].type === "reference" &&
2788
+ pattern.children[0].name === this.name &&
2789
+ pattern.children[2].type === "reference" &&
2790
+ pattern.children[2].name === this.name &&
2791
+ pattern.children.length === 3;
2792
+ }
2793
+ _extractDelimiter(pattern) {
2794
+ if (pattern.type === "right-associated") {
2795
+ return pattern.children[0].children[1];
2796
+ }
2797
+ return pattern.children[1];
2798
+ }
2799
+ _extractName(pattern) {
2800
+ if (pattern.type === "right-associated") {
2801
+ return pattern.children[0].name;
2802
+ }
2803
+ return pattern.name;
2804
+ }
2805
+ _isRecursive(pattern) {
2806
+ if (pattern.type === "right-associated" && this._isRecursivePattern(pattern.children[0])) {
2807
+ return true;
2808
+ }
2809
+ return this._isRecursivePattern(pattern);
2810
+ }
2811
+ _isRecursivePattern(pattern) {
2812
+ return pattern.type === "sequence" &&
2813
+ pattern.children[0].type === "reference" &&
2814
+ pattern.children[0].name === this.name &&
2815
+ pattern.children.length > 2;
2816
+ }
2817
+ _extractRecursiveTail(pattern) {
2818
+ if (pattern.type === "right-associated") {
2819
+ return new Sequence(`${pattern.children[0].name}-tail`, pattern.children[0].children.slice(1));
2820
+ }
2821
+ return new Sequence(`${pattern.name}-tail`, pattern.children.slice(1));
2822
+ }
2823
+ parse(cursor) {
2824
+ // This is a cache to help with speed
2825
+ this._firstIndex = cursor.index;
2826
+ depthCache.incrementDepth(this._id, this._firstIndex);
2827
+ this._firstIndex = cursor.index;
2828
+ const node = this._tryToParse(cursor);
2829
+ depthCache.decrementDepth(this._id, this._firstIndex);
2830
+ if (node != null) {
2831
+ cursor.moveTo(node.lastIndex);
2832
+ cursor.resolveError();
2833
+ return node;
2834
+ }
2835
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
2836
+ return null;
2837
+ }
2838
+ _tryToParse(cursor) {
2839
+ if (depthCache.getDepth(this._id, this._firstIndex) > 2) {
2840
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
2841
+ return null;
2842
+ }
2843
+ let lastUnaryNode = null;
2844
+ let lastBinaryNode = null;
2845
+ let onIndex = cursor.index;
2846
+ outer: while (true) {
2847
+ onIndex = cursor.index;
2848
+ for (let i = 0; i < this._unaryPatterns.length; i++) {
2849
+ cursor.moveTo(onIndex);
2850
+ const pattern = this._unaryPatterns[i];
2851
+ const node = pattern.parse(cursor);
2852
+ if (node != null) {
2853
+ lastUnaryNode = node;
2854
+ break;
2855
+ }
2856
+ else {
2857
+ lastUnaryNode = null;
2858
+ cursor.resolveError();
2859
+ }
2860
+ }
2861
+ if (lastUnaryNode == null) {
2862
+ break;
2863
+ }
2864
+ if (cursor.hasNext()) {
2865
+ cursor.next();
2866
+ }
2867
+ else {
2868
+ if (lastBinaryNode != null && lastUnaryNode != null) {
2869
+ lastBinaryNode.appendChild(lastUnaryNode);
2870
+ }
2871
+ break;
2872
+ }
2873
+ onIndex = cursor.index;
2874
+ for (let i = 0; i < this._recursivePatterns.length; i++) {
2875
+ const pattern = this._recursivePatterns[i];
2876
+ const node = pattern.parse(cursor);
2877
+ if (node != null) {
2878
+ if (lastBinaryNode != null && lastUnaryNode != null) {
2879
+ lastBinaryNode.appendChild(lastUnaryNode);
2880
+ }
2881
+ const frontExpression = lastBinaryNode == null ? lastUnaryNode : lastBinaryNode.findRoot();
2882
+ const name = this._recursiveNames[i];
2883
+ const recursiveNode = createNode(name, [frontExpression, ...node.children]);
2884
+ recursiveNode.normalize(this._firstIndex);
2885
+ return recursiveNode;
2886
+ }
2887
+ cursor.moveTo(onIndex);
2888
+ }
2889
+ onIndex = cursor.index;
2890
+ for (let i = 0; i < this._binaryPatterns.length; i++) {
2891
+ cursor.moveTo(onIndex);
2892
+ const pattern = this._binaryPatterns[i];
2893
+ const name = this._binaryNames[i];
2894
+ const delimiterNode = pattern.parse(cursor);
2895
+ if (delimiterNode == null) {
2896
+ if (i === this._binaryPatterns.length - 1) {
2897
+ if (lastBinaryNode == null) {
2898
+ return lastUnaryNode;
2899
+ }
2900
+ else if (lastUnaryNode != null) {
2901
+ lastBinaryNode.appendChild(lastUnaryNode);
2902
+ }
2903
+ }
2904
+ continue;
2905
+ }
2906
+ if (lastBinaryNode == null && lastUnaryNode != null && delimiterNode != null) {
2907
+ const node = createNode(name, [lastUnaryNode, delimiterNode]);
2908
+ lastBinaryNode = node;
2909
+ }
2910
+ else if (lastBinaryNode != null && lastUnaryNode != null && delimiterNode != null) {
2911
+ const precedence = this._precedenceMap[name];
2912
+ const lastPrecendece = lastBinaryNode == null ? 0 : this._precedenceMap[lastBinaryNode.name];
2913
+ const association = this._binaryAssociation[i];
2914
+ if (precedence === lastPrecendece && association === Association.right) {
2915
+ const node = createNode(name, [lastUnaryNode, delimiterNode]);
2916
+ lastBinaryNode.appendChild(node);
2917
+ lastBinaryNode = node;
2918
+ }
2919
+ else if (precedence === lastPrecendece) {
2920
+ const node = createNode(name, []);
2921
+ lastBinaryNode.replaceWith(node);
2922
+ lastBinaryNode.appendChild(lastUnaryNode);
2923
+ node.append(lastBinaryNode, delimiterNode);
2924
+ lastBinaryNode = node;
2925
+ }
2926
+ else if (precedence > lastPrecendece) {
2927
+ let ancestor = lastBinaryNode.parent;
2928
+ let root = lastBinaryNode;
2929
+ while (ancestor != null) {
2930
+ const nodePrecedence = this._precedenceMap[ancestor.name];
2931
+ if (nodePrecedence > precedence) {
2932
+ break;
2933
+ }
2934
+ root = ancestor;
2935
+ ancestor = ancestor.parent;
2936
+ }
2937
+ lastBinaryNode.appendChild(lastUnaryNode);
2938
+ if (root != null) {
2939
+ const node = createNode(name, []);
2940
+ root.replaceWith(node);
2941
+ node.append(root, delimiterNode);
2942
+ lastBinaryNode = node;
2943
+ }
2944
+ else {
2945
+ const node = createNode(name, [lastUnaryNode, delimiterNode]);
2946
+ lastBinaryNode = node;
2947
+ }
2948
+ }
2949
+ else {
2950
+ const node = createNode(name, [lastUnaryNode, delimiterNode]);
2951
+ lastBinaryNode.appendChild(node);
2952
+ lastBinaryNode = node;
2953
+ }
2954
+ }
2955
+ if (cursor.hasNext()) {
2956
+ cursor.next();
2957
+ }
2958
+ else {
2959
+ break outer;
2960
+ }
2961
+ break;
2962
+ }
2963
+ if (lastBinaryNode == null) {
2964
+ break;
2965
+ }
2966
+ }
2967
+ if (lastBinaryNode == null) {
2968
+ return lastUnaryNode;
2969
+ }
2970
+ else {
2971
+ const root = lastBinaryNode.findAncestor(n => n.parent == null) || lastBinaryNode;
2972
+ if (lastBinaryNode.children.length < 3) {
2973
+ lastBinaryNode.remove();
2974
+ if (lastBinaryNode === root) {
2975
+ return lastUnaryNode;
2976
+ }
2977
+ }
2978
+ root.normalize(this._firstIndex);
2979
+ return root;
2980
+ }
2981
+ }
2982
+ test(text) {
2983
+ const cursor = new Cursor(text);
2984
+ const ast = this.parse(cursor);
2985
+ return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
2986
+ }
2987
+ exec(text, record = false) {
2988
+ const cursor = new Cursor(text);
2989
+ record && cursor.startRecording();
2990
+ const ast = this.parse(cursor);
2991
+ return {
2992
+ ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
2993
+ cursor
2994
+ };
2995
+ }
2996
+ getTokens() {
2997
+ return this.unaryPatterns.map(p => p.getTokens()).flat();
2998
+ }
2999
+ getTokensAfter(childReference) {
3000
+ if (this.unaryPatterns.indexOf(childReference)) {
3001
+ const recursiveTokens = this._recursivePatterns.map(p => p.getTokens()).flat();
3002
+ const binaryTokens = this._binaryPatterns.map(p => p.getTokens()).flat();
3003
+ return [...recursiveTokens, ...binaryTokens];
3004
+ }
3005
+ if (this.recursivePatterns.indexOf(childReference)) {
3006
+ return this._binaryPatterns.map(p => p.getTokens()).flat();
3007
+ }
3008
+ if (this.binaryPatterns.indexOf(childReference)) {
3009
+ const unaryTokens = this._unaryPatterns.map(p => p.getTokens()).flat();
3010
+ if (this._parent != null) {
3011
+ const nextTokens = this._parent.getTokensAfter(this);
3012
+ return [...unaryTokens, ...nextTokens];
3013
+ }
3014
+ return unaryTokens;
3015
+ }
3016
+ return [];
3017
+ }
3018
+ getNextTokens() {
3019
+ if (this._parent == null) {
3020
+ return [];
3021
+ }
3022
+ return this._parent.getTokensAfter(this);
3023
+ }
3024
+ getPatterns() {
3025
+ return this.unaryPatterns.map(p => p.getPatterns()).flat();
3026
+ }
3027
+ getPatternsAfter(childReference) {
3028
+ if (this.unaryPatterns.indexOf(childReference)) {
3029
+ const recursivePatterns = this._recursivePatterns.map(p => p.getPatterns()).flat();
3030
+ const binaryPatterns = this._binaryPatterns.map(p => p.getPatterns()).flat();
3031
+ return [...recursivePatterns, ...binaryPatterns];
3032
+ }
3033
+ if (this.recursivePatterns.indexOf(childReference)) {
3034
+ return this._binaryPatterns.map(p => p.getPatterns()).flat();
3035
+ }
3036
+ if (this.binaryPatterns.indexOf(childReference)) {
3037
+ const unaryPatterns = this._unaryPatterns.map(p => p.getPatterns()).flat();
3038
+ if (this._parent != null) {
3039
+ const nextPatterns = this._parent.getPatternsAfter(this);
3040
+ return [...unaryPatterns, ...nextPatterns];
3041
+ }
3042
+ return unaryPatterns;
3043
+ }
3044
+ return [];
3045
+ }
3046
+ getNextPatterns() {
3047
+ if (this._parent == null) {
3048
+ return [];
3049
+ }
3050
+ return this._parent.getPatternsAfter(this);
3051
+ }
3052
+ find(predicate) {
3053
+ return findPattern(this, predicate);
3054
+ }
3055
+ clone(name = this._name) {
3056
+ const clone = new ExpressionPattern(name, this._originalPatterns);
3057
+ clone._id = this._id;
3058
+ return clone;
3059
+ }
3060
+ isEqual(pattern) {
3061
+ return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
3062
+ }
3063
+ }
3064
+
2676
3065
  let anonymousIndexId = 0;
2677
3066
  const patternNodes = {
2678
3067
  "literal": true,
@@ -2855,9 +3244,29 @@ class Grammar {
2855
3244
  const patternNodes = node.children.filter(n => n.name !== "default-divider" && n.name !== "greedy-divider");
2856
3245
  const isGreedy = node.find(n => n.name === "greedy-divider") != null;
2857
3246
  const patterns = patternNodes.map(n => this._buildPattern(n));
3247
+ const hasRecursivePattern = patterns.some(p => this._isRecursive(name, p));
3248
+ if (hasRecursivePattern && !isGreedy) {
3249
+ try {
3250
+ const expression = new ExpressionPattern(name, patterns);
3251
+ return expression;
3252
+ }
3253
+ catch (_a) { }
3254
+ }
2858
3255
  const or = new Options(name, patterns, isGreedy);
2859
3256
  return or;
2860
3257
  }
3258
+ _isRecursive(name, pattern) {
3259
+ if (pattern.type === "right-associated" && this._isRecursivePattern(name, pattern.children[0])) {
3260
+ return true;
3261
+ }
3262
+ return this._isRecursivePattern(name, pattern);
3263
+ }
3264
+ _isRecursivePattern(name, pattern) {
3265
+ return pattern.type === "sequence" &&
3266
+ pattern.children[0].type === "reference" &&
3267
+ pattern.children[0].name === name &&
3268
+ pattern.children.length > 2;
3269
+ }
2861
3270
  _buildPattern(node) {
2862
3271
  const type = node.name;
2863
3272
  const name = `anonymous-pattern-${anonymousIndexId++}`;
@@ -3099,5 +3508,5 @@ function patterns(strings, ...values) {
3099
3508
  return result;
3100
3509
  }
3101
3510
 
3102
- export { AutoComplete, Context, Cursor, CursorHistory, Grammar, Literal, Node, Not, Optional, Options, ParseError, Reference, Regex, Repeat, Sequence, grammar, patterns };
3511
+ export { AutoComplete, Context, Cursor, CursorHistory, ExpressionPattern, Grammar, Literal, Node, Not, Optional, Options, ParseError, Reference, Regex, Repeat, Sequence, grammar, patterns };
3103
3512
  //# sourceMappingURL=index.esm.js.map