clarity-pattern-parser 6.0.2 → 7.0.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.
Files changed (88) hide show
  1. package/TODO.md +1 -78
  2. package/dist/ast/Node.d.ts +1 -0
  3. package/dist/grammar/Grammar.d.ts +17 -0
  4. package/dist/grammar/patterns/andLiteral.d.ts +2 -0
  5. package/dist/grammar/patterns/comment.d.ts +2 -0
  6. package/dist/grammar/patterns/grammar.d.ts +2 -0
  7. package/dist/grammar/patterns/literal.d.ts +2 -0
  8. package/dist/grammar/patterns/name.d.ts +2 -0
  9. package/dist/grammar/patterns/orLiteral.d.ts +2 -0
  10. package/dist/grammar/patterns/pattern.d.ts +2 -0
  11. package/dist/grammar/patterns/regexLiteral.d.ts +2 -0
  12. package/dist/grammar/patterns/repeatLiteral.d.ts +3 -0
  13. package/dist/grammar/patterns/spaces.d.ts +2 -0
  14. package/dist/grammar/patterns/statement.d.ts +2 -0
  15. package/dist/index.browser.js +1161 -556
  16. package/dist/index.browser.js.map +1 -1
  17. package/dist/index.d.ts +5 -4
  18. package/dist/index.esm.js +1159 -555
  19. package/dist/index.esm.js.map +1 -1
  20. package/dist/index.js +1159 -554
  21. package/dist/index.js.map +1 -1
  22. package/dist/intellisense/AutoComplete.d.ts +2 -6
  23. package/dist/patterns/And.d.ts +1 -1
  24. package/dist/patterns/Cursor.d.ts +1 -0
  25. package/dist/patterns/CursorHistory.d.ts +2 -1
  26. package/dist/patterns/FiniteRepeat.d.ts +39 -0
  27. package/dist/patterns/InfiniteRepeat.d.ts +47 -0
  28. package/dist/patterns/Literal.d.ts +1 -1
  29. package/dist/patterns/Not.d.ts +1 -1
  30. package/dist/patterns/Or.d.ts +1 -1
  31. package/dist/patterns/Pattern.d.ts +1 -1
  32. package/dist/patterns/Reference.d.ts +1 -1
  33. package/dist/patterns/Regex.d.ts +1 -1
  34. package/dist/patterns/Repeat.d.ts +18 -22
  35. package/jest.config.js +0 -1
  36. package/jest.coverage.config.js +13 -0
  37. package/package.json +3 -3
  38. package/src/ast/Node.test.ts +15 -0
  39. package/src/ast/Node.ts +12 -6
  40. package/src/grammar/Grammar.test.ts +306 -0
  41. package/src/grammar/Grammar.ts +249 -0
  42. package/src/grammar/patterns/andLiteral.ts +8 -0
  43. package/src/grammar/patterns/comment.ts +3 -0
  44. package/src/grammar/patterns/grammar.ts +19 -0
  45. package/src/grammar/patterns/literal.ts +5 -0
  46. package/src/grammar/patterns/name.ts +3 -0
  47. package/src/grammar/patterns/orLiteral.ts +8 -0
  48. package/src/grammar/patterns/pattern.ts +13 -0
  49. package/src/grammar/patterns/regexLiteral.ts +4 -0
  50. package/src/grammar/patterns/repeatLiteral.ts +72 -0
  51. package/src/grammar/patterns/spaces.ts +4 -0
  52. package/src/grammar/patterns/statement.ts +36 -0
  53. package/src/grammar/spec.md +142 -0
  54. package/src/index.ts +6 -3
  55. package/src/intellisense/AutoComplete.test.ts +21 -2
  56. package/src/intellisense/AutoComplete.ts +14 -25
  57. package/src/intellisense/Suggestion.ts +0 -1
  58. package/src/intellisense/css/cssValue.ts +1 -1
  59. package/src/intellisense/css/method.ts +1 -1
  60. package/src/intellisense/css/values.ts +1 -1
  61. package/src/intellisense/javascript/Javascript.test.ts +0 -1
  62. package/src/intellisense/javascript/arrayLiteral.ts +1 -1
  63. package/src/intellisense/javascript/expression.ts +1 -1
  64. package/src/intellisense/javascript/invocation.ts +1 -1
  65. package/src/intellisense/javascript/objectLiteral.ts +1 -1
  66. package/src/intellisense/javascript/parameters.ts +1 -1
  67. package/src/intellisense/javascript/stringLiteral.ts +2 -4
  68. package/src/patterns/And.test.ts +5 -5
  69. package/src/patterns/And.ts +11 -17
  70. package/src/patterns/Cursor.ts +4 -0
  71. package/src/patterns/CursorHistory.ts +34 -5
  72. package/src/patterns/FiniteRepeat.test.ts +481 -0
  73. package/src/patterns/FiniteRepeat.ts +231 -0
  74. package/src/patterns/InfiniteRepeat.test.ts +296 -0
  75. package/src/patterns/InfiniteRepeat.ts +329 -0
  76. package/src/patterns/Literal.test.ts +4 -4
  77. package/src/patterns/Literal.ts +1 -1
  78. package/src/patterns/Not.test.ts +11 -11
  79. package/src/patterns/Not.ts +1 -1
  80. package/src/patterns/Or.test.ts +9 -9
  81. package/src/patterns/Or.ts +1 -1
  82. package/src/patterns/Pattern.ts +1 -1
  83. package/src/patterns/Reference.test.ts +8 -8
  84. package/src/patterns/Reference.ts +1 -1
  85. package/src/patterns/Regex.test.ts +4 -4
  86. package/src/patterns/Regex.ts +1 -1
  87. package/src/patterns/Repeat.test.ts +160 -165
  88. package/src/patterns/Repeat.ts +95 -230
