clarity-pattern-parser 5.0.0 → 6.0.2
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/README.md +328 -38
- package/TODO.md +63 -7
- package/dist/ast/Node.d.ts +8 -2
- package/dist/index.browser.js +520 -205
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.esm.js +519 -206
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +520 -205
- package/dist/index.js.map +1 -1
- package/dist/intellisense/AutoComplete.d.ts +34 -0
- package/dist/intellisense/Suggestion.d.ts +10 -0
- package/dist/intellisense/SuggestionOption.d.ts +4 -0
- package/dist/patterns/And.d.ts +8 -7
- package/dist/patterns/Cursor.d.ts +6 -4
- package/dist/patterns/CursorHistory.d.ts +2 -2
- package/dist/patterns/Literal.d.ts +8 -8
- package/dist/patterns/Not.d.ts +9 -5
- package/dist/patterns/Or.d.ts +8 -5
- package/dist/patterns/Pattern.d.ts +8 -4
- package/dist/patterns/Reference.d.ts +11 -7
- package/dist/patterns/Regex.d.ts +8 -8
- package/dist/patterns/Repeat.d.ts +8 -7
- package/package.json +1 -1
- package/src/ast/Node.test.ts +116 -0
- package/src/ast/Node.ts +71 -5
- package/src/index.ts +14 -3
- package/src/intellisense/AutoComplete.test.ts +168 -23
- package/src/intellisense/AutoComplete.ts +102 -21
- package/src/intellisense/Suggestion.ts +3 -4
- package/src/intellisense/javascript/Javascript.test.ts +86 -62
- package/src/intellisense/javascript/{expressionStatement.ts → assignment.ts} +7 -8
- package/src/intellisense/javascript/escapedCharacter.ts +0 -1
- package/src/intellisense/javascript/exponent.ts +0 -2
- package/src/intellisense/javascript/expression.ts +44 -26
- package/src/intellisense/javascript/fraction.ts +0 -2
- package/src/intellisense/javascript/infixOperator.ts +6 -2
- package/src/intellisense/javascript/keywords.ts +3 -0
- package/src/intellisense/javascript/objectAccess.ts +9 -0
- package/src/intellisense/javascript/objectLiteral.ts +3 -3
- package/src/intellisense/javascript/propertyAccess.ts +8 -3
- package/src/intellisense/javascript/stringLiteral.ts +16 -8
- package/src/patterns/And.test.ts +74 -50
- package/src/patterns/And.ts +72 -36
- package/src/patterns/Cursor.ts +17 -14
- package/src/patterns/CursorHistory.ts +8 -8
- package/src/patterns/Literal.test.ts +79 -38
- package/src/patterns/Literal.ts +34 -41
- package/src/patterns/Not.test.ts +99 -8
- package/src/patterns/Not.ts +58 -14
- package/src/patterns/Or.test.ts +128 -13
- package/src/patterns/Or.ts +46 -13
- package/src/patterns/Pattern.ts +8 -4
- package/src/patterns/Reference.test.ts +127 -28
- package/src/patterns/Reference.ts +62 -32
- package/src/patterns/Regex.test.ts +76 -35
- package/src/patterns/Regex.ts +35 -43
- package/src/patterns/Repeat.test.ts +72 -41
- package/src/patterns/Repeat.ts +55 -38
- package/src/patterns/getNextPattern.test.ts +0 -39
- package/src/patterns/getNextPattern.ts +0 -18
package/src/patterns/Or.test.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Node } from "../ast/Node";
|
|
|
3
3
|
import { Literal } from "./Literal";
|
|
4
4
|
import { Or } from "./Or";
|
|
5
5
|
import { And } from "./And";
|
|
6
|
+
import { Pattern } from "./Pattern";
|
|
6
7
|
|
|
7
8
|
describe("Or", () => {
|
|
8
9
|
test("Empty Options", () => {
|
|
@@ -63,30 +64,23 @@ describe("Or", () => {
|
|
|
63
64
|
expect(tokens).toEqual(expected);
|
|
64
65
|
});
|
|
65
66
|
|
|
66
|
-
test("Get
|
|
67
|
+
test("Get Tokens After", () => {
|
|
67
68
|
const a = new Or("a", [new Literal("a", "A")]);
|
|
68
69
|
const parent = new And("parent", [a, new Literal("b", "B")]);
|
|
69
|
-
const tokens = parent.children[0].
|
|
70
|
+
const tokens = parent.children[0].getTokensAfter(parent.children[0].children[0]);
|
|
70
71
|
const expected = ["B"];
|
|
71
72
|
|
|
72
73
|
expect(tokens).toEqual(expected);
|
|
73
74
|
});
|
|
74
75
|
|
|
75
|
-
test("Get
|
|
76
|
+
test("Get Tokens After Without A Parent", () => {
|
|
76
77
|
const a = new Or("a", [new Literal("a", "A")]);
|
|
77
|
-
const tokens = a.
|
|
78
|
+
const tokens = a.getTokensAfter(a.children[0]);
|
|
78
79
|
const expected: string[] = [];
|
|
79
80
|
|
|
80
81
|
expect(tokens).toEqual(expected);
|
|
81
82
|
});
|
|
82
83
|
|
|
83
|
-
test("Get Next Pattern", () => {
|
|
84
|
-
const a = new Or("a", [new Literal("a", "A")]);
|
|
85
|
-
const nextToken = a.getNextPattern();
|
|
86
|
-
|
|
87
|
-
expect(nextToken).toBeNull();
|
|
88
|
-
});
|
|
89
|
-
|
|
90
84
|
test("Properties", () => {
|
|
91
85
|
const a = new Or("a", [new Literal("a", "A")]);
|
|
92
86
|
|
|
@@ -97,9 +91,130 @@ describe("Or", () => {
|
|
|
97
91
|
expect(a.children[0].name).toBe("a");
|
|
98
92
|
});
|
|
99
93
|
|
|
100
|
-
test("
|
|
94
|
+
test("Exec", () => {
|
|
101
95
|
const a = new Or("a", [new Literal("a", "A")]);
|
|
102
|
-
const { ast: result } = a.
|
|
96
|
+
const { ast: result } = a.exec("B");
|
|
103
97
|
expect(result).toBeNull();
|
|
104
98
|
});
|
|
99
|
+
|
|
100
|
+
test("Test No Match", () => {
|
|
101
|
+
const a = new Or("a", [new Literal("a", "A")]);
|
|
102
|
+
const result = a.test("B");
|
|
103
|
+
expect(result).toBeFalsy();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test("Test With Match", () => {
|
|
107
|
+
const a = new Or("a", [new Literal("a", "A")]);
|
|
108
|
+
const result = a.test("A");
|
|
109
|
+
expect(result).toBeTruthy();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("Get Next Tokens", () => {
|
|
113
|
+
const sequence = new And("sequence", [
|
|
114
|
+
new Or("a-or-b", [
|
|
115
|
+
new Literal("a", "A"),
|
|
116
|
+
new Literal("b", "B")
|
|
117
|
+
]),
|
|
118
|
+
new Literal("c", "C")
|
|
119
|
+
]);
|
|
120
|
+
|
|
121
|
+
const orClone = sequence.findPattern(p => p.name === "a-or-b") as Pattern;
|
|
122
|
+
const tokens = orClone.getNextTokens();
|
|
123
|
+
|
|
124
|
+
expect(tokens.length).toBe(1);
|
|
125
|
+
expect(tokens[0]).toBe("C");
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("Get Next Tokens With Null Parent", () => {
|
|
129
|
+
const or = new Or("a-or-b", [
|
|
130
|
+
new Literal("a", "A"),
|
|
131
|
+
new Literal("b", "B")
|
|
132
|
+
])
|
|
133
|
+
|
|
134
|
+
const tokens = or.getNextTokens();
|
|
135
|
+
expect(tokens.length).toBe(0);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
test("Get Tokens After", () => {
|
|
140
|
+
const sequence = new And("sequence", [
|
|
141
|
+
new Or("a-or-b", [
|
|
142
|
+
new Literal("a", "A"),
|
|
143
|
+
new Literal("b", "B")
|
|
144
|
+
]),
|
|
145
|
+
new Literal("c", "C")
|
|
146
|
+
]);
|
|
147
|
+
|
|
148
|
+
const aClone = sequence.findPattern(p => p.name === "a") as Pattern;
|
|
149
|
+
const orClone = sequence.findPattern(p => p.name === "a-or-b") as Pattern;
|
|
150
|
+
const tokens = orClone.getTokensAfter(aClone);
|
|
151
|
+
|
|
152
|
+
expect(tokens.length).toBe(1);
|
|
153
|
+
expect(tokens[0]).toBe("C");
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test("Get Patterns", () => {
|
|
157
|
+
const aOrB = new Or("a-b", [new Literal("a", "A"), new Literal("b", "B")]);
|
|
158
|
+
const patterns = aOrB.getPatterns();
|
|
159
|
+
const expected = [
|
|
160
|
+
aOrB.findPattern(p => p.name === "a"),
|
|
161
|
+
aOrB.findPattern(p => p.name === "b")
|
|
162
|
+
];
|
|
163
|
+
|
|
164
|
+
expect(patterns).toEqual(expected);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("Get Patterns After", () => {
|
|
168
|
+
const sequence = new And("sequence", [
|
|
169
|
+
new Or("a-or-b", [
|
|
170
|
+
new Literal("a", "A"),
|
|
171
|
+
new Literal("b", "B")
|
|
172
|
+
]),
|
|
173
|
+
new Literal("c", "C")
|
|
174
|
+
]);
|
|
175
|
+
|
|
176
|
+
const aClone = sequence.findPattern(p => p.name === "a") as Pattern;
|
|
177
|
+
const orClone = sequence.findPattern(p => p.name === "a-or-b") as Pattern;
|
|
178
|
+
const patterns = orClone.getPatternsAfter(aClone);
|
|
179
|
+
|
|
180
|
+
expect(patterns.length).toBe(1);
|
|
181
|
+
expect(patterns[0].name).toBe("c");
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("Get Patterns After With Null Parent", () => {
|
|
185
|
+
const or = new Or("a-or-b", [
|
|
186
|
+
new Literal("a", "A"),
|
|
187
|
+
new Literal("b", "B")
|
|
188
|
+
])
|
|
189
|
+
const aClone = or.findPattern(p => p.name === "a") as Pattern;
|
|
190
|
+
const patterns = or.getPatternsAfter(aClone);
|
|
191
|
+
|
|
192
|
+
expect(patterns.length).toBe(0);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test("Get Next Patterns", () => {
|
|
196
|
+
const sequence = new And("sequence", [
|
|
197
|
+
new Or("a-or-b", [
|
|
198
|
+
new Literal("a", "A"),
|
|
199
|
+
new Literal("b", "B")
|
|
200
|
+
]),
|
|
201
|
+
new Literal("c", "C")
|
|
202
|
+
]);
|
|
203
|
+
|
|
204
|
+
const orClone = sequence.findPattern(p => p.name === "a-or-b") as Pattern;
|
|
205
|
+
const patterns = orClone.getNextPatterns();
|
|
206
|
+
|
|
207
|
+
expect(patterns.length).toBe(1);
|
|
208
|
+
expect(patterns[0].name).toBe("c");
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test("Get Next Patterns With Null Parent", () => {
|
|
212
|
+
const or = new Or("a-or-b", [
|
|
213
|
+
new Literal("a", "A"),
|
|
214
|
+
new Literal("b", "B")
|
|
215
|
+
])
|
|
216
|
+
const patterns = or.getNextPatterns();
|
|
217
|
+
|
|
218
|
+
expect(patterns.length).toBe(0);
|
|
219
|
+
});
|
|
105
220
|
});
|
package/src/patterns/Or.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { Node } from "../ast/Node";
|
|
|
2
2
|
import { Cursor } from "./Cursor";
|
|
3
3
|
import { Pattern } from "./Pattern";
|
|
4
4
|
import { clonePatterns } from "./clonePatterns";
|
|
5
|
-
import { getNextPattern } from "./getNextPattern";
|
|
6
5
|
import { findPattern } from "./findPattern";
|
|
7
6
|
|
|
8
7
|
export class Or implements Pattern {
|
|
@@ -11,7 +10,6 @@ export class Or implements Pattern {
|
|
|
11
10
|
private _parent: Pattern | null;
|
|
12
11
|
private _children: Pattern[];
|
|
13
12
|
private _isOptional: boolean;
|
|
14
|
-
private _node: Node | null;
|
|
15
13
|
private _firstIndex: number;
|
|
16
14
|
|
|
17
15
|
get type(): string {
|
|
@@ -51,7 +49,6 @@ export class Or implements Pattern {
|
|
|
51
49
|
this._parent = null;
|
|
52
50
|
this._children = children;
|
|
53
51
|
this._isOptional = isOptional;
|
|
54
|
-
this._node = null;
|
|
55
52
|
this._firstIndex = 0;
|
|
56
53
|
}
|
|
57
54
|
|
|
@@ -61,19 +58,25 @@ export class Or implements Pattern {
|
|
|
61
58
|
}
|
|
62
59
|
}
|
|
63
60
|
|
|
64
|
-
|
|
61
|
+
test(text: string) {
|
|
65
62
|
const cursor = new Cursor(text);
|
|
66
|
-
const ast = this.parse(cursor)
|
|
63
|
+
const ast = this.parse(cursor);
|
|
64
|
+
|
|
65
|
+
return ast?.value === text;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
exec(text: string) {
|
|
69
|
+
const cursor = new Cursor(text);
|
|
70
|
+
const ast = this.parse(cursor);
|
|
67
71
|
|
|
68
72
|
return {
|
|
69
|
-
ast,
|
|
73
|
+
ast: ast?.value === text ? ast : null,
|
|
70
74
|
cursor
|
|
71
75
|
};
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
parse(cursor: Cursor): Node | null {
|
|
75
79
|
this._firstIndex = cursor.index;
|
|
76
|
-
this._node = null;
|
|
77
80
|
|
|
78
81
|
const node = this._tryToParse(cursor);
|
|
79
82
|
|
|
@@ -117,20 +120,50 @@ export class Or implements Pattern {
|
|
|
117
120
|
return tokens;
|
|
118
121
|
}
|
|
119
122
|
|
|
120
|
-
|
|
123
|
+
getTokensAfter(_childReference: Pattern): string[] {
|
|
121
124
|
if (this._parent === null) {
|
|
122
125
|
return [];
|
|
123
126
|
}
|
|
124
127
|
|
|
125
|
-
return this._parent.
|
|
128
|
+
return this._parent.getTokensAfter(this);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
getNextTokens(): string[] {
|
|
132
|
+
if (this._parent == null) {
|
|
133
|
+
return []
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return this._parent.getTokensAfter(this);
|
|
126
137
|
}
|
|
127
138
|
|
|
128
|
-
|
|
129
|
-
|
|
139
|
+
getPatterns(): Pattern[] {
|
|
140
|
+
const patterns: Pattern[] = [];
|
|
141
|
+
|
|
142
|
+
for (const pattern of this._children) {
|
|
143
|
+
patterns.push(...pattern.getPatterns());
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return patterns;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
getPatternsAfter(_childReference: Pattern): Pattern[] {
|
|
150
|
+
if (this._parent === null) {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return this._parent.getPatternsAfter(this)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
getNextPatterns(): Pattern[] {
|
|
158
|
+
if (this.parent == null) {
|
|
159
|
+
return [];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return this.parent.getPatternsAfter(this)
|
|
130
163
|
}
|
|
131
164
|
|
|
132
|
-
findPattern(
|
|
133
|
-
return findPattern(this,
|
|
165
|
+
findPattern(predicate: (p: Pattern) => boolean): Pattern | null {
|
|
166
|
+
return findPattern(this, predicate);
|
|
134
167
|
}
|
|
135
168
|
|
|
136
169
|
clone(name = this._name, isOptional = this._isOptional): Pattern {
|
package/src/patterns/Pattern.ts
CHANGED
|
@@ -10,10 +10,14 @@ export interface Pattern {
|
|
|
10
10
|
isOptional: boolean;
|
|
11
11
|
|
|
12
12
|
parse(cursor: Cursor): Node | null;
|
|
13
|
-
|
|
13
|
+
exec(text: string): ParseResult;
|
|
14
|
+
test(text: string): boolean;
|
|
14
15
|
clone(name?: string, isOptional?: boolean): Pattern;
|
|
15
16
|
getTokens(): string[];
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
getTokensAfter(childReference: Pattern): string[];
|
|
18
|
+
getNextTokens(): string[];
|
|
19
|
+
getPatterns(): Pattern[];
|
|
20
|
+
getPatternsAfter(childReference: Pattern): Pattern[];
|
|
21
|
+
getNextPatterns(): Pattern[];
|
|
22
|
+
findPattern(predicate: (p: Pattern) => boolean): Pattern | null;
|
|
19
23
|
}
|
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
import { Cursor, Repeat } from "..";
|
|
2
1
|
import { Node } from "../ast/Node";
|
|
3
2
|
import { And } from "./And";
|
|
3
|
+
import { Cursor } from "./Cursor";
|
|
4
4
|
import { findPattern } from "./findPattern";
|
|
5
5
|
import { Literal } from "./Literal";
|
|
6
6
|
import { Or } from "./Or";
|
|
7
|
+
import { Pattern } from "./Pattern";
|
|
7
8
|
import { Reference } from "./Reference";
|
|
8
9
|
import { Regex } from "./Regex";
|
|
10
|
+
import { Repeat } from "./Repeat";
|
|
9
11
|
|
|
10
12
|
function createValuePattern() {
|
|
11
13
|
const number = new Regex("number", "\\d+");
|
|
14
|
+
number.setTokens(["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]);
|
|
15
|
+
|
|
12
16
|
const openBracket = new Literal("open-bracket", "[");
|
|
13
17
|
const closeBracket = new Literal("close-bracket", "]");
|
|
14
18
|
const divider = new Regex("divider", "\\s*,\\s+");
|
|
19
|
+
divider.setTokens([", "]);
|
|
20
|
+
|
|
15
21
|
const valueRef = new Reference("value");
|
|
16
22
|
const values = new Repeat("values", valueRef, divider);
|
|
17
23
|
const array = new And("array", [openBracket, values, closeBracket]);
|
|
18
24
|
const value = new Or("value", [number, array]);
|
|
19
25
|
|
|
20
|
-
number.setTokens(["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]);
|
|
21
|
-
divider.setTokens([", "])
|
|
22
|
-
|
|
23
26
|
return value;
|
|
24
27
|
}
|
|
25
28
|
|
|
@@ -54,37 +57,30 @@ describe("Reference", () => {
|
|
|
54
57
|
const value = createValuePattern();
|
|
55
58
|
const ref = findPattern(value, (p) => p.type === "reference");
|
|
56
59
|
const tokens = ref?.getTokens();
|
|
57
|
-
const expected = [
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
60
|
+
const expected = [
|
|
61
|
+
"1",
|
|
62
|
+
"2",
|
|
63
|
+
"3",
|
|
64
|
+
"4",
|
|
65
|
+
"5",
|
|
66
|
+
"6",
|
|
67
|
+
"7",
|
|
68
|
+
"8",
|
|
69
|
+
"9",
|
|
70
|
+
"0",
|
|
71
|
+
"["
|
|
72
|
+
];
|
|
70
73
|
|
|
71
74
|
expect(tokens).toEqual(expected);
|
|
72
75
|
});
|
|
73
76
|
|
|
74
|
-
test("Get
|
|
77
|
+
test("Get Tokens After With No Parent", () => {
|
|
75
78
|
const ref = new Reference("bad-reference");
|
|
76
|
-
const tokens = ref.
|
|
79
|
+
const tokens = ref.getTokensAfter(new Literal("bogus", "bogus"))
|
|
77
80
|
|
|
78
81
|
expect(tokens).toEqual([]);
|
|
79
82
|
});
|
|
80
83
|
|
|
81
|
-
test("Get Next Pattern", () => {
|
|
82
|
-
const ref = new Reference("ref");
|
|
83
|
-
const nextPattern = ref.getNextPattern();
|
|
84
|
-
|
|
85
|
-
expect(nextPattern).toBeNull()
|
|
86
|
-
});
|
|
87
|
-
|
|
88
84
|
test("Properties", () => {
|
|
89
85
|
const ref = new Reference("ref");
|
|
90
86
|
|
|
@@ -95,10 +91,113 @@ describe("Reference", () => {
|
|
|
95
91
|
expect(ref.children).toEqual([])
|
|
96
92
|
});
|
|
97
93
|
|
|
98
|
-
test("
|
|
94
|
+
test("Exec", () => {
|
|
99
95
|
const value = createValuePattern();
|
|
100
96
|
const reference = findPattern(value, p => p.type === "reference") as Reference
|
|
101
|
-
const { ast: result } = reference.
|
|
97
|
+
const { ast: result } = reference.exec("B");
|
|
102
98
|
expect(result).toBeNull()
|
|
103
99
|
});
|
|
100
|
+
|
|
101
|
+
test("Test With Match", () => {
|
|
102
|
+
const value = createValuePattern();
|
|
103
|
+
const reference = findPattern(value, p => p.type === "reference") as Reference
|
|
104
|
+
const result = reference.test("[1]");
|
|
105
|
+
expect(result).toBeTruthy()
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test("Test No Match", () => {
|
|
109
|
+
const value = createValuePattern();
|
|
110
|
+
const reference = findPattern(value, p => p.type === "reference") as Reference
|
|
111
|
+
const result = reference.test("B");
|
|
112
|
+
expect(result).toBeFalsy()
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("Find Pattern", () => {
|
|
116
|
+
const value = createValuePattern();
|
|
117
|
+
const reference = value.findPattern(p => p.type === "reference") as Pattern;
|
|
118
|
+
|
|
119
|
+
const pattern = reference?.findPattern(p => p.name === "Nada");
|
|
120
|
+
|
|
121
|
+
expect(pattern).toBe(null);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
test("Get Next Tokens", () => {
|
|
126
|
+
const value = createValuePattern();
|
|
127
|
+
const reference = value.findPattern(p => p.type === "reference") as Pattern;
|
|
128
|
+
const tokens = reference.getNextTokens();
|
|
129
|
+
|
|
130
|
+
expect(tokens).toEqual([", ", "]"]);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test("Get Next Tokens With Null Parent", () => {
|
|
134
|
+
const reference = new Reference("ref-name");
|
|
135
|
+
const tokens = reference.getNextTokens();
|
|
136
|
+
|
|
137
|
+
expect(tokens).toEqual([])
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test("Get Tokens After", () => {
|
|
141
|
+
const value = createValuePattern();
|
|
142
|
+
const reference = value.findPattern(p => p.type === "reference") as Pattern;
|
|
143
|
+
const tokens = reference.getTokensAfter(new Literal("bogus", "Bogus"));
|
|
144
|
+
|
|
145
|
+
expect(tokens).toEqual([", ", "]"]);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("Get Tokens After With Null Parent", () => {
|
|
149
|
+
const reference = new Reference("ref-name");
|
|
150
|
+
const tokens = reference.getTokensAfter(new Literal("bogus", "Bogus"));
|
|
151
|
+
|
|
152
|
+
expect(tokens).toEqual([])
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("Get Patterns", () => {
|
|
156
|
+
const value = createValuePattern();
|
|
157
|
+
const ref = findPattern(value, (p) => p.type === "reference");
|
|
158
|
+
const patterns = ref?.getPatterns() || [];
|
|
159
|
+
|
|
160
|
+
expect(patterns.length).toBe(2);
|
|
161
|
+
expect(patterns[0].name).toBe("number");
|
|
162
|
+
expect(patterns[1].name).toBe("open-bracket");
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test("Get Patterns After", () => {
|
|
166
|
+
const value = createValuePattern();
|
|
167
|
+
const reference = value.findPattern(p => p.type === "reference") as Pattern;
|
|
168
|
+
const patterns = reference.getPatternsAfter(new Literal("bogus", "Bogus"));
|
|
169
|
+
|
|
170
|
+
expect(patterns.length).toEqual(2);
|
|
171
|
+
expect(patterns[0].type).toEqual("regex");
|
|
172
|
+
expect(patterns[0].name).toEqual("divider");
|
|
173
|
+
expect(patterns[1].type).toEqual("literal");
|
|
174
|
+
expect(patterns[1].name).toEqual("close-bracket");
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test("Get Patterns After With Null Parent", () => {
|
|
178
|
+
const reference = new Reference("ref-name");
|
|
179
|
+
const patterns = reference.getPatternsAfter(new Literal("bogus", "Bogus"));
|
|
180
|
+
|
|
181
|
+
expect(patterns).toEqual([])
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("Get Next Patterns", () => {
|
|
185
|
+
const value = createValuePattern();
|
|
186
|
+
const reference = value.findPattern(p => p.type === "reference") as Pattern;
|
|
187
|
+
const patterns = reference.getNextPatterns();
|
|
188
|
+
|
|
189
|
+
expect(patterns.length).toEqual(2);
|
|
190
|
+
expect(patterns[0].type).toEqual("regex");
|
|
191
|
+
expect(patterns[0].name).toEqual("divider");
|
|
192
|
+
expect(patterns[1].type).toEqual("literal");
|
|
193
|
+
expect(patterns[1].name).toEqual("close-bracket");
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("Get Next Patterns With Null Parent", () => {
|
|
197
|
+
const reference = new Reference("ref-name");
|
|
198
|
+
const patterns = reference.getNextPatterns();
|
|
199
|
+
|
|
200
|
+
expect(patterns).toEqual([])
|
|
201
|
+
});
|
|
202
|
+
|
|
104
203
|
});
|
|
@@ -2,7 +2,6 @@ import { Node } from "../ast/Node";
|
|
|
2
2
|
import { Cursor } from "./Cursor";
|
|
3
3
|
import { Pattern } from "./Pattern";
|
|
4
4
|
import { findPattern } from "./findPattern";
|
|
5
|
-
import { getNextPattern } from "./getNextPattern";
|
|
6
5
|
|
|
7
6
|
export class Reference implements Pattern {
|
|
8
7
|
private _type: string;
|
|
@@ -20,10 +19,6 @@ export class Reference implements Pattern {
|
|
|
20
19
|
return this._name;
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
get isOptional(): boolean {
|
|
24
|
-
return this._isOptional;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
22
|
get parent(): Pattern | null {
|
|
28
23
|
return this._parent;
|
|
29
24
|
}
|
|
@@ -36,6 +31,10 @@ export class Reference implements Pattern {
|
|
|
36
31
|
return this._children
|
|
37
32
|
}
|
|
38
33
|
|
|
34
|
+
get isOptional(): boolean {
|
|
35
|
+
return this._isOptional;
|
|
36
|
+
}
|
|
37
|
+
|
|
39
38
|
constructor(name: string, isOptional: boolean = false) {
|
|
40
39
|
this._type = "reference";
|
|
41
40
|
this._name = name;
|
|
@@ -45,12 +44,19 @@ export class Reference implements Pattern {
|
|
|
45
44
|
this._children = [];
|
|
46
45
|
}
|
|
47
46
|
|
|
48
|
-
|
|
47
|
+
test(text: string) {
|
|
49
48
|
const cursor = new Cursor(text);
|
|
50
|
-
const ast = this.parse(cursor)
|
|
49
|
+
const ast = this.parse(cursor);
|
|
50
|
+
|
|
51
|
+
return ast?.value === text;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
exec(text: string) {
|
|
55
|
+
const cursor = new Cursor(text);
|
|
56
|
+
const ast = this.parse(cursor);
|
|
51
57
|
|
|
52
58
|
return {
|
|
53
|
-
ast,
|
|
59
|
+
ast: ast?.value === text ? ast : null,
|
|
54
60
|
cursor
|
|
55
61
|
};
|
|
56
62
|
}
|
|
@@ -59,30 +65,6 @@ export class Reference implements Pattern {
|
|
|
59
65
|
return this._getPatternSafely().parse(cursor);
|
|
60
66
|
}
|
|
61
67
|
|
|
62
|
-
clone(name = this._name, isOptional = this._isOptional): Pattern {
|
|
63
|
-
return new Reference(name, isOptional);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
getTokens(): string[] {
|
|
67
|
-
return this._getPatternSafely().getTokens();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
getNextTokens(_lastMatched: Pattern): string[] {
|
|
71
|
-
if (this.parent == null) {
|
|
72
|
-
return [];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return this.parent.getNextTokens(this);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
getNextPattern(): Pattern | null {
|
|
79
|
-
return getNextPattern(this)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
findPattern(_isMatch: (p: Pattern)=>boolean): Pattern | null{
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
68
|
private _getPatternSafely(): Pattern {
|
|
87
69
|
if (this._pattern === null) {
|
|
88
70
|
const pattern = this._findPattern();
|
|
@@ -124,4 +106,52 @@ export class Reference implements Pattern {
|
|
|
124
106
|
|
|
125
107
|
return node;
|
|
126
108
|
}
|
|
109
|
+
|
|
110
|
+
getTokens(): string[] {
|
|
111
|
+
return this._getPatternSafely().getTokens();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
getTokensAfter(_lastMatched: Pattern): string[] {
|
|
115
|
+
if (this._parent == null) {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return this._parent.getTokensAfter(this);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
getNextTokens(): string[] {
|
|
123
|
+
if (this.parent == null) {
|
|
124
|
+
return []
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return this.parent.getTokensAfter(this);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
getPatterns(): Pattern[] {
|
|
131
|
+
return this._getPatternSafely().getPatterns();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
getPatternsAfter(_childReference: Pattern): Pattern[] {
|
|
135
|
+
if (this._parent == null) {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return this._parent.getPatternsAfter(this);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
getNextPatterns(): Pattern[] {
|
|
143
|
+
if (this.parent == null) {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return this.parent.getPatternsAfter(this)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
findPattern(_predicate: (p: Pattern) => boolean): Pattern | null {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
clone(name = this._name, isOptional = this._isOptional): Pattern {
|
|
155
|
+
return new Reference(name, isOptional);
|
|
156
|
+
}
|
|
127
157
|
}
|