clarity-pattern-parser 7.0.2 → 7.0.3

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.
@@ -45,6 +45,10 @@ export class Cursor {
45
45
  return this._history.error;
46
46
  }
47
47
 
48
+ get errors() {
49
+ return this._history.errors;
50
+ }
51
+
48
52
  get index(): number {
49
53
  return this._index;
50
54
  }
@@ -118,8 +122,8 @@ export class Cursor {
118
122
  this._history.recordMatch(pattern, node);
119
123
  }
120
124
 
121
- recordErrorAt(index: number, onPattern: Pattern): void {
122
- this._history.recordErrorAt(index, onPattern);
125
+ recordErrorAt(firstIndex: number, lastIndex: number, onPattern: Pattern): void {
126
+ this._history.recordErrorAt(firstIndex, lastIndex, onPattern);
123
127
  }
124
128
 
125
129
  resolveError(): void {
@@ -30,13 +30,15 @@ describe("CursorHistory", () => {
30
30
  test("Add Error At", () => {
31
31
  const history = new CursorHistory();
32
32
  const pattern = new Literal("a", "A");
33
-
33
+
34
34
  history.startRecording();
35
- history.recordErrorAt(0, pattern);
35
+ history.recordErrorAt(0, 0, pattern);
36
36
 
37
- expect(history.error?.index).toBe(0);
37
+ expect(history.error?.startIndex).toBe(0);
38
+ expect(history.error?.endIndex).toBe(0);
38
39
  expect(history.error?.pattern).toBe(pattern);
39
- expect(history.errors[0]?.index).toBe(0);
40
+ expect(history.errors[0]?.startIndex).toBe(0);
41
+ expect(history.errors[0]?.endIndex).toBe(0);
40
42
  expect(history.errors[0]?.pattern).toBe(pattern);
41
43
 
42
44
  history.stopRecording()
@@ -44,11 +46,13 @@ describe("CursorHistory", () => {
44
46
 
45
47
  expect(history.isRecording).toBeFalsy();
46
48
  expect(history.error).toBeNull();
47
-
48
- expect(history.errors[0]?.index).toBe(0);
49
+
50
+ expect(history.errors[0]?.startIndex).toBe(0);
51
+ expect(history.errors[0]?.endIndex).toBe(0);
49
52
  expect(history.errors[0]?.pattern).toBe(pattern);
50
53
 
51
- expect(history.furthestError?.index).toBe(0);
54
+ expect(history.furthestError?.startIndex).toBe(0);
55
+ expect(history.furthestError?.endIndex).toBe(0);
52
56
  expect(history.furthestError?.pattern).toBe(pattern);
53
57
  });
54
58
  });
@@ -8,7 +8,7 @@ export interface Match {
8
8
  }
9
9
 
10
10
  export class CursorHistory {
11
- private _isRecording: boolean = false;
11
+ private _isRecording = false;
12
12
  private _leafMatches: Match[] = [{ pattern: null, node: null }];
13
13
  private _furthestError: ParseError | null = null;
14
14
  private _currentError: ParseError | null = null;
@@ -82,7 +82,7 @@ export class CursorHistory {
82
82
  let parent = m.pattern?.parent;
83
83
 
84
84
  while (parent != null) {
85
- if (parent == pattern.parent) {
85
+ if (parent === pattern.parent) {
86
86
  return true;
87
87
  }
88
88
  parent = parent.parent
@@ -96,11 +96,11 @@ export class CursorHistory {
96
96
  }
97
97
  }
98
98
 
99
- recordErrorAt(index: number, pattern: Pattern): void {
100
- const error = new ParseError(index, pattern);
99
+ recordErrorAt(firstIndex: number, lastIndex: number, pattern: Pattern): void {
100
+ const error = new ParseError(firstIndex, lastIndex, pattern);
101
101
  this._currentError = error;
102
102
 
103
- if (this._furthestError === null || index > this._furthestError.index) {
103
+ if (this._furthestError === null || lastIndex > this._furthestError.endIndex) {
104
104
  this._furthestError = error;
105
105
  }
106
106
 
@@ -112,7 +112,7 @@ export class FiniteRepeat implements Pattern {
112
112
 
113
113
  if (matchCount < this._min) {
114
114
  cursor.moveTo(startIndex);
115
- cursor.recordErrorAt(startIndex, this);
115
+ cursor.recordErrorAt(startIndex, startIndex, this);
116
116
  return null;
117
117
  } else if (nodes.length === 0) {
118
118
  cursor.resolveError();
@@ -197,7 +197,7 @@ export class FiniteRepeat implements Pattern {
197
197
  const childIndex = this._children.indexOf(childReference);
198
198
 
199
199
  // If Reference Pattern isn't a child.
200
- if (childIndex == -1) {
200
+ if (childIndex === -1) {
201
201
  return [];
202
202
  }
203
203
 
@@ -132,6 +132,7 @@ export class InfiniteRepeat implements Pattern {
132
132
  }
133
133
 
134
134
  private _tryToParse(cursor: Cursor): boolean {
135
+ const firstIndex = cursor.index;
135
136
  let passed = false;
136
137
 
137
138
  while (true) {
@@ -145,7 +146,7 @@ export class InfiniteRepeat implements Pattern {
145
146
  passed = true;
146
147
  } else {
147
148
  cursor.moveTo(runningCursorIndex);
148
- cursor.recordErrorAt(runningCursorIndex, this._pattern);
149
+ cursor.recordErrorAt(firstIndex, runningCursorIndex, this._pattern);
149
150
  passed = false;
150
151
  }
151
152
 
@@ -187,7 +188,7 @@ export class InfiniteRepeat implements Pattern {
187
188
  if (hasMinimum) {
188
189
  return passed;
189
190
  } else if (!hasMinimum && passed) {
190
- cursor.recordErrorAt(cursor.index, this);
191
+ cursor.recordErrorAt(firstIndex, cursor.index, this);
191
192
  cursor.moveTo(this._firstIndex);
192
193
  return false;
193
194
  }
@@ -34,7 +34,8 @@ describe("Literal", () => {
34
34
 
35
35
  expect(result).toEqual(null);
36
36
  expect(cursor.index).toBe(6);
37
- expect(cursor.error?.index).toBe(6);
37
+ expect(cursor.error?.startIndex).toBe(0);
38
+ expect(cursor.error?.endIndex).toBe(6);
38
39
  expect(cursor.error?.pattern).toBe(literal)
39
40
  });
40
41
 
@@ -46,7 +47,8 @@ describe("Literal", () => {
46
47
 
47
48
  expect(result).toEqual(null);
48
49
  expect(cursor.index).toBe(10);
49
- expect(cursor.error?.index).toBe(10);
50
+ expect(cursor.error?.startIndex).toBe(0);
51
+ expect(cursor.error?.endIndex).toBe(11);
50
52
  expect(cursor.error?.pattern).toBe(literal)
51
53
  });
52
54
 
@@ -11,6 +11,7 @@ export class Literal implements Pattern {
11
11
  private _runes: string[];
12
12
  private _firstIndex: number;
13
13
  private _lastIndex: number;
14
+ private _endIndex: number;
14
15
 
15
16
  get type(): string {
16
17
  return this._type;
@@ -49,6 +50,7 @@ export class Literal implements Pattern {
49
50
  this._parent = null;
50
51
  this._firstIndex = 0;
51
52
  this._lastIndex = 0;
53
+ this._endIndex = 0;
52
54
  }
53
55
 
54
56
  test(text: string) {
@@ -82,7 +84,7 @@ export class Literal implements Pattern {
82
84
  }
83
85
 
84
86
  if (!this._isOptional) {
85
- cursor.recordErrorAt(cursor.index, this)
87
+ cursor.recordErrorAt(this._firstIndex, this._endIndex, this)
86
88
  return null;
87
89
  }
88
90
 
@@ -100,6 +102,7 @@ export class Literal implements Pattern {
100
102
  const cursorRune = cursor.currentChar;
101
103
 
102
104
  if (literalRune !== cursorRune) {
105
+ this._endIndex = cursor.index;
103
106
  break
104
107
  }
105
108
 
@@ -110,6 +113,7 @@ export class Literal implements Pattern {
110
113
  }
111
114
 
112
115
  if (!cursor.hasNext()) {
116
+ this._endIndex = cursor.index + 1;
113
117
  break;
114
118
  }
115
119
 
@@ -67,7 +67,7 @@ export class Not implements Pattern {
67
67
  } else {
68
68
  cursor.moveTo(firstIndex);
69
69
  cursor.resolveError();
70
- cursor.recordErrorAt(firstIndex, this);
70
+ cursor.recordErrorAt(firstIndex, firstIndex, this);
71
71
  }
72
72
 
73
73
  return null;
@@ -86,7 +86,7 @@ export class Or implements Pattern {
86
86
  }
87
87
 
88
88
  if (!this._isOptional) {
89
- cursor.recordErrorAt(this._firstIndex, this)
89
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this)
90
90
  return null;
91
91
  }
92
92
 
@@ -1,11 +1,13 @@
1
1
  import { Pattern } from "./Pattern";
2
2
 
3
3
  export class ParseError {
4
- public index: number;
4
+ public startIndex: number
5
+ public endIndex: number;
5
6
  public pattern: Pattern;
6
7
 
7
- constructor(index: number, pattern: Pattern) {
8
- this.index = index;
8
+ constructor(startIndex: number, endIndex: number, pattern: Pattern) {
9
+ this.startIndex = startIndex;
10
+ this.endIndex = endIndex;
9
11
  this.pattern = pattern;
10
12
  }
11
13
  }
@@ -35,7 +35,7 @@ export class Reference implements Pattern {
35
35
  return this._isOptional;
36
36
  }
37
37
 
38
- constructor(name: string, isOptional: boolean = false) {
38
+ constructor(name: string, isOptional = false) {
39
39
  this._type = "reference";
40
40
  this._name = name;
41
41
  this._parent = null;
@@ -11,7 +11,8 @@ export class Regex implements Pattern {
11
11
  private _regex: RegExp;
12
12
  private _node: Node | null = null;
13
13
  private _cursor: Cursor | null = null;
14
- private _substring: string = "";
14
+ private _firstIndex = -1;
15
+ private _substring = "";
15
16
  private _tokens: string[] = [];
16
17
 
17
18
  get type(): string {
@@ -86,6 +87,7 @@ export class Regex implements Pattern {
86
87
  }
87
88
 
88
89
  parse(cursor: Cursor) {
90
+ this._firstIndex = cursor.index;
89
91
  this.resetState(cursor);
90
92
  this.tryToParse(cursor);
91
93
 
@@ -128,7 +130,7 @@ export class Regex implements Pattern {
128
130
 
129
131
  private processError(cursor: Cursor) {
130
132
  if (!this._isOptional) {
131
- cursor.recordErrorAt(cursor.index, this);
133
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
132
134
  }
133
135
 
134
136
  this._node = null;
@@ -58,7 +58,7 @@ export class Repeat implements Pattern {
58
58
  max: options.max == null ? Infinity : options.max
59
59
  };
60
60
 
61
- if (this._options.max != Infinity) {
61
+ if (this._options.max !== Infinity) {
62
62
  this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
63
63
  } else {
64
64
  this._repeatPattern = new InfiniteRepeat(name, pattern, this._options)