clarity-pattern-parser 7.0.2 → 8.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.
- package/biome.json +257 -0
- package/dist/index.browser.js +46 -22
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +46 -22
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +46 -22
- package/dist/index.js.map +1 -1
- package/dist/intellisense/AutoComplete.d.ts +1 -0
- package/dist/patterns/Cursor.d.ts +2 -1
- package/dist/patterns/CursorHistory.d.ts +1 -1
- package/dist/patterns/Literal.d.ts +1 -0
- package/dist/patterns/ParseError.d.ts +3 -2
- package/dist/patterns/Regex.d.ts +1 -0
- package/package.json +1 -1
- package/src/intellisense/AutoComplete.test.ts +106 -0
- package/src/intellisense/AutoComplete.ts +20 -3
- package/src/patterns/And.test.ts +6 -4
- package/src/patterns/And.ts +2 -2
- package/src/patterns/Cursor.test.ts +5 -3
- package/src/patterns/Cursor.ts +6 -2
- package/src/patterns/CursorHistory.test.ts +11 -7
- package/src/patterns/CursorHistory.ts +5 -5
- package/src/patterns/FiniteRepeat.ts +2 -2
- package/src/patterns/InfiniteRepeat.ts +3 -2
- package/src/patterns/Literal.test.ts +4 -2
- package/src/patterns/Literal.ts +5 -1
- package/src/patterns/Not.ts +1 -1
- package/src/patterns/Or.ts +1 -1
- package/src/patterns/ParseError.ts +5 -3
- package/src/patterns/Reference.ts +1 -1
- package/src/patterns/Regex.ts +4 -2
- package/src/patterns/Repeat.ts +1 -1
package/src/patterns/Cursor.ts
CHANGED
|
@@ -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(
|
|
122
|
-
this._history.recordErrorAt(
|
|
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?.
|
|
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]?.
|
|
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]?.
|
|
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?.
|
|
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
|
|
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
|
|
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(
|
|
100
|
-
const error = new ParseError(
|
|
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 ||
|
|
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
|
|
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?.
|
|
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?.
|
|
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
|
|
package/src/patterns/Literal.ts
CHANGED
|
@@ -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(
|
|
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
|
|
package/src/patterns/Not.ts
CHANGED
package/src/patterns/Or.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Pattern } from "./Pattern";
|
|
2
2
|
|
|
3
3
|
export class ParseError {
|
|
4
|
-
public
|
|
4
|
+
public startIndex: number
|
|
5
|
+
public endIndex: number;
|
|
5
6
|
public pattern: Pattern;
|
|
6
7
|
|
|
7
|
-
constructor(
|
|
8
|
-
this.
|
|
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
|
|
38
|
+
constructor(name: string, isOptional = false) {
|
|
39
39
|
this._type = "reference";
|
|
40
40
|
this._name = name;
|
|
41
41
|
this._parent = null;
|
package/src/patterns/Regex.ts
CHANGED
|
@@ -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
|
|
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(
|
|
133
|
+
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
this._node = null;
|
package/src/patterns/Repeat.ts
CHANGED
|
@@ -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
|
|
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)
|