clarity-pattern-parser 4.0.3 → 6.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 (133) hide show
  1. package/README.md +466 -1
  2. package/TODO.md +76 -2
  3. package/dist/ast/Node.d.ts +49 -11
  4. package/dist/ast/Visitor.d.ts +31 -31
  5. package/dist/index.browser.js +1513 -1495
  6. package/dist/index.browser.js.map +1 -1
  7. package/dist/index.d.ts +17 -17
  8. package/dist/index.esm.js +1480 -1459
  9. package/dist/index.esm.js.map +1 -1
  10. package/dist/index.js +1481 -1463
  11. package/dist/index.js.map +1 -1
  12. package/dist/intellisense/AutoComplete.d.ts +28 -0
  13. package/dist/intellisense/Suggestion.d.ts +11 -0
  14. package/dist/intellisense/SuggestionOption.d.ts +4 -0
  15. package/dist/patterns/And.d.ts +37 -24
  16. package/dist/patterns/Cursor.d.ts +37 -0
  17. package/dist/patterns/CursorHistory.d.ts +30 -0
  18. package/dist/patterns/Literal.d.ts +35 -19
  19. package/dist/patterns/Not.d.ts +29 -11
  20. package/dist/patterns/Or.d.ts +33 -22
  21. package/dist/patterns/ParseError.d.ts +6 -8
  22. package/dist/patterns/ParseResult.d.ts +6 -0
  23. package/dist/patterns/Pattern.d.ts +20 -26
  24. package/dist/patterns/Reference.d.ts +34 -12
  25. package/dist/patterns/Regex.d.ts +41 -21
  26. package/dist/patterns/Repeat.d.ts +38 -20
  27. package/dist/patterns/clonePatterns.d.ts +2 -0
  28. package/dist/patterns/filterOutNull.d.ts +2 -0
  29. package/dist/patterns/findPattern.d.ts +2 -0
  30. package/dist/patterns/getNextPattern.d.ts +2 -0
  31. package/jest.config.js +2 -1
  32. package/package.json +4 -5
  33. package/rollup.config.js +1 -1
  34. package/src/ast/Node.test.ts +364 -0
  35. package/src/ast/Node.ts +237 -23
  36. package/src/index.ts +25 -27
  37. package/src/intellisense/AutoComplete.test.ts +150 -0
  38. package/src/intellisense/AutoComplete.ts +200 -0
  39. package/src/intellisense/Suggestion.ts +12 -0
  40. package/src/intellisense/SuggestionOption.ts +4 -0
  41. package/src/{tests/cssPatterns → intellisense/css}/cssValue.ts +1 -1
  42. package/src/{tests/cssPatterns → intellisense/css}/divider.ts +2 -1
  43. package/src/intellisense/css/hex.ts +6 -0
  44. package/src/{tests/cssPatterns → intellisense/css}/method.ts +8 -9
  45. package/src/intellisense/css/name.ts +5 -0
  46. package/src/{tests/javascriptPatterns → intellisense/css}/number.ts +3 -3
  47. package/src/intellisense/css/spaces.ts +6 -0
  48. package/src/intellisense/css/unit.ts +10 -0
  49. package/src/{tests/cssPatterns → intellisense/css}/value.ts +1 -1
  50. package/src/{tests/cssPatterns → intellisense/css}/values.ts +1 -1
  51. package/src/intellisense/javascript/Javascript.test.ts +203 -0
  52. package/src/intellisense/javascript/arrayLiteral.ts +25 -0
  53. package/src/intellisense/javascript/deleteStatement.ts +14 -0
  54. package/src/intellisense/javascript/escapedCharacter.ts +49 -0
  55. package/src/intellisense/javascript/exponent.ts +24 -0
  56. package/src/intellisense/javascript/expression.ts +87 -0
  57. package/src/intellisense/javascript/expressionStatement.ts +29 -0
  58. package/src/intellisense/javascript/fraction.ts +11 -0
  59. package/src/intellisense/javascript/infixOperator.ts +36 -0
  60. package/src/intellisense/javascript/integer.ts +7 -0
  61. package/src/intellisense/javascript/invocation.ts +28 -0
  62. package/src/intellisense/javascript/literal.ts +14 -0
  63. package/src/intellisense/javascript/name.ts +3 -0
  64. package/src/intellisense/javascript/numberLiteral.ts +10 -0
  65. package/src/intellisense/javascript/objectLiteral.ts +30 -0
  66. package/src/intellisense/javascript/optionalSpaces.ts +3 -0
  67. package/src/intellisense/javascript/parameters.ts +20 -0
  68. package/src/intellisense/javascript/prefixOperator.ts +13 -0
  69. package/src/intellisense/javascript/propertyAccess.ts +23 -0
  70. package/src/intellisense/javascript/stringLiteral.ts +28 -0
  71. package/src/patterns/And.test.ts +310 -0
  72. package/src/patterns/And.ts +244 -119
  73. package/src/patterns/Cursor.test.ts +93 -0
  74. package/src/patterns/Cursor.ts +133 -0
  75. package/src/patterns/CursorHistory.test.ts +54 -0
  76. package/src/patterns/CursorHistory.ts +95 -0
  77. package/src/patterns/Literal.test.ts +166 -0
  78. package/src/patterns/Literal.ts +141 -62
  79. package/src/patterns/Not.test.ts +168 -0
  80. package/src/patterns/Not.ts +113 -32
  81. package/src/patterns/Or.test.ts +209 -0
  82. package/src/patterns/Or.ts +128 -97
  83. package/src/patterns/ParseError.ts +3 -7
  84. package/src/patterns/ParseResult.ts +7 -0
  85. package/src/patterns/Pattern.ts +21 -150
  86. package/src/patterns/Reference.test.ts +193 -0
  87. package/src/patterns/Reference.ts +114 -88
  88. package/src/patterns/Regex.test.ts +133 -0
  89. package/src/patterns/Regex.ts +117 -60
  90. package/src/patterns/Repeat.test.ts +218 -0
  91. package/src/patterns/Repeat.ts +220 -103
  92. package/src/patterns/clonePatterns.ts +5 -0
  93. package/src/patterns/filterOutNull.ts +13 -0
  94. package/src/patterns/findPattern.ts +25 -0
  95. package/src/Cursor.ts +0 -141
  96. package/src/CursorHistory.ts +0 -146
  97. package/src/TextSuggester.ts +0 -317
  98. package/src/ast/Visitor.ts +0 -271
  99. package/src/patterns/LookAhead.ts +0 -32
  100. package/src/patterns/Recursive.ts +0 -92
  101. package/src/tests/And.test.ts +0 -180
  102. package/src/tests/ComplexExamples.test.ts +0 -86
  103. package/src/tests/CssPatterns.test.ts +0 -90
  104. package/src/tests/CursorHistory.test.ts +0 -107
  105. package/src/tests/Cusor.test.ts +0 -174
  106. package/src/tests/HtmlPatterns.test.ts +0 -34
  107. package/src/tests/Literal.test.ts +0 -79
  108. package/src/tests/LookAhead.test.ts +0 -44
  109. package/src/tests/Not.test.ts +0 -51
  110. package/src/tests/Or.test.ts +0 -113
  111. package/src/tests/Pattern.test.ts +0 -290
  112. package/src/tests/Recursive.test.ts +0 -64
  113. package/src/tests/Reference.test.ts +0 -16
  114. package/src/tests/Repeat.test.ts +0 -75
  115. package/src/tests/SpeedTest.test.ts +0 -31
  116. package/src/tests/TextSuggester.test.ts +0 -297
  117. package/src/tests/Visitor.test.ts +0 -331
  118. package/src/tests/cssPatterns/hex.ts +0 -5
  119. package/src/tests/cssPatterns/name.ts +0 -5
  120. package/src/tests/cssPatterns/number.ts +0 -8
  121. package/src/tests/cssPatterns/spaces.ts +0 -5
  122. package/src/tests/cssPatterns/unit.ts +0 -8
  123. package/src/tests/htmlPatterns/element.ts +0 -49
  124. package/src/tests/javascriptPatterns/boolean.ts +0 -10
  125. package/src/tests/javascriptPatterns/json.ts +0 -67
  126. package/src/tests/javascriptPatterns/name.ts +0 -5
  127. package/src/tests/javascriptPatterns/objectLiteral.ts +0 -40
  128. package/src/tests/javascriptPatterns/string.ts +0 -84
  129. package/src/tests/javascriptPatterns/unit.ts +0 -8
  130. package/src/tests/javascriptPatterns/whitespace.ts +0 -44
  131. package/src/tests/naturalLanguage/filter.ts +0 -37
  132. package/src/tests/patterns/sentence.ts +0 -37
  133. /package/src/{tests/cssPatterns → intellisense/css}/optionalSpaces.ts +0 -0