@@ -1,227 +1,222 @@
1
1
  import { Node } from "../ast/Node";
2
2
  import { And } from "./And";
3
3
  import { Cursor } from "./Cursor";
4
- import { findPattern } from "./findPattern";
4
+ import { InfiniteRepeat } from "./InfiniteRepeat";
5
5
  import { Literal } from "./Literal";
6
6
  import { Pattern } from "./Pattern";
7
7
  import { Regex } from "./Regex";
8
8
  import { Repeat } from "./Repeat";
9
9
 
10
+ // To Check all behavior look at FiniteRepeat and InfiniteRepeat.
10
11
  describe("Repeat", () => {
11
- test("Successful Parse", () => {
12
- const digit = new Regex("digit", "\\d");
13
- const integer = new Repeat("number", digit);
14
- const cursor = new Cursor("337");
15
- const result = integer.parse(cursor);
16
- const expected = new Node("repeat", "number", 0, 2, [
17
- new Node("regex", "digit", 0, 0, [], "3"),
18
- new Node("regex", "digit", 1, 1, [], "3"),
19
- new Node("regex", "digit", 2, 2, [], "7"),
12
+ test("Finite Repeat Without Min", () => {
13
+ const number = new Regex("number", "\\d");
14
+ const finiteRepeat = new Repeat("numbers", number, { max: 2 });
15
+
16
+ let cursor = new Cursor("f");
17
+ let result = finiteRepeat.parse(cursor);
18
+ let expected: Node | null = null;
19
+
20
+ expect(result).toBe(expected);
21
+ expect(cursor.hasError).toBeTruthy();
22
+
23
+ cursor = new Cursor("1");
24
+ result = finiteRepeat.parse(cursor);
25
+ expected = new Node("finite-repeat", "numbers", 0, 0, [
26
+ new Node("regex", "number", 0, 0, [], "1")
20
27
  ]);
21
28
 
22
- expect(result).toEqual(expected)
23
- expect(cursor.hasError).toBeFalsy()
24
- });
29
+ expect(result).toEqual(expected);
30
+ expect(cursor.hasError).toBeFalsy();
25
31
 
26
- test("Failed Parse", () => {
27
- const digit = new Regex("digit", "\\d");
28
- const integer = new Repeat("number", digit);
29
- const cursor = new Cursor("John");
30
- const result = integer.parse(cursor);
32
+ cursor = new Cursor("12");
33
+ result = finiteRepeat.parse(cursor);
34
+ expected = new Node("finite-repeat", "numbers", 0, 1, [
35
+ new Node("regex", "number", 0, 0, [], "1"),
36
+ new Node("regex", "number", 1, 1, [], "2")
37
+ ]);
31
38
 
32
- expect(result).toBeNull()
33
- expect(cursor.hasError).toBeTruthy()
34
- });
39
+ expect(result).toEqual(expected);
40
+ expect(cursor.hasError).toBeFalsy();
35
41
 
36
- test("Successful Parse With Divider", () => {
37
- const digit = new Regex("digit", "\\d");
38
- const divider = new Literal("divider", ",");
39
- const integer = new Repeat("number", digit, divider);
40
- const cursor = new Cursor("3,3,7");
41
- const result = integer.parse(cursor);
42
- const expected = new Node("repeat", "number", 0, 4, [
43
- new Node("regex", "digit", 0, 0, [], "3"),
44
- new Node("literal", "divider", 1, 1, [], ","),
45
- new Node("regex", "digit", 2, 2, [], "3"),
46
- new Node("literal", "divider", 3, 3, [], ","),
47
- new Node("regex", "digit", 4, 4, [], "7"),
42
+ cursor = new Cursor("123");
43
+ result = finiteRepeat.parse(cursor);
44
+ expected = new Node("finite-repeat", "numbers", 0, 1, [
45
+ new Node("regex", "number", 0, 0, [], "1"),
46
+ new Node("regex", "number", 1, 1, [], "2")
48
47
  ]);
49
48
 
50
- expect(result).toEqual(expected)
51
- expect(cursor.hasError).toBeFalsy()
49
+ expect(result).toEqual(expected);
50
+ expect(cursor.hasError).toBeFalsy();
51
+ expect(cursor.index).toBe(1);
52
52
  });
53
53
 
54
- test("Successful Parse Text Ends With Divider", () => {
55
- const digit = new Regex("digit", "\\d");
56
- const divider = new Literal("divider", ",");
57
- const integer = new Repeat("number", digit, divider);
58
- const cursor = new Cursor("3,3,7,");
59
- const result = integer.parse(cursor);
60
- const expected = new Node("repeat", "number", 0, 4, [
61
- new Node("regex", "digit", 0, 0, [], "3"),
62
- new Node("literal", "divider", 1, 1, [], ","),
63
- new Node("regex", "digit", 2, 2, [], "3"),
64
- new Node("literal", "divider", 3, 3, [], ","),
65
- new Node("regex", "digit", 4, 4, [], "7"),
54
+ test("Finite Repeat With Min", () => {
55
+ const number = new Regex("number", "\\d");
56
+ const finiteRepeat = new Repeat("numbers", number, { max: 2, min: 2 });
57
+
58
+ let cursor = new Cursor("f");
59
+ let result = finiteRepeat.parse(cursor);
60
+ let expected: Node | null = null;
61
+
62
+ expect(result).toBe(expected);
63
+ expect(cursor.hasError).toBeTruthy();
64
+
65
+ cursor = new Cursor("1");
66
+ result = finiteRepeat.parse(cursor);
67
+ expected = null;
68
+
69
+ expect(result).toEqual(expected);
70
+ expect(cursor.hasError).toBeTruthy();
71
+
72
+ cursor = new Cursor("12");
73
+ result = finiteRepeat.parse(cursor);
74
+ expected = new Node("finite-repeat", "numbers", 0, 1, [
75
+ new Node("regex", "number", 0, 0, [], "1"),
76
+ new Node("regex", "number", 1, 1, [], "2")
66
77
  ]);
67
78
 
68
- expect(result).toEqual(expected)
69
- expect(cursor.hasError).toBeFalsy()
70
- });
79
+ expect(result).toEqual(expected);
80
+ expect(cursor.hasError).toBeFalsy();
71
81
 
72
- test("Successful Parse Trailing Comma", () => {
73
- const digit = new Regex("digit", "\\d");
74
- const divider = new Literal("divider", ",");
75
- const integer = new Repeat("number", digit, divider);
76
- const cursor = new Cursor("3,3,7,t");
77
- const result = integer.parse(cursor);
78
- const expected = new Node("repeat", "number", 0, 4, [
79
- new Node("regex", "digit", 0, 0, [], "3"),
80
- new Node("literal", "divider", 1, 1, [], ","),
81
- new Node("regex", "digit", 2, 2, [], "3"),
82
- new Node("literal", "divider", 3, 3, [], ","),
83
- new Node("regex", "digit", 4, 4, [], "7"),
82
+ cursor = new Cursor("123");
83
+ result = finiteRepeat.parse(cursor);
84
+ expected = new Node("finite-repeat", "numbers", 0, 1, [
85
+ new Node("regex", "number", 0, 0, [], "1"),
86
+ new Node("regex", "number", 1, 1, [], "2")
84
87
  ]);
85
88
 
86
- expect(result).toEqual(expected)
87
- expect(cursor.hasError).toBeFalsy()
89
+ expect(result).toEqual(expected);
90
+ expect(cursor.hasError).toBeFalsy();
91
+ expect(cursor.index).toBe(1);
88
92
  });
89
93
 
90
- test("Failed (Optional)", () => {
91
- const digit = new Regex("digit", "\\d");
92
- const integer = new Repeat("number", digit, undefined, true);
93
- const cursor = new Cursor("John");
94
- const result = integer.parse(cursor);
94
+ test("Finite Repeat Get Tokens", () => {
95
+ const number = new Literal("number", "1");
96
+ const repeat = new Repeat("numbers", number);
97
+ const numberClone = repeat.find(p => p.name === "number") as Pattern;
95
98
 
96
- expect(result).toBeNull()
97
- expect(cursor.hasError).toBeFalsy()
98
- });
99
+ let tokens = repeat.getTokens();
100
+ let expected = ["1"];
99
101
 
100
- test("Get Tokens", () => {
101
- const a = new Literal("a", "A");
102
- const manyA = new Repeat("number", a);
103
- const tokens = manyA.getTokens();
104
- const expected = ["A"];
102
+ expect(tokens).toEqual(expected);
105
103
 
106
- expect(tokens).toEqual(expected)
107
- });
104
+ tokens = repeat.getNextTokens();
105
+ expected = [];
106
+
107
+ expect(tokens).toEqual(expected);
108
108
 
109
- test("Get Tokens After With Bogus Pattern", () => {
110
- const a = new Literal("a", "A");
111
- const manyA = new Repeat("many-a", a);
112
- const tokens = manyA.getTokensAfter(new Literal("bogus", "bogus"));
113
- const expected: string[] = [];
109
+ tokens = repeat.getTokensAfter(numberClone);
110
+ expected = [];
114
111
 
115
- expect(tokens).toEqual(expected)
112
+ expect(tokens).toEqual(expected);
116
113
  });
117
114
 
118
- test("Get Tokens After With Divider", () => {
119
- const a = new Literal("a", "A");
120
- const b = new Literal("b", "B");
121
- const divider = new Literal("divider", ",");
122
- const manyA = new Repeat("many-a", a, divider);
123
- const parent = new And("parent", [manyA, b]);
115
+ test("Get Tokens After", () => {
116
+ const number = new Literal("number", "1");
117
+ const repeat = new Repeat("numbers", number);
118
+ const parent = new And("parent", [repeat, new Literal("b", "B")]);
119
+ const numberClone = parent.find(p => p.name === "number") as Pattern;
120
+ const repeatClone = parent.children[0];
124
121
 
125
- const clonedManyA = findPattern(parent, p => p.name == "many-a");
126
- let tokens = clonedManyA?.getTokensAfter(clonedManyA.children[0]);
127
- let expected = [",", "B"];
122
+ let tokens = repeatClone.getTokensAfter(numberClone);
123
+ let expected = ["B"];
128
124
 
129
- expect(tokens).toEqual(expected)
125
+ expect(tokens).toEqual(expected);
126
+ });
130
127
 
131
- tokens = clonedManyA?.getTokensAfter(clonedManyA.children[1]);
132
- expected = ["A"];
128
+ test("Get Next Tokens", () => {
129
+ const number = new Literal("number", "1");
130
+ const repeat = new Repeat("numbers", number);
131
+ const parent = new And("parent", [repeat, new Literal("b", "B")]);
132
+ const repeatClone = parent.children[0];
133
133
 
134
- expect(tokens).toEqual(expected)
134
+ let tokens = repeatClone.getNextTokens();
135
+ let expected = ["B"];
136
+
137
+ expect(tokens).toEqual(expected);
135
138
  });
136
139
 
137
- test("Get Tokens After Without Divider", () => {
138
- const a = new Literal("a", "A");
139
- const b = new Literal("b", "B");
140
- const manyA = new Repeat("many-a", a);
141
- const parent = new And("parent", [manyA, b]);
140
+ test("Get Next Patterns", () => {
141
+ const number = new Literal("number", "1");
142
+ const repeat = new Repeat("numbers", number);
143
+ const parent = new And("parent", [repeat, new Literal("b", "B")]);
144
+ const repeatClone = parent.children[0];
145
+ const bClone = parent.find(p => p.name === "b") as Pattern;
142
146
 
143
- const clonedManyA = findPattern(parent, p => p.name == "many-a");
144
- const tokens = clonedManyA?.getTokensAfter(clonedManyA.children[0]);
145
- const expected = ["A", "B"];
147
+ let patterns = repeatClone.getNextPatterns();
148
+ let expected = [bClone];
146
149
 
147
- expect(tokens).toEqual(expected)
150
+ expect(patterns).toEqual(expected);
148
151
  });
149
152
 
150
- test("Properties", () => {
151
- const integer = new Repeat("integer", new Regex("digit", "\\d"));
153
+ test("Repeat Get Patterns", () => {
154
+ const number = new Literal("number", "1");
155
+ const repeat = new Repeat("numbers", number);
156
+ const numberClone = repeat.find(p => p.name === "number") as Pattern;
152
157
 
153
- expect(integer.type).toBe("repeat");
154
- expect(integer.name).toBe("integer");
155
- expect(integer.isOptional).toBeFalsy()
156
- expect(integer.parent).toBeNull();
157
- expect(integer.children[0].name).toBe("digit");
158
- });
158
+ let patterns = repeat.getPatterns();
159
+ let expected = [numberClone];
159
160
 
160
- test("Exec", () => {
161
- const integer = new Repeat("integer", new Regex("digit", "\\d"));
162
- const { ast: result } = integer.exec("B");
163
- expect(result).toBeNull()
164
- });
161
+ expect(patterns).toEqual(expected);
165
162
 
166
- test("Test With Match", () => {
167
- const integer = new Repeat("integer", new Regex("digit", "\\d"));
168
- const result = integer.test("1");
169
- expect(result).toBeTruthy()
170
- });
163
+ patterns = repeat.getNextPatterns();
164
+ expected = [];
171
165
 
172
- test("Test With No Match", () => {
173
- const integer = new Repeat("integer", new Regex("digit", "\\d"));
174
- const result = integer.test("b");
175
- expect(result).toBeFalsy()
176
- });
166
+ expect(patterns).toEqual(expected);
177
167
 
178
- test("Get Next Tokens", () => {
179
- const integer = new Repeat("integer", new Regex("digit", "\\d"));
180
- const parent = new And("parent", [integer, new Literal("pow", "!")]);
181
- const integerClone = parent.findPattern(p => p.name === "integer") as Pattern;
182
- const tokens = integerClone.getNextTokens();
168
+ patterns = repeat.getPatternsAfter(numberClone);
169
+ expected = [];
183
170
 
184
- expect(tokens).toEqual(["!"])
171
+ expect(patterns).toEqual(expected);
185
172
  });
186
173
 
187
- test("Get Next Tokens With Null Parents", () => {
188
- const integer = new Repeat("integer", new Regex("digit", "\\d"));
189
- const tokens = integer.getNextTokens();
174
+ test("Repeat Properties", () => {
175
+ const number = new Literal("number", "1");
176
+ const repeat = new Repeat("numbers", number);
190
177
 
191
- expect(tokens.length).toBe(0);
178
+ expect(repeat.type).toBe("infinite-repeat");
179
+ expect(repeat.name).toBe("numbers");
180
+ expect(repeat.parent).toBeNull();
181
+ expect(repeat.isOptional).toBeFalsy();
192
182
  });
193
183
 
194
- test("Find Pattern", () => {
195
- const integer = new Repeat("integer", new Regex("digit", "\\d"));
196
- const digitClone = integer.findPattern(p => p.name === "digit") as Pattern;
184
+ test("test", () => {
185
+ const number = new Literal("number", "1");
186
+ const repeat = new Repeat("numbers", number);
187
+ let result = repeat.test("1");
188
+ let expected = true;
197
189
 
198
- expect(digitClone).not.toBeNull();
199
- });
190
+ expect(result).toBe(expected);
200
191
 
201
- test("Get Patterns", () => {
202
- const a = new Literal("a", "A");
203
- const manyA = new Repeat("number", a);
204
- const patterns = manyA.getPatterns();
205
- const expected = [manyA.findPattern(p => p.name === "a")];
192
+ result = repeat.test("g");
193
+ expected = false;
206
194
 
207
- expect(patterns).toEqual(expected)
195
+ expect(result).toBe(expected);
208
196
  });
209
197
 
210
- test("Get Next Patterns", () => {
211
- const integer = new Repeat("integer", new Regex("digit", "\\d"));
212
- const parent = new And("parent", [integer, new Literal("pow", "!")]);
213
- const integerClone = parent.findPattern(p => p.name === "integer") as Pattern;
214
- const powClone = parent.findPattern(p => p.name === "pow") as Pattern;
215
- const patterns = integerClone.getNextPatterns();
216
-
217
- expect(patterns.length).toBe(1);
218
- expect(patterns[0]).toBe(powClone);
219
- });
198
+ test("Repeat Clone", () => {
199
+ const number = new Literal("number", "1");
200
+ const repeat = new Repeat("numbers", number);
201
+
202
+ let repeatClone = repeat.clone();
203
+ let expected = new Repeat("numbers", number);
204
+
205
+ expect(repeatClone).toEqual(expected);
206
+
207
+ repeatClone = repeat.clone("new-name");
208
+ expected = new Repeat("new-name", number);
209
+
210
+ expect(repeatClone).toEqual(expected);
211
+
212
+ repeatClone = repeat.clone("new-name", false);
213
+ expected = new Repeat("new-name", number);
214
+
215
+ expect(repeatClone).toEqual(expected);
220
216
 
221
- test("Get Next Patterns With Null Parents", () => {
222
- const integer = new Repeat("integer", new Regex("digit", "\\d"));
223
- const patterns = integer.getNextPatterns();
217
+ repeatClone = repeat.clone("new-name", true);
218
+ expected = new Repeat("new-name", number, { min: 0 });
224
219
 
225
- expect(patterns.length).toBe(0);
220
+ expect(repeatClone).toEqual(expected);
226
221
  });
227
222
  });