clarity-pattern-parser 3.0.15 → 4.0.0

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 (168) hide show
  1. package/README.md +0 -191
  2. package/dist/ast/Node.d.ts +4 -5
  3. package/dist/index.browser.js +476 -731
  4. package/dist/index.browser.js.map +1 -1
  5. package/dist/index.d.ts +10 -18
  6. package/dist/index.esm.js +469 -716
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/index.js +476 -731
  9. package/dist/index.js.map +1 -1
  10. package/dist/patterns/And.d.ts +24 -0
  11. package/dist/patterns/Literal.d.ts +19 -0
  12. package/dist/patterns/LookAhead.d.ts +8 -0
  13. package/dist/patterns/Not.d.ts +11 -0
  14. package/dist/patterns/Or.d.ts +22 -0
  15. package/dist/patterns/Pattern.d.ts +6 -7
  16. package/dist/patterns/{RecursivePattern.d.ts → Recursive.d.ts} +4 -4
  17. package/dist/patterns/Reference.d.ts +14 -0
  18. package/dist/patterns/Regex.d.ts +21 -0
  19. package/dist/patterns/Repeat.d.ts +20 -0
  20. package/package.json +1 -1
  21. package/src/CursorHistory.ts +1 -1
  22. package/src/ast/Node.ts +20 -17
  23. package/src/ast/Visitor.ts +14 -18
  24. package/src/index.ts +17 -33
  25. package/src/patterns/And.ts +178 -0
  26. package/src/patterns/Literal.ts +91 -0
  27. package/src/patterns/LookAhead.ts +32 -0
  28. package/src/patterns/Not.ts +50 -0
  29. package/src/patterns/Or.ts +132 -0
  30. package/src/patterns/Pattern.ts +31 -47
  31. package/src/patterns/Recursive.ts +92 -0
  32. package/src/patterns/Reference.ts +127 -0
  33. package/src/patterns/Regex.ts +123 -0
  34. package/src/patterns/Repeat.ts +155 -0
  35. package/src/tests/{AndValue.test.ts → And.test.ts} +31 -41
  36. package/src/tests/CursorHistory.test.ts +6 -6
  37. package/src/tests/Cusor.test.ts +7 -10
  38. package/src/tests/Literal.test.ts +3 -5
  39. package/src/tests/LookAhead.test.ts +44 -0
  40. package/src/tests/Not.test.ts +51 -0
  41. package/src/tests/Or.test.ts +113 -0
  42. package/src/tests/Pattern.test.ts +41 -141
  43. package/src/tests/{RecursivePattern.test.ts → Recursive.test.ts} +10 -8
  44. package/src/tests/Reference.test.ts +16 -0
  45. package/src/tests/{RepeatValue.test.ts → Repeat.test.ts} +10 -42
  46. package/src/tests/TextSuggester.test.ts +20 -28
  47. package/src/tests/{NodeVisitor.test.ts → Visitor.test.ts} +42 -21
  48. package/src/tests/cssPatterns/cssValue.ts +2 -2
  49. package/src/tests/cssPatterns/divider.ts +2 -2
  50. package/src/tests/cssPatterns/hex.ts +2 -2
  51. package/src/tests/cssPatterns/method.ts +7 -9
  52. package/src/tests/cssPatterns/name.ts +2 -2
  53. package/src/tests/cssPatterns/number.ts +2 -2
  54. package/src/tests/cssPatterns/optionalSpaces.ts +1 -2
  55. package/src/tests/cssPatterns/spaces.ts +2 -2
  56. package/src/tests/cssPatterns/unit.ts +3 -3
  57. package/src/tests/cssPatterns/value.ts +2 -2
  58. package/src/tests/cssPatterns/values.ts +2 -2
  59. package/src/tests/htmlPatterns/element.ts +18 -33
  60. package/src/tests/javascriptPatterns/boolean.ts +2 -3
  61. package/src/tests/javascriptPatterns/json.ts +14 -24
  62. package/src/tests/javascriptPatterns/name.ts +3 -20
  63. package/src/tests/javascriptPatterns/number.ts +2 -2
  64. package/src/tests/javascriptPatterns/objectLiteral.ts +9 -16
  65. package/src/tests/javascriptPatterns/string.ts +26 -24
  66. package/src/tests/javascriptPatterns/unit.ts +3 -6
  67. package/src/tests/javascriptPatterns/whitespace.ts +8 -12
  68. package/src/tests/naturalLanguage/filter.ts +16 -33
  69. package/src/tests/patterns/sentence.ts +8 -8
  70. package/dist/Cursor.js +0 -105
  71. package/dist/Cursor.js.map +0 -1
  72. package/dist/CursorHistory.js +0 -104
  73. package/dist/CursorHistory.js.map +0 -1
  74. package/dist/Permutor.d.ts +0 -13
  75. package/dist/Permutor.js +0 -52
  76. package/dist/Permutor.js.map +0 -1
  77. package/dist/TextSuggester.js +0 -244
  78. package/dist/TextSuggester.js.map +0 -1
  79. package/dist/ast/CompositeNode.d.ts +0 -6
  80. package/dist/ast/CompositeNode.js +0 -17
  81. package/dist/ast/CompositeNode.js.map +0 -1
  82. package/dist/ast/Node.js +0 -16
  83. package/dist/ast/Node.js.map +0 -1
  84. package/dist/ast/NodeVisitor.d.ts +0 -31
  85. package/dist/ast/ValueNode.d.ts +0 -6
  86. package/dist/ast/ValueNode.js +0 -14
  87. package/dist/ast/ValueNode.js.map +0 -1
  88. package/dist/ast/Visitor.js +0 -209
  89. package/dist/ast/Visitor.js.map +0 -1
  90. package/dist/patterns/ParseError.js +0 -9
  91. package/dist/patterns/ParseError.js.map +0 -1
  92. package/dist/patterns/Pattern.js +0 -127
  93. package/dist/patterns/Pattern.js.map +0 -1
  94. package/dist/patterns/RecursivePattern.js +0 -65
  95. package/dist/patterns/RecursivePattern.js.map +0 -1
  96. package/dist/patterns/composite/AndComposite.d.ts +0 -22
  97. package/dist/patterns/composite/AndComposite.js +0 -117
  98. package/dist/patterns/composite/AndComposite.js.map +0 -1
  99. package/dist/patterns/composite/CompositePattern.d.ts +0 -4
  100. package/dist/patterns/composite/CompositePattern.js +0 -7
  101. package/dist/patterns/composite/CompositePattern.js.map +0 -1
  102. package/dist/patterns/composite/OptionalComposite.d.ts +0 -10
  103. package/dist/patterns/composite/OptionalComposite.js +0 -29
  104. package/dist/patterns/composite/OptionalComposite.js.map +0 -1
  105. package/dist/patterns/composite/OrComposite.d.ts +0 -16
  106. package/dist/patterns/composite/OrComposite.js +0 -69
  107. package/dist/patterns/composite/OrComposite.js.map +0 -1
  108. package/dist/patterns/composite/RepeatComposite.d.ts +0 -21
  109. package/dist/patterns/composite/RepeatComposite.js +0 -88
  110. package/dist/patterns/composite/RepeatComposite.js.map +0 -1
  111. package/dist/patterns/value/AndValue.d.ts +0 -21
  112. package/dist/patterns/value/AndValue.js +0 -118
  113. package/dist/patterns/value/AndValue.js.map +0 -1
  114. package/dist/patterns/value/AnyOfThese.d.ts +0 -18
  115. package/dist/patterns/value/AnyOfThese.js +0 -59
  116. package/dist/patterns/value/AnyOfThese.js.map +0 -1
  117. package/dist/patterns/value/Literal.d.ts +0 -20
  118. package/dist/patterns/value/Literal.js +0 -63
  119. package/dist/patterns/value/Literal.js.map +0 -1
  120. package/dist/patterns/value/NotValue.d.ts +0 -17
  121. package/dist/patterns/value/NotValue.js +0 -70
  122. package/dist/patterns/value/NotValue.js.map +0 -1
  123. package/dist/patterns/value/OptionalValue.d.ts +0 -9
  124. package/dist/patterns/value/OptionalValue.js +0 -32
  125. package/dist/patterns/value/OptionalValue.js.map +0 -1
  126. package/dist/patterns/value/OrValue.d.ts +0 -19
  127. package/dist/patterns/value/OrValue.js +0 -73
  128. package/dist/patterns/value/OrValue.js.map +0 -1
  129. package/dist/patterns/value/RegexValue.d.ts +0 -19
  130. package/dist/patterns/value/RegexValue.js +0 -69
  131. package/dist/patterns/value/RegexValue.js.map +0 -1
  132. package/dist/patterns/value/RepeatValue.d.ts +0 -19
  133. package/dist/patterns/value/RepeatValue.js +0 -89
  134. package/dist/patterns/value/RepeatValue.js.map +0 -1
  135. package/dist/patterns/value/ValuePattern.d.ts +0 -5
  136. package/dist/patterns/value/ValuePattern.js +0 -7
  137. package/dist/patterns/value/ValuePattern.js.map +0 -1
  138. package/src/Permutor.ts +0 -64
  139. package/src/ast/CompositeNode.ts +0 -26
  140. package/src/ast/ValueNode.ts +0 -28
  141. package/src/patterns/RecursivePattern.ts +0 -86
  142. package/src/patterns/composite/AndComposite.ts +0 -159
  143. package/src/patterns/composite/CompositePattern.ts +0 -7
  144. package/src/patterns/composite/OptionalComposite.ts +0 -37
  145. package/src/patterns/composite/OrComposite.ts +0 -96
  146. package/src/patterns/composite/RepeatComposite.ts +0 -130
  147. package/src/patterns/value/AndValue.ts +0 -153
  148. package/src/patterns/value/AnyOfThese.ts +0 -81
  149. package/src/patterns/value/Literal.ts +0 -92
  150. package/src/patterns/value/NotValue.ts +0 -95
  151. package/src/patterns/value/OptionalValue.ts +0 -39
  152. package/src/patterns/value/OrValue.ts +0 -103
  153. package/src/patterns/value/RegexValue.ts +0 -103
  154. package/src/patterns/value/RepeatValue.ts +0 -131
  155. package/src/patterns/value/ValuePattern.ts +0 -8
  156. package/src/tests/AndComposite.test.ts +0 -102
  157. package/src/tests/AnyOfThese.test.ts +0 -74
  158. package/src/tests/CompositeNode.test.ts +0 -33
  159. package/src/tests/NotValue.test.ts +0 -69
  160. package/src/tests/OptionalValue.test.ts +0 -50
  161. package/src/tests/OrComposite.test.ts +0 -75
  162. package/src/tests/OrValue.test.ts +0 -171
  163. package/src/tests/Permutor.test.ts +0 -30
  164. package/src/tests/RegexValue.test.ts +0 -22
  165. package/src/tests/RepeatComposite.test.ts +0 -58
  166. package/src/tests/ValueNode.test.ts +0 -24
  167. package/src/tests/javascriptPatterns/varStatement.ts +0 -0
  168. package/src/tests/readmeDemo.test.ts +0 -124