@@ -1,127 +1,153 @@
1
- import Pattern from "./Pattern";
2
- import ParserError from "./ParseError";
3
- import Cursor from "../Cursor";
1
+ import { Node } from "../ast/Node";
2
+ import { Cursor } from "./Cursor";
3
+ import { Pattern } from "./Pattern";
4
+ import { findPattern } from "./findPattern";
5
+
6
+ export class Reference implements Pattern {
7
+ private _type: string;
8
+ private _name: string;
9
+ private _parent: Pattern | null;
10
+ private _isOptional: boolean;
11
+ private _pattern: Pattern | null;
12
+ private _children: Pattern[];
13
+
14
+ get type(): string {
15
+ return this._type;
16
+ }
4
17
 
5
- export default class Reference extends Pattern {
6
- constructor(name: string, isOptional = false) {
7
- super("reference", name, [], isOptional);
18
+ get name(): string {
19
+ return this._name;
8
20
  }
9
21
 
10
- private getRoot() {
11
- let node = this.parent;
12
- while (node != null) {
13
- if (node.parent == null) {
14
- return node;
15
- }
16
- node = node.parent;
17
- }
18
- return node;
22
+ get parent(): Pattern | null {
23
+ return this._parent;
19
24
  }
20
25
 
21
- private findPattern(): Pattern | null {
22
- const root = this.getRoot();
23
- let result: Pattern | null = null;
26
+ set parent(pattern: Pattern | null) {
27
+ this._parent = pattern;
28
+ }
24
29
 
25
- if (root == null) {
26
- return null;
27
- }
30
+ get children(): Pattern[] {
31
+ return this._children
32
+ }
28
33
 
29
- this.walkTheTree(root, (pattern) => {
30
- if (
31
- pattern.name === this.name &&
32
- pattern != this &&
33
- pattern.type != "reference"
34
- ) {
35
- result = pattern;
36
- return false;
37
- }
38
- return true;
39
- });
34
+ get isOptional(): boolean {
35
+ return this._isOptional;
36
+ }
40
37
 
41
- return result;
38
+ constructor(name: string, isOptional: boolean = false) {
39
+ this._type = "reference";
40
+ this._name = name;
41
+ this._parent = null;
42
+ this._isOptional = isOptional;
43
+ this._pattern = null;
44
+ this._children = [];
42
45
  }
43
46
 
44
- private walkTheTree(
45
- pattern: Pattern,
46
- callback: (pattern: Pattern) => boolean
47
- ) {
48
- for (let x = 0; x < pattern.children.length; x++) {
49
- const p = pattern.children[x];
50
- const continueWalking = this.walkTheTree(p, callback);
47
+ test(text: string) {
48
+ const cursor = new Cursor(text);
49
+ const ast = this.parse(cursor);
51
50
 
52
- if (!continueWalking) {
53
- return false;
51
+ return ast?.value === text;
52
+ }
53
+
54
+ exec(text: string) {
55
+ const cursor = new Cursor(text);
56
+ const ast = this.parse(cursor);
57
+
58
+ return {
59
+ ast: ast?.value === text ? ast : null,
60
+ cursor
61
+ };
62
+ }
63
+
64
+ parse(cursor: Cursor): Node | null {
65
+ return this._getPatternSafely().parse(cursor);
66
+ }
67
+
68
+ private _getPatternSafely(): Pattern {
69
+ if (this._pattern === null) {
70
+ const pattern = this._findPattern();
71
+
72
+ if (pattern === null) {
73
+ throw new Error(`Couldn't find '${this._name}' pattern within tree.`);
54
74
  }
75
+
76
+ const clonedPattern = pattern.clone(this._name, this._isOptional);
77
+ clonedPattern.parent = this;
78
+
79
+ this._pattern = clonedPattern;
80
+ this._children = [this._pattern];
55
81
  }
56
82
 
57
- return callback(pattern);
83
+ return this._pattern;
58
84
  }
59
85
 
60
- parse(cursor: Cursor) {
61
- const mark = cursor.mark();
86
+ private _findPattern(): Pattern | null {
87
+ const root = this._getRoot();
62
88
 
63
- try {
64
- const node = this.safelyGetPattern().parse(cursor);
89
+ return findPattern(root, (pattern: Pattern) => {
90
+ return pattern.name === this._name && pattern.type !== "reference";
91
+ });
92
+ }
65
93
 
66
- if (!cursor.hasUnresolvedError() && node != null) {
67
- cursor.addMatch(this, node);
68
- }
94
+ private _getRoot(): Pattern {
95
+ let node: Pattern = this;
69
96
 
70
- if (cursor.hasUnresolvedError() && this._isOptional) {
71
- cursor.resolveError();
72
- cursor.moveToMark(mark);
73
- }
97
+ while (true) {
98
+ const parent = node.parent;
74
99
 
75
- return node;
76
- } catch (error) {
77
- if (this._isOptional) {
78
- cursor.moveToMark(mark);
100
+ if (parent == null) {
101
+ break;
79
102
  } else {
80
- cursor.throwError(
81
- new ParserError(
82
- `Couldn't find reference pattern to parse, with the name ${this.name}.`,
83
- cursor.index,
84
- this as Pattern
85
- )
86
- );
103
+ node = parent
87
104
  }
88
-
89
- return null;
90
105
  }
106
+
107
+ return node;
108
+ }
109
+
110
+ getTokens(): string[] {
111
+ return this._getPatternSafely().getTokens();
91
112
  }
92
113
 
93
- clone(name?: string, isOptional?: boolean) {
94
- if (name == null) {
95
- name = this.name;
114
+ getTokensAfter(_lastMatched: Pattern): string[] {
115
+ if (this._parent == null) {
116
+ return [];
96
117
  }
97
118
 
98
- if (isOptional == null) {
99
- isOptional = this._isOptional;
119
+ return this._parent.getTokensAfter(this);
120
+ }
121
+
122
+ getNextTokens(): string[] {
123
+ if (this.parent == null) {
124
+ return []
100
125
  }
101
126
 
102
- return new Reference(name, isOptional);
127
+ return this.parent.getTokensAfter(this);
103
128
  }
104
129
 
105
- private safelyGetPattern() {
106
- let pattern = this.children[0];
107
- const hasNoPattern = pattern == null;
130
+ getPatternsAfter(_childReference: Pattern): Pattern[] {
131
+ if (this._parent == null) {
132
+ return [];
133
+ }
108
134
 
109
- if (hasNoPattern) {
110
- const reference = this.findPattern();
111
- if (reference == null) {
112
- throw new Error(
113
- `Couldn't find reference pattern, with the name ${this.name}.`
114
- );
115
- }
135
+ return this._parent.getPatternsAfter(this);
136
+ }
116
137
 
117
- pattern = reference;
118
- this.children = [pattern];
138
+ getNextPatterns(): Pattern[] {
139
+ if (this.parent == null) {
140
+ return [];
119
141
  }
120
142
 
121
- return pattern;
143
+ return this.parent.getPatternsAfter(this)
144
+ }
145
+
146
+ findPattern(_predicate: (p: Pattern) => boolean): Pattern | null {
147
+ return null;
122
148
  }
123
149
 
124
- getTokens() {
125
- return this.safelyGetPattern().getTokens();
150
+ clone(name = this._name, isOptional = this._isOptional): Pattern {
151
+ return new Reference(name, isOptional);
126
152
  }
127
153
  }
@@ -0,0 +1,133 @@
1
+ import { Cursor } from "./Cursor";
2
+ import { Regex } from "./Regex";
3
+ import { Node } from "../ast/Node"
4
+ import { And } from "./And";
5
+ import { Literal } from "./Literal";
6
+ import { Pattern } from "./Pattern";
7
+
8
+ describe("Regex", () => {
9
+ test("Empty String", () => {
10
+ expect(() => new Regex("empty", "")).toThrowError()
11
+ });
12
+
13
+ test("Starts With ^", () => {
14
+ expect(() => new Regex("carrot", "^")).toThrowError()
15
+ });
16
+
17
+ test("Ends With $", () => {
18
+ expect(() => new Regex("money", ".$")).toThrowError()
19
+ });
20
+
21
+ test("Successful Parse", () => {
22
+ const number = new Regex("number", "\\d");
23
+ const cursor = new Cursor("1");
24
+ const result = number.parse(cursor);
25
+ const expected = new Node("regex", "number", 0, 0, [], "1");
26
+
27
+ expect(result).toEqual(expected);
28
+ expect(cursor.hasError).toBeFalsy()
29
+ })
30
+
31
+ test("Failed Parse", () => {
32
+ const number = new Regex("number", "\\d");
33
+ const cursor = new Cursor("F");
34
+ const result = number.parse(cursor);
35
+
36
+ expect(result).toBeNull();
37
+ expect(cursor.hasError).toBeTruthy()
38
+ });
39
+
40
+
41
+ test("Get Tokens", () => {
42
+ const a = new Regex("a", "A");
43
+
44
+ a.setTokens(["A"]);
45
+
46
+ const tokens = a.getTokens();
47
+ const expectedTokens = ["A"];
48
+
49
+ expect(tokens).toEqual(expectedTokens);
50
+ });
51
+
52
+ test("Get Tokens After", () => {
53
+ const regex = new Regex("a", "A");
54
+ const tokens = regex.getTokensAfter(new Literal("bogus", "bogus"));
55
+ const expected: string[] = [];
56
+
57
+ expect(tokens).toEqual(expected)
58
+ });
59
+
60
+ test("Properties", () => {
61
+ const regex = new Regex("a", "A");
62
+
63
+ expect(regex.type).toBe("regex");
64
+ expect(regex.name).toBe("a");
65
+ expect(regex.parent).toBeNull();
66
+ expect(regex.children).toEqual([]);
67
+ });
68
+
69
+ test("Exec", () => {
70
+ const regex = new Regex("a", "A");
71
+ const { ast: result } = regex.exec("B");
72
+ expect(result).toBeNull();
73
+ });
74
+
75
+ test("Test With Match", () => {
76
+ const regex = new Regex("a", "A");
77
+ const result = regex.test("A");
78
+ expect(result).toBeTruthy();
79
+ });
80
+
81
+ test("Test With No Match", () => {
82
+ const regex = new Regex("a", "A");
83
+ const result = regex.test("B");
84
+ expect(result).toBeFalsy();
85
+ });
86
+
87
+ test("Get Next Tokens", () => {
88
+ const parent = new And("parent", [new Regex("a", "A"), new Literal("b", "B")]);
89
+ const aClone = parent.findPattern(p => p.name === "a") as Pattern;
90
+ const tokens = aClone.getNextTokens();
91
+
92
+ expect(tokens).toEqual(["B"]);
93
+ });
94
+
95
+ test("Get Next Tokens With Null Parent", () => {
96
+ const a = new Regex("a", "A")
97
+ const tokens = a.getNextTokens();
98
+
99
+ expect(tokens).toEqual([]);
100
+ });
101
+
102
+ test("Get Patterns After", () => {
103
+ const a = new Regex("a", "A")
104
+ const patterns = a.getPatternsAfter(new Literal("bogus", "bogus"));
105
+
106
+ expect(patterns).toEqual([]);
107
+ });
108
+
109
+ test("Find Pattern", () => {
110
+ const a = new Regex("a", "A")
111
+ const pattern = a.findPattern(p => p.name === "other");
112
+
113
+ expect(pattern).toBeNull();
114
+ });
115
+
116
+ test("Get Next Patterns", () => {
117
+ const parent = new And("parent", [new Regex("a", "A"), new Literal("b", "B")]);
118
+ const aClone = parent.findPattern(p => p.name === "a") as Pattern;
119
+ const bClone = parent.findPattern(p => p.name === "b") as Pattern;
120
+ const patterns = aClone.getNextPatterns();
121
+
122
+ expect(patterns.length).toBe(1);
123
+ expect(patterns[0]).toBe(bClone);
124
+ });
125
+
126
+ test("Get Next Patterns With Null Parent", () => {
127
+ const a = new Regex("a", "A")
128
+ const patterns = a.getNextPatterns();
129
+
130
+ expect(patterns).toEqual([])
131
+ });
132
+
133
+ });
@@ -1,123 +1,180 @@
1
- import ParseError from "./ParseError";
2
- import Node from "../ast/Node";
3
- import Pattern from "./Pattern";
4
- import Cursor from "../Cursor";
5
-
6
- export default class Regex extends Pattern {
7
- private regexString: string;
8
- private regex: RegExp;
9
- private node: Node | null = null;
10
- private cursor: Cursor | null = null;
11
- private substring: string = "";
1
+ import { Node } from "../ast/Node";
2
+ import { Pattern } from "./Pattern";
3
+ import { Cursor } from "./Cursor";
4
+
5
+ export class Regex implements Pattern {
6
+ private _type: string;
7
+ private _name: string;
8
+ private _isOptional: boolean;
9
+ private _parent: Pattern | null;
10
+ private _originalRegexString: string;
11
+ private _regex: RegExp;
12
+ private _node: Node | null = null;
13
+ private _cursor: Cursor | null = null;
14
+ private _substring: string = "";
15
+ private _tokens: string[] = [];
16
+
17
+ get type(): string {
18
+ return this._type;
19
+ }
20
+
21
+ get name(): string {
22
+ return this._name;
23
+ }
24
+
25
+ get parent(): Pattern | null {
26
+ return this._parent;
27
+ }
28
+
29
+ set parent(pattern: Pattern | null) {
30
+ this._parent = pattern;
31
+ }
32
+
33
+ get children(): Pattern[] {
34
+ return [];
35
+ }
36
+
37
+ get isOptional(): boolean {
38
+ return this._isOptional;
39
+ }
12
40
 
13
41
  constructor(name: string, regex: string, isOptional = false) {
14
- super("regex", name, [], isOptional);
15
- this.regexString = regex;
16
- this.regex = new RegExp(`^${regex}`, "g");
42
+ this._type = "regex"
43
+ this._name = name;
44
+ this._isOptional = isOptional;
45
+ this._parent = null;
46
+ this._originalRegexString = regex;
47
+ this._regex = new RegExp(`^${regex}`, "g");
17
48
  this.assertArguments();
18
49
  }
19
50
 
20
51
  private assertArguments() {
21
- if (this.regexString.length < 1) {
52
+ if (this._originalRegexString.length < 1) {
22
53
  throw new Error(
23
54
  "Invalid Arguments: The regex string argument needs to be at least one character long."
24
55
  );
25
56
  }
26
57
 
27
- if (this.regexString.charAt(0) === "^") {
58
+ if (this._originalRegexString.charAt(0) === "^") {
28
59
  throw new Error(
29
60
  "Invalid Arguments: The regex string cannot start with a '^' because it is expected to be in the middle of a string."
30
61
  );
31
62
  }
32
63
 
33
- if (this.regexString.charAt(this.regexString.length - 1) === "$") {
64
+ if (this._originalRegexString.charAt(this._originalRegexString.length - 1) === "$") {
34
65
  throw new Error(
35
66
  "Invalid Arguments: The regex string cannot end with a '$' because it is expected to be in the middle of a string."
36
67
  );
37
68
  }
38
69
  }
39
70
 
71
+ test(text: string) {
72
+ const cursor = new Cursor(text);
73
+ const ast = this.parse(cursor);
74
+
75
+ return ast?.value === text;
76
+ }
77
+
78
+ exec(text: string) {
79
+ const cursor = new Cursor(text);
80
+ const ast = this.parse(cursor);
81
+
82
+ return {
83
+ ast: ast?.value === text ? ast : null,
84
+ cursor
85
+ };
86
+ }
87
+
40
88
  parse(cursor: Cursor) {
41
89
  this.resetState(cursor);
42
- this.tryToParse();
90
+ this.tryToParse(cursor);
43
91
 
44
- return this.node;
92
+ return this._node;
45
93
  }
46
94
 
47
95
  private resetState(cursor: Cursor) {
48
- this.cursor = cursor;
49
- this.regex.lastIndex = 0;
50
- this.substring = this.cursor.text.substr(this.cursor.getIndex());
51
- this.node = null;
96
+ this._cursor = cursor;
97
+ this._regex.lastIndex = 0;
98
+ this._substring = this._cursor.text.substr(this._cursor.index);
99
+ this._node = null;
52
100
  }
53
101
 
54
- private tryToParse() {
55
- const result = this.regex.exec(this.substring);
102
+ private tryToParse(cursor: Cursor) {
103
+ const result = this._regex.exec(this._substring);
56
104
 
57
105
  if (result != null && result.index === 0) {
58
- this.processResult(result);
106
+ this.processResult(cursor, result);
59
107
  } else {
60
- this.processError();
108
+ this.processError(cursor);
61
109
  }
62
110
  }
63
111
 
64
- private processResult(result: RegExpExecArray) {
65
- const cursor = this.safelyGetCursor();
66
- const currentIndex = cursor.getIndex();
112
+ private processResult(cursor: Cursor, result: RegExpExecArray) {
113
+ const currentIndex = cursor.index;
67
114
  const newIndex = currentIndex + result[0].length - 1;
68
115
 
69
- this.node = new Node(
116
+ this._node = new Node(
70
117
  "regex",
71
- this.name,
118
+ this._name,
72
119
  currentIndex,
73
120
  newIndex,
74
- [],
121
+ undefined,
75
122
  result[0]
76
123
  );
77
124
 
78
- cursor.moveToMark(newIndex);
79
- cursor.addMatch(this, this.node);
125
+ cursor.moveTo(newIndex);
126
+ cursor.recordMatch(this, this._node);
80
127
  }
81
128
 
82
- private processError() {
83
- const cursor = this.safelyGetCursor();
84
-
129
+ private processError(cursor: Cursor) {
85
130
  if (!this._isOptional) {
86
- const message = `ParseError: Expected regex pattern of '${this.regexString}' but found '${this.substring}'.`;
87
- const parseError = new ParseError(message, cursor.getIndex(), this);
88
-
89
- cursor.throwError(parseError);
131
+ cursor.recordErrorAt(cursor.index, this);
90
132
  }
91
133
 
92
- this.node = null;
134
+ this._node = null;
93
135
  }
94
136
 
95
- private safelyGetCursor() {
96
- const cursor = this.cursor;
137
+ clone(name = this._name, isOptional = this._isOptional) {
138
+ const pattern = new Regex(name, this._originalRegexString, isOptional);
139
+ pattern._tokens = this._tokens.slice();
97
140
 
98
- if (cursor == null) {
99
- throw new Error("Couldn't find cursor.");
100
- }
101
- return cursor;
141
+ return pattern;
102
142
  }
103
143
 
104
- clone(name?: string, isOptional?: boolean) {
105
- if (name == null) {
106
- name = this.name;
144
+ getTokens() {
145
+ return this._tokens;
146
+ }
147
+
148
+ getTokensAfter(_childReference: Pattern): string[] {
149
+ return [];
150
+ }
151
+
152
+ getNextTokens(): string[] {
153
+ if (this.parent == null) {
154
+ return []
107
155
  }
108
156
 
109
- if (isOptional == null) {
110
- isOptional = this._isOptional;
157
+ return this.parent.getTokensAfter(this);
158
+ }
159
+
160
+ getPatternsAfter(_childReference: Pattern): Pattern[] {
161
+ return [];
162
+ }
163
+
164
+ getNextPatterns(): Pattern[] {
165
+ if (this.parent == null) {
166
+ return [];
111
167
  }
112
168
 
113
- return new Regex(name, this.regexString, isOptional);
169
+ return this.parent.getPatternsAfter(this)
114
170
  }
115
171
 
116
- getTokenValue() {
117
- return this.name;
172
+ findPattern(_predicate: (p: Pattern) => boolean): Pattern | null {
173
+ return null;
118
174
  }
119
175
 
120
- getTokens() {
121
- return [this.name];
176
+ setTokens(tokens: string[]) {
177
+ this._tokens = tokens;
122
178
  }
123
- }
179
+
180
+ }