clarity-pattern-parser 11.0.3 → 11.0.4
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/dist/index.browser.js +26 -6
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +26 -6
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +26 -6
- package/dist/index.js.map +1 -1
- package/dist/patterns/PrecedenceTree.d.ts +1 -1
- package/package.json +1 -1
- package/src/patterns/PrecedenceTree.test.ts +113 -1
- package/src/patterns/PrecedenceTree.ts +35 -7
|
@@ -11,9 +11,9 @@ export declare class PrecedenceTree {
|
|
|
11
11
|
private _binaryPlaceholder;
|
|
12
12
|
private _binaryNode;
|
|
13
13
|
private _atomNode;
|
|
14
|
-
private _orphanedAtom;
|
|
15
14
|
private _precedenceMap;
|
|
16
15
|
private _associationMap;
|
|
16
|
+
private _revertBinary;
|
|
17
17
|
constructor(precedenceMap?: Record<string, number>, associationMap?: Record<string, Association>);
|
|
18
18
|
addPrefix(name: string, ...prefix: Node[]): void;
|
|
19
19
|
addPostfix(name: string, ...postfix: Node[]): void;
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PrecedenceTree } from "./PrecedenceTree";
|
|
1
|
+
import { Association, PrecedenceTree } from "./PrecedenceTree";
|
|
2
2
|
import { Node } from "../ast/Node";
|
|
3
3
|
|
|
4
4
|
describe("Precedence Tree", () => {
|
|
@@ -159,4 +159,116 @@ describe("Precedence Tree", () => {
|
|
|
159
159
|
expect(result?.toString()).toBe("!a++*b+c");
|
|
160
160
|
expect(result?.toCycleFreeObject()).toEqual(expected.toCycleFreeObject());
|
|
161
161
|
});
|
|
162
|
+
|
|
163
|
+
test("add Partial Binary With Lower Precedence", () => {
|
|
164
|
+
const tree = new PrecedenceTree({
|
|
165
|
+
mul: 0,
|
|
166
|
+
add: 1,
|
|
167
|
+
bool: 2
|
|
168
|
+
}, {});
|
|
169
|
+
|
|
170
|
+
tree.addAtom(Node.createValueNode("literal", "a", "a"));
|
|
171
|
+
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
|
|
172
|
+
tree.addAtom(Node.createValueNode("literal", "b", "b"));
|
|
173
|
+
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
|
|
174
|
+
tree.addAtom(Node.createValueNode("literal", "c", "c"));
|
|
175
|
+
tree.addBinary("bool", Node.createValueNode("literal", "||", "||"));
|
|
176
|
+
|
|
177
|
+
const result = tree.commit();
|
|
178
|
+
const expected = Node.createNode("expression", "add", [
|
|
179
|
+
Node.createValueNode("literal", "a", "a"),
|
|
180
|
+
Node.createValueNode("literal", "+", "+"),
|
|
181
|
+
Node.createNode("expression", "mul", [
|
|
182
|
+
Node.createValueNode("literal", "b", "b"),
|
|
183
|
+
Node.createValueNode("literal", "*", "*"),
|
|
184
|
+
Node.createValueNode("literal", "c", "c"),
|
|
185
|
+
]),
|
|
186
|
+
]);
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
expect(result?.toString()).toBe("a+b*c");
|
|
190
|
+
expect(result?.toCycleFreeObject()).toEqual(expected.toCycleFreeObject());
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test("add Partial Binary With Equal Precedence", () => {
|
|
194
|
+
const tree = new PrecedenceTree({
|
|
195
|
+
mul: 0,
|
|
196
|
+
add: 1,
|
|
197
|
+
bool: 2
|
|
198
|
+
}, {});
|
|
199
|
+
|
|
200
|
+
tree.addAtom(Node.createValueNode("literal", "a", "a"));
|
|
201
|
+
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
|
|
202
|
+
tree.addAtom(Node.createValueNode("literal", "b", "b"));
|
|
203
|
+
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
|
|
204
|
+
tree.addAtom(Node.createValueNode("literal", "c", "c"));
|
|
205
|
+
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
|
|
206
|
+
|
|
207
|
+
const result = tree.commit();
|
|
208
|
+
const expected = Node.createNode("expression", "add", [
|
|
209
|
+
Node.createValueNode("literal", "a", "a"),
|
|
210
|
+
Node.createValueNode("literal", "+", "+"),
|
|
211
|
+
Node.createNode("expression", "mul", [
|
|
212
|
+
Node.createValueNode("literal", "b", "b"),
|
|
213
|
+
Node.createValueNode("literal", "*", "*"),
|
|
214
|
+
Node.createValueNode("literal", "c", "c"),
|
|
215
|
+
]),
|
|
216
|
+
]);
|
|
217
|
+
|
|
218
|
+
expect(result?.toString()).toBe("a+b*c");
|
|
219
|
+
expect(result?.toCycleFreeObject()).toEqual(expected.toCycleFreeObject());
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test("add Partial Binary With Equal Precedence And Right Associated", () => {
|
|
223
|
+
const tree = new PrecedenceTree({
|
|
224
|
+
mul: 0,
|
|
225
|
+
add: 1,
|
|
226
|
+
bool: 2
|
|
227
|
+
}, { mul: Association.right });
|
|
228
|
+
|
|
229
|
+
tree.addAtom(Node.createValueNode("literal", "a", "a"));
|
|
230
|
+
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
|
|
231
|
+
tree.addAtom(Node.createValueNode("literal", "b", "b"));
|
|
232
|
+
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
|
|
233
|
+
tree.addAtom(Node.createValueNode("literal", "c", "c"));
|
|
234
|
+
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
|
|
235
|
+
|
|
236
|
+
const result = tree.commit();
|
|
237
|
+
const expected = Node.createNode("expression", "add", [
|
|
238
|
+
Node.createValueNode("literal", "a", "a"),
|
|
239
|
+
Node.createValueNode("literal", "+", "+"),
|
|
240
|
+
Node.createNode("expression", "mul", [
|
|
241
|
+
Node.createValueNode("literal", "b", "b"),
|
|
242
|
+
Node.createValueNode("literal", "*", "*"),
|
|
243
|
+
Node.createValueNode("literal", "c", "c"),
|
|
244
|
+
]),
|
|
245
|
+
]);
|
|
246
|
+
|
|
247
|
+
expect(result?.toString()).toBe("a+b*c");
|
|
248
|
+
expect(result?.toCycleFreeObject()).toEqual(expected.toCycleFreeObject());
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
test("add Partial Binary With Greater Precedence", () => {
|
|
252
|
+
const tree = new PrecedenceTree({
|
|
253
|
+
mul: 0,
|
|
254
|
+
add: 1,
|
|
255
|
+
bool: 2
|
|
256
|
+
}, {});
|
|
257
|
+
|
|
258
|
+
tree.addAtom(Node.createValueNode("literal", "a", "a"));
|
|
259
|
+
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
|
|
260
|
+
tree.addAtom(Node.createValueNode("literal", "b", "b"));
|
|
261
|
+
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
const result = tree.commit();
|
|
265
|
+
const expected = Node.createNode("expression", "add", [
|
|
266
|
+
Node.createValueNode("literal", "a", "a"),
|
|
267
|
+
Node.createValueNode("literal", "+", "+"),
|
|
268
|
+
Node.createValueNode("literal", "b", "b"),
|
|
269
|
+
]);
|
|
270
|
+
|
|
271
|
+
expect(result?.toString()).toBe("a+b");
|
|
272
|
+
expect(result?.toCycleFreeObject()).toEqual(expected.toCycleFreeObject());
|
|
273
|
+
});
|
|
162
274
|
});
|
|
@@ -13,9 +13,9 @@ export class PrecedenceTree {
|
|
|
13
13
|
private _binaryPlaceholder: Node;
|
|
14
14
|
private _binaryNode: Node | null;
|
|
15
15
|
private _atomNode: Node | null;
|
|
16
|
-
private _orphanedAtom: Node | null;
|
|
17
16
|
private _precedenceMap: Record<string, number>;
|
|
18
17
|
private _associationMap: Record<string, Association>;
|
|
18
|
+
private _revertBinary: () => void;
|
|
19
19
|
|
|
20
20
|
constructor(precedenceMap: Record<string, number> = {}, associationMap: Record<string, Association> = {}) {
|
|
21
21
|
this._prefixPlaceholder = Node.createNode("placeholder", "prefix-placeholder");
|
|
@@ -25,9 +25,9 @@ export class PrecedenceTree {
|
|
|
25
25
|
this._binaryPlaceholder = Node.createNode("placeholder", "binary-placeholder");
|
|
26
26
|
this._atomNode = null;
|
|
27
27
|
this._binaryNode = null;
|
|
28
|
-
this._orphanedAtom = null;
|
|
29
28
|
this._precedenceMap = precedenceMap;
|
|
30
29
|
this._associationMap = associationMap;
|
|
30
|
+
this._revertBinary = () => { };
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
addPrefix(name: string, ...prefix: Node[]) {
|
|
@@ -72,12 +72,17 @@ export class PrecedenceTree {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
this._binaryPlaceholder.remove();
|
|
75
|
-
this._orphanedAtom = lastAtomNode;
|
|
76
75
|
|
|
77
76
|
if (lastBinaryNode == null) {
|
|
78
77
|
const node = Node.createNode("expression", name, [lastAtomNode, ...delimiterNode, this._binaryPlaceholder]);
|
|
79
78
|
|
|
80
79
|
this._binaryNode = node;
|
|
80
|
+
|
|
81
|
+
this._revertBinary = () => {
|
|
82
|
+
lastAtomNode.remove();
|
|
83
|
+
this._binaryNode = lastAtomNode;
|
|
84
|
+
};
|
|
85
|
+
|
|
81
86
|
return;
|
|
82
87
|
}
|
|
83
88
|
|
|
@@ -86,6 +91,11 @@ export class PrecedenceTree {
|
|
|
86
91
|
|
|
87
92
|
lastBinaryNode.appendChild(node);
|
|
88
93
|
|
|
94
|
+
this._revertBinary = () => {
|
|
95
|
+
node.replaceWith(lastAtomNode);
|
|
96
|
+
this._binaryNode = lastBinaryNode;
|
|
97
|
+
};
|
|
98
|
+
|
|
89
99
|
this._binaryNode = node;
|
|
90
100
|
} else if (precedence === lastPrecendece) {
|
|
91
101
|
const node = Node.createNode("expression", name, []);
|
|
@@ -94,6 +104,13 @@ export class PrecedenceTree {
|
|
|
94
104
|
lastBinaryNode.appendChild(lastAtomNode);
|
|
95
105
|
|
|
96
106
|
node.append(lastBinaryNode, ...delimiterNode, this._binaryPlaceholder);
|
|
107
|
+
|
|
108
|
+
this._revertBinary = () => {
|
|
109
|
+
lastBinaryNode.remove();
|
|
110
|
+
node.replaceWith(lastBinaryNode);
|
|
111
|
+
this._binaryNode = lastBinaryNode;
|
|
112
|
+
};
|
|
113
|
+
|
|
97
114
|
this._binaryNode = node;
|
|
98
115
|
} else if (precedence > lastPrecendece) {
|
|
99
116
|
let ancestor = lastBinaryNode.parent;
|
|
@@ -115,6 +132,12 @@ export class PrecedenceTree {
|
|
|
115
132
|
root.replaceWith(node);
|
|
116
133
|
node.append(root, ...delimiterNode, this._binaryPlaceholder);
|
|
117
134
|
|
|
135
|
+
this._revertBinary = () => {
|
|
136
|
+
root.remove();
|
|
137
|
+
node.replaceWith(root);
|
|
138
|
+
this._binaryNode = root;
|
|
139
|
+
};
|
|
140
|
+
|
|
118
141
|
this._binaryNode = node;
|
|
119
142
|
|
|
120
143
|
|
|
@@ -122,6 +145,12 @@ export class PrecedenceTree {
|
|
|
122
145
|
const node = Node.createNode("expression", name, [lastAtomNode, ...delimiterNode, this._binaryPlaceholder]);
|
|
123
146
|
lastBinaryNode.appendChild(node);
|
|
124
147
|
|
|
148
|
+
this._revertBinary = () => {
|
|
149
|
+
lastAtomNode.remove();
|
|
150
|
+
node.replaceWith(lastAtomNode);
|
|
151
|
+
this._binaryNode = lastBinaryNode;
|
|
152
|
+
};
|
|
153
|
+
|
|
125
154
|
this._binaryNode = node;
|
|
126
155
|
}
|
|
127
156
|
|
|
@@ -171,7 +200,7 @@ export class PrecedenceTree {
|
|
|
171
200
|
this._atomNode = node;
|
|
172
201
|
}
|
|
173
202
|
|
|
174
|
-
hasAtom(){
|
|
203
|
+
hasAtom() {
|
|
175
204
|
return this._atomNode != null;
|
|
176
205
|
}
|
|
177
206
|
|
|
@@ -183,8 +212,8 @@ export class PrecedenceTree {
|
|
|
183
212
|
const atomNode = this._compileAtomNode();
|
|
184
213
|
|
|
185
214
|
if (atomNode == null) {
|
|
186
|
-
|
|
187
|
-
this.
|
|
215
|
+
this._revertBinary();
|
|
216
|
+
let root = this._binaryNode.findRoot();
|
|
188
217
|
this.reset();
|
|
189
218
|
return root;
|
|
190
219
|
} else {
|
|
@@ -199,7 +228,6 @@ export class PrecedenceTree {
|
|
|
199
228
|
private reset() {
|
|
200
229
|
this._prefixNode = null;
|
|
201
230
|
this._atomNode = null;
|
|
202
|
-
this._orphanedAtom = null;
|
|
203
231
|
this._postfixNode = null;
|
|
204
232
|
this._binaryNode = null;
|
|
205
233
|
}
|