@@ -1,130 +0,0 @@
1
- import CompositePattern from "./CompositePattern";
2
- import CompositeNode from "../../ast/CompositeNode";
3
- import ParseError from "../ParseError";
4
- import OptionalComposite from "./OptionalComposite";
5
- import Pattern from "../Pattern";
6
- import Cursor from "../../Cursor";
7
- import Node from "../../ast/Node";
8
-
9
- export default class RepeatComposite extends CompositePattern {
10
- private _pattern: Pattern;
11
- private _divider: Pattern;
12
- public nodes: Node[] = [];
13
- public cursor!: Cursor;
14
- public mark: number = 0;
15
- public node: CompositeNode | null = null;
16
-
17
- constructor(name: string, pattern: Pattern, divider?: Pattern) {
18
- super(
19
- "repeat-composite",
20
- name,
21
- divider != null ? [pattern, divider] : [pattern]
22
- );
23
- this._pattern = this.children[0];
24
- this._divider = this.children[1];
25
- this._assertArguments();
26
- }
27
-
28
- private _assertArguments() {
29
- if (this._pattern instanceof OptionalComposite) {
30
- throw new Error(
31
- "Invalid Arguments: The pattern cannot be a optional pattern."
32
- );
33
- }
34
- }
35
-
36
- private _reset(cursor: Cursor) {
37
- this.nodes = [];
38
- this.cursor = cursor;
39
- this.mark = this.cursor.mark();
40
- }
41
-
42
- parse(cursor: Cursor) {
43
- this._reset(cursor);
44
- this._tryPattern();
45
-
46
- return this.node;
47
- }
48
-
49
- private _tryPattern() {
50
- while (true) {
51
- const node = this._pattern.parse(this.cursor);
52
-
53
- if (this.cursor.hasUnresolvedError() || node == null) {
54
- this._processMatch();
55
- break;
56
- } else {
57
- this.nodes.push(node);
58
-
59
- if (node.endIndex === this.cursor.lastIndex()) {
60
- this._processMatch();
61
- break;
62
- }
63
-
64
- this.cursor.next();
65
-
66
- if (this._divider != null) {
67
- const mark = this.cursor.mark();
68
- const node = this._divider.parse(this.cursor);
69
-
70
- if (this.cursor.hasUnresolvedError() || node == null) {
71
- this.cursor.moveToMark(mark);
72
- this._processMatch();
73
- break;
74
- } else {
75
- this.nodes.push(node);
76
-
77
- if (node.endIndex === this.cursor.lastIndex()) {
78
- this._processMatch();
79
- break;
80
- }
81
-
82
- this.cursor.next();
83
- }
84
- }
85
- }
86
- }
87
- }
88
-
89
- private _processMatch() {
90
- const endsOnDivider = this.nodes.length % 2 === 0;
91
- const noMatch = this.nodes.length === 0;
92
- const hasDivider = this._divider != null;
93
-
94
- this.cursor.resolveError();
95
-
96
- if ((hasDivider && endsOnDivider) || noMatch) {
97
- this.cursor.throwError(
98
- new ParseError(
99
- `Did not find a repeating match of ${this.name}.`,
100
- this.mark,
101
- this
102
- )
103
- );
104
- this.node = null;
105
- } else {
106
- this.node = new CompositeNode(
107
- "repeat-composite",
108
- this.name,
109
- this.nodes[0].startIndex,
110
- this.nodes[this.nodes.length - 1].endIndex
111
- );
112
-
113
- this.node.children = this.nodes;
114
- this.cursor.index = this.node.endIndex;
115
-
116
- this.cursor.addMatch(this, this.node);
117
- }
118
- }
119
-
120
- clone(name?: string) {
121
- if (typeof name !== "string") {
122
- name = this.name;
123
- }
124
- return new RepeatComposite(name, this._pattern, this._divider);
125
- }
126
-
127
- getTokens() {
128
- return this._pattern.getTokens();
129
- }
130
- }
@@ -1,153 +0,0 @@
1
- import ValuePattern from "./ValuePattern";
2
- import ValueNode from "../../ast/ValueNode";
3
- import ParseError from "../../patterns/ParseError";
4
- import OptionalValue from "./OptionalValue";
5
- import Permutor from "../../Permutor";
6
- import Pattern from "../Pattern";
7
- import Cursor from "../../Cursor";
8
-
9
- const permutor = new Permutor();
10
-
11
- export default class AndValue extends ValuePattern {
12
- public index: number = 0;
13
- public nodes: ValueNode[] = [];
14
- public node: ValueNode | null = null;
15
- public cursor!: Cursor;
16
- public mark: number = 0;
17
-
18
- constructor(name: string, patterns: ValuePattern[]) {
19
- super("and-value", name, patterns);
20
- this._assertArguments();
21
- }
22
-
23
- private _assertArguments() {
24
- if (this._children.length < 2) {
25
- throw new Error(
26
- "Invalid Argument: AndValue needs to have more than one value pattern."
27
- );
28
- }
29
- }
30
-
31
- private _reset(cursor: Cursor) {
32
- this.index = 0;
33
- this.nodes = [];
34
- this.node = null;
35
- this.cursor = cursor;
36
- this.mark = this.cursor.mark();
37
- }
38
-
39
- parse(cursor: Cursor) {
40
- this._reset(cursor);
41
- this._tryPatterns();
42
-
43
- return this.node;
44
- }
45
-
46
- private _tryPatterns() {
47
- while (true) {
48
- const pattern = this._children[this.index];
49
- const node = pattern.parse(this.cursor) as ValueNode;
50
-
51
- if (this.cursor.hasUnresolvedError()) {
52
- break;
53
- } else {
54
- this.nodes.push(node);
55
- }
56
-
57
- if (!this._next()) {
58
- this._processValue();
59
- break;
60
- }
61
- }
62
- }
63
-
64
- private _next() {
65
- if (this._hasMorePatterns()) {
66
- if (this.cursor.hasNext()) {
67
- // If the last result was a failed optional, then don't increment the cursor.
68
- if (this.nodes[this.nodes.length - 1] != null) {
69
- this.cursor.next();
70
- }
71
-
72
- this.index++;
73
- return true;
74
- } else if (this.nodes[this.nodes.length - 1] == null) {
75
- this.index++;
76
- return true;
77
- }
78
-
79
- this._assertRestOfPatternsAreOptional();
80
- return false;
81
- } else {
82
- return false;
83
- }
84
- }
85
-
86
- private _hasMorePatterns() {
87
- return this.index + 1 < this._children.length;
88
- }
89
-
90
- private _assertRestOfPatternsAreOptional() {
91
- const areTheRestOptional = this.children.every((pattern, index) => {
92
- return index <= this.index || pattern instanceof OptionalValue;
93
- });
94
-
95
- if (!areTheRestOptional) {
96
- const parseError = new ParseError(
97
- `Could not match ${this.name} before string ran out.`,
98
- this.index,
99
- this
100
- );
101
-
102
- this.cursor.throwError(parseError);
103
- }
104
- }
105
-
106
- private _processValue() {
107
- if (this.cursor.hasUnresolvedError()) {
108
- this.node = null;
109
- } else {
110
- this.nodes = this.nodes.filter((node) => node != null);
111
-
112
- const lastNode = this.nodes[this.nodes.length - 1];
113
- const startIndex = this.mark;
114
- const endIndex = lastNode.endIndex;
115
- const value = this.nodes.map((node) => node.value).join("");
116
-
117
- this.node = new ValueNode(
118
- "and-value",
119
- this.name,
120
- value,
121
- startIndex,
122
- endIndex
123
- );
124
-
125
- this.cursor.index = this.node.endIndex;
126
- this.cursor.addMatch(this, this.node);
127
- }
128
- }
129
-
130
- clone(name?: string) {
131
- if (typeof name !== "string") {
132
- name = this.name;
133
- }
134
- return new AndValue(name, this._children as ValuePattern[]);
135
- }
136
-
137
- getTokens() {
138
- let tokens: string[] = [];
139
-
140
- for (let x = 0; x < this._children.length; x++) {
141
- const child = this._children[x];
142
-
143
- if (child instanceof OptionalValue) {
144
- tokens = tokens.concat(child.getTokens());
145
- } else {
146
- tokens = tokens.concat(child.getTokens());
147
- break;
148
- }
149
- }
150
-
151
- return tokens;
152
- }
153
- }
@@ -1,81 +0,0 @@
1
- import ValuePattern from "./ValuePattern";
2
- import ParseError from "../ParseError";
3
- import ValueNode from "../../ast/ValueNode";
4
- import Pattern from "../Pattern";
5
- import Cursor from "../../Cursor";
6
-
7
- export default class AnyOfThese extends ValuePattern {
8
- public characters: string;
9
- public node: ValueNode | null = null;
10
- public cursor!: Cursor;
11
- public mark: number = 0;
12
-
13
- constructor(name: string, characters: string) {
14
- super("any-of-these", name);
15
- this.characters = characters;
16
- this._assertArguments();
17
- }
18
-
19
- private _assertArguments() {
20
- if (typeof this.characters !== "string") {
21
- throw new Error(
22
- "Invalid Arguments: The characters argument needs to be a string of characters."
23
- );
24
- }
25
-
26
- if (this.characters.length < 1) {
27
- throw new Error(
28
- "Invalid Arguments: The characters argument needs to be at least one character long."
29
- );
30
- }
31
- }
32
-
33
- parse(cursor: Cursor) {
34
- this._reset(cursor);
35
- this._tryPattern();
36
- return this.node;
37
- }
38
-
39
- private _reset(cursor: Cursor) {
40
- this.cursor = cursor;
41
- this.mark = this.cursor.mark();
42
- this.node = null;
43
- }
44
-
45
- private _tryPattern() {
46
- if (this._isMatch()) {
47
- const value = this.cursor.getChar();
48
- const index = this.cursor.getIndex();
49
-
50
- this.node = new ValueNode("any-of-these", this.name, value, index, index);
51
-
52
- this.cursor.addMatch(this, this.node);
53
- } else {
54
- this._processError();
55
- }
56
- }
57
-
58
- private _isMatch() {
59
- return this.characters.indexOf(this.cursor.getChar()) > -1;
60
- }
61
-
62
- private _processError() {
63
- const message = `ParseError: Expected one of these characters, '${
64
- this.characters
65
- }' but found '${this.cursor.getChar()}' while parsing for '${this.name}'.`;
66
-
67
- const parseError = new ParseError(message, this.cursor.getIndex(), this);
68
- this.cursor.throwError(parseError);
69
- }
70
-
71
- clone(name?: string) {
72
- if (typeof name !== "string") {
73
- name = this.name;
74
- }
75
- return new AnyOfThese(name, this.characters);
76
- }
77
-
78
- getTokens() {
79
- return this.characters.split("");
80
- }
81
- }
@@ -1,92 +0,0 @@
1
- import ParseError from "../ParseError";
2
- import ValueNode from "../../ast/ValueNode";
3
- import ValuePattern from "./ValuePattern";
4
- import Cursor from "../../Cursor";
5
-
6
- export default class Literal extends ValuePattern {
7
- public literal: string;
8
- public node: ValueNode | null = null;
9
- public cursor!: Cursor;
10
- public mark: number = 0;
11
- public substring: string = "";
12
-
13
- constructor(name: string, literal: string) {
14
- super("literal", name);
15
- this.literal = literal;
16
- this._assertArguments();
17
- }
18
-
19
- private _assertArguments() {
20
- if (typeof this.literal !== "string") {
21
- throw new Error(
22
- "Invalid Arguments: The literal argument needs to be a string of characters."
23
- );
24
- }
25
-
26
- if (this.literal.length < 1) {
27
- throw new Error(
28
- "Invalid Arguments: The literalString argument needs to be at least one character long."
29
- );
30
- }
31
- }
32
-
33
- parse(cursor: Cursor) {
34
- this._reset(cursor);
35
- this._tryPattern();
36
-
37
- return this.node;
38
- }
39
-
40
- private _reset(cursor: Cursor) {
41
- this.cursor = cursor;
42
- this.mark = this.cursor.mark();
43
- this.substring = this.cursor.text.substring(
44
- this.mark,
45
- this.mark + this.literal.length
46
- );
47
- this.node = null;
48
- }
49
-
50
- private _tryPattern() {
51
- if (this.substring === this.literal) {
52
- this._processMatch();
53
- } else {
54
- this._processError();
55
- }
56
- }
57
-
58
- private _processError() {
59
- const message = `ParseError: Expected '${this.literal}' but found '${this.substring}'.`;
60
-
61
- const parseError = new ParseError(message, this.cursor.getIndex(), this);
62
- this.cursor.throwError(parseError);
63
- }
64
-
65
- private _processMatch() {
66
- this.node = new ValueNode(
67
- "literal",
68
- this.name,
69
- this.substring,
70
- this.mark,
71
- this.mark + this.literal.length - 1
72
- );
73
-
74
- this.cursor.index = this.node.endIndex;
75
- this.cursor.addMatch(this, this.node);
76
- }
77
-
78
- clone(name?: string) {
79
- if (typeof name !== "string") {
80
- name = this.name;
81
- }
82
- return new Literal(name, this.literal);
83
- }
84
-
85
- getTokenValue() {
86
- return this.literal;
87
- }
88
-
89
- getTokens() {
90
- return [this.getTokenValue()];
91
- }
92
- }
@@ -1,95 +0,0 @@
1
- import ValuePattern from "./ValuePattern";
2
- import ValueNode from "../../ast/ValueNode";
3
- import ParseError from "../ParseError";
4
- import Pattern from "../Pattern";
5
- import Cursor from "../../Cursor";
6
-
7
- export default class NotValue extends ValuePattern {
8
- public match: string = "";
9
- public node: ValueNode | null = null;
10
- public cursor!: Cursor;
11
- public mark: number = 0;
12
-
13
- constructor(name: string, pattern: ValuePattern) {
14
- super("not-value", name, [pattern]);
15
- this._assertArguments();
16
- }
17
-
18
- private _assertArguments() {
19
- if (!(this.children[0] instanceof Pattern)) {
20
- throw new Error(
21
- "Invalid Arguments: Expected the pattern to be a ValuePattern."
22
- );
23
- }
24
-
25
- if (typeof this.name !== "string") {
26
- throw new Error("Invalid Arguments: Expected name to be a string.");
27
- }
28
- }
29
-
30
- private _reset(cursor: Cursor) {
31
- this.match = "";
32
- this.node = null;
33
- this.cursor = cursor;
34
- this.mark = this.cursor.mark();
35
- }
36
-
37
- parse(cursor: Cursor) {
38
- this._reset(cursor);
39
- this._tryPattern();
40
-
41
- return this.node;
42
- }
43
-
44
- private _tryPattern() {
45
- while (true) {
46
- const mark = this.cursor.mark();
47
- this.children[0].parse(this.cursor);
48
-
49
- if (this.cursor.hasUnresolvedError()) {
50
- this.cursor.resolveError();
51
- this.cursor.moveToMark(mark);
52
- this.match += this.cursor.getChar();
53
- break;
54
- } else {
55
- this.cursor.moveToMark(mark);
56
- break;
57
- }
58
- }
59
-
60
- this._processMatch();
61
- }
62
-
63
- private _processMatch() {
64
- if (this.match.length === 0) {
65
- const parseError = new ParseError(
66
- `Didn't find any characters that didn't match the ${this.children[0].name} pattern.`,
67
- this.mark,
68
- this
69
- );
70
- this.cursor.throwError(parseError);
71
- } else {
72
- this.node = new ValueNode(
73
- "not-value",
74
- this.name,
75
- this.match,
76
- this.mark,
77
- this.mark
78
- );
79
-
80
- this.cursor.index = this.node.endIndex;
81
- this.cursor.addMatch(this, this.node);
82
- }
83
- }
84
-
85
- clone(name?: string) {
86
- if (typeof name !== "string") {
87
- name = this.name;
88
- }
89
- return new NotValue(name, this.children[0] as ValuePattern);
90
- }
91
-
92
- getTokens() {
93
- return [];
94
- }
95
- }
@@ -1,39 +0,0 @@
1
- import ValuePattern from "./ValuePattern";
2
- import Pattern from "../Pattern";
3
- import Cursor from "../../Cursor";
4
-
5
- export default class OptionalValue extends ValuePattern {
6
- constructor(pattern: ValuePattern) {
7
- super("optional-value", "optional-value", [pattern]);
8
- this._assertArguments();
9
- }
10
-
11
- private _assertArguments() {
12
- if (!(this.children[0] instanceof ValuePattern)) {
13
- throw new Error("Invalid Arguments: Expected a ValuePattern.");
14
- }
15
- }
16
-
17
- parse(cursor: Cursor) {
18
- const mark = cursor.mark();
19
-
20
- const node = this.children[0].parse(cursor);
21
-
22
- if (cursor.hasUnresolvedError() || node == null) {
23
- cursor.resolveError();
24
- cursor.moveToMark(mark);
25
- return null;
26
- } else {
27
- cursor.addMatch(this, node);
28
- return node;
29
- }
30
- }
31
-
32
- clone() {
33
- return new OptionalValue(this.children[0] as ValuePattern);
34
- }
35
-
36
- getTokens() {
37
- return this._children[0].getTokens();
38
- }
39
- }
@@ -1,103 +0,0 @@
1
- import ValuePattern from "./ValuePattern";
2
- import ValueNode from "../../ast/ValueNode";
3
- import OptionalValue from "./OptionalValue";
4
- import Pattern from "../Pattern";
5
- import ParseError from "../ParseError";
6
- import Cursor from "../../Cursor";
7
-
8
- export default class OrValue extends ValuePattern {
9
- public index: number = 0;
10
- public errors: ParseError[] = [];
11
- public node: ValueNode | null = null;
12
- public cursor!: Cursor;
13
- public mark: number = 0;
14
- public parseError: ParseError | null = null;
15
-
16
- constructor(name: string, patterns: ValuePattern[]) {
17
- super("or-value", name, patterns);
18
- this._assertArguments();
19
- }
20
-
21
- private _assertArguments() {
22
- if (this._children.length < 2) {
23
- throw new Error(
24
- "Invalid Argument: OrValue needs to have more than one value pattern."
25
- );
26
- }
27
-
28
- const hasOptionalChildren = this._children.some(
29
- (pattern) => pattern instanceof OptionalValue
30
- );
31
-
32
- if (hasOptionalChildren) {
33
- throw new Error("OrValues cannot have optional values.");
34
- }
35
- }
36
-
37
- private _reset(cursor: Cursor) {
38
- this.index = 0;
39
- this.errors = [];
40
- this.node = null;
41
- this.cursor = cursor;
42
- this.mark = cursor.mark();
43
- }
44
-
45
- parse(cursor: Cursor) {
46
- this._reset(cursor);
47
- this._tryPattern();
48
-
49
- return this.node;
50
- }
51
-
52
- private _tryPattern() {
53
- while (true) {
54
- const pattern = this._children[this.index];
55
- const node = pattern.parse(this.cursor) as ValueNode;
56
-
57
- if (this.cursor.hasUnresolvedError()) {
58
- if (this.index + 1 < this._children.length) {
59
- this.cursor.resolveError();
60
- this.index++;
61
- this.cursor.moveToMark(this.mark);
62
- } else {
63
- this.node = null;
64
- break;
65
- }
66
- } else {
67
- this.node = new ValueNode(
68
- "or-value",
69
- this.name,
70
- node.value,
71
- node.startIndex,
72
- node.endIndex
73
- );
74
-
75
- this.cursor.index = this.node.endIndex;
76
- this.cursor.addMatch(this, this.node);
77
-
78
- break;
79
- }
80
- }
81
- }
82
-
83
- clone(name: string) {
84
- if (typeof name !== "string") {
85
- name = this.name;
86
- }
87
- return new OrValue(name, this._children as ValuePattern[]);
88
- }
89
-
90
- getTokens() {
91
- const tokens = this._children.map((c) => c.getTokens());
92
-
93
- const hasPrimitiveTokens = tokens.every((t) =>
94
- t.every((value) => typeof value === "string")
95
- );
96
-
97
- if (hasPrimitiveTokens && tokens.length > 0) {
98
- return tokens.reduce((acc, t) => acc.concat(t), []);
99
- }
100
-
101
- return this._children[0].getTokens();
102
- }
103
- }