clarity-pattern-parser
Version:
Parsing Library for Typescript and Javascript.
274 lines (235 loc) • 11.2 kB
text/typescript
import { Association, PrecedenceTree } from "./PrecedenceTree";
import { Node } from "../ast/Node";
describe("Precedence Tree", () => {
test("add Binary", () => {
const tree = new PrecedenceTree({
mul: 0,
add: 1,
bool: 2
}, {});
tree.addAtom(Node.createValueNode("literal", "a", "a"));
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
tree.addAtom(Node.createValueNode("literal", "b", "b"));
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
tree.addAtom(Node.createValueNode("literal", "c", "c"));
tree.addBinary("bool", Node.createValueNode("literal", "||", "||"));
tree.addAtom(Node.createValueNode("literal", "d", "d"));
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
tree.addAtom(Node.createValueNode("literal", "e", "e"));
const result = tree.commit();
const expected = Node.createNode("expression", "bool", [
Node.createNode("expression", "add", [
Node.createValueNode("literal", "a", "a"),
Node.createValueNode("literal", "+", "+"),
Node.createNode("expression", "mul", [
Node.createValueNode("literal", "b", "b"),
Node.createValueNode("literal", "*", "*"),
Node.createValueNode("literal", "c", "c"),
]),
]),
Node.createValueNode("literal", "||", "||"),
Node.createNode("expression", "add", [
Node.createValueNode("literal", "d", "d"),
Node.createValueNode("literal", "+", "+"),
Node.createValueNode("literal", "e", "e"),
]),
]);
expect(result?.toString()).toBe("a+b*c||d+e");
expect(result?.isEqual(expected));
});
test("add Prefix", () => {
const tree = new PrecedenceTree();
tree.addPrefix("negate", Node.createValueNode("literal", "!", "!"));
tree.addPrefix("increment", Node.createValueNode("literal", "++", "++"));
tree.addPrefix("plus", Node.createValueNode("literal", "+", "+"));
tree.addAtom(Node.createValueNode("literal", "a", "a"));
let result = tree.commit();
const expected = Node.createNode("expression", "negate", [
Node.createValueNode("literal", "!", "!"),
Node.createNode("expression", "increment", [
Node.createValueNode("literal", "++", "++"),
Node.createNode("expression", "plus", [
Node.createValueNode("literal", "+", "+"),
Node.createValueNode("literal", "a", "a"),
]),
]),
]);
expect(result?.toString()).toBe("!+++a");
expect(result?.isEqual(expected));
});
test("add Postfix", () => {
const tree = new PrecedenceTree();
tree.addPostfix("decrement", Node.createValueNode("literal", "--", "--"));
tree.addPostfix("increment", Node.createValueNode("literal", "++", "++"));
tree.addAtom(Node.createValueNode("literal", "a", "a"));
const expected = Node.createNode("expression", "increment", [
Node.createNode("expression", "decrement", [
Node.createValueNode("literal", "a", "a"),
Node.createValueNode("literal", "--", "--"),
]),
Node.createValueNode("literal", "++", "++"),
]);
const result = tree.commit();
expect(result?.toString()).toBe("a--++");
expect(result?.isEqual(expected));
});
test("all", () => {
const tree = new PrecedenceTree({
mul: 0,
add: 1,
bool: 2
}, {});
tree.addPrefix("negate", Node.createValueNode("literal", "!", "!"));
tree.addPostfix("increment", Node.createValueNode("literal", "++", "++"));
tree.addAtom(Node.createValueNode("literal", "a", "a"));
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
tree.addAtom(Node.createValueNode("literal", "b", "b"));
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
tree.addAtom(Node.createValueNode("literal", "c", "c"));
const result = tree.commit();
const expected = Node.createNode("expression", "add", [
Node.createNode("expression", "mul", [
Node.createNode("expression", "increment", [
Node.createNode("expression", "negate", [
Node.createValueNode("literal", "!", "!"),
Node.createValueNode("literal", "a", "a"),
]),
Node.createValueNode("literal", "++", "++"),
]),
Node.createValueNode("literal", "*", "*"),
Node.createValueNode("literal", "b", "b"),
]),
Node.createValueNode("literal", "+", "+"),
Node.createValueNode("literal", "c", "c"),
]);
expect(result?.toString()).toBe("!a++*b+c");
expect(result?.isEqual(expected));
});
test("Incomplete", () => {
const tree = new PrecedenceTree({
mul: 0,
add: 1,
bool: 2
}, {});
tree.addPrefix("negate", Node.createValueNode("literal", "!", "!"));
tree.addPostfix("increment", Node.createValueNode("literal", "++", "++"));
tree.addAtom(Node.createValueNode("literal", "a", "a"));
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
tree.addAtom(Node.createValueNode("literal", "b", "b"));
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
tree.addAtom(Node.createValueNode("literal", "c", "c"));
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
const result = tree.commit();
const expected = Node.createNode("expression", "add", [
Node.createNode("expression", "mul", [
Node.createNode("expression", "increment", [
Node.createNode("expression", "negate", [
Node.createValueNode("literal", "!", "!"),
Node.createValueNode("literal", "a", "a"),
]),
Node.createValueNode("literal", "++", "++"),
]),
Node.createValueNode("literal", "*", "*"),
Node.createValueNode("literal", "b", "b"),
]),
Node.createValueNode("literal", "+", "+"),
Node.createValueNode("literal", "c", "c"),
]);
expect(result?.toString()).toBe("!a++*b+c");
expect(result?.isEqual(expected));
});
test("add Partial Binary With Lower Precedence", () => {
const tree = new PrecedenceTree({
mul: 0,
add: 1,
bool: 2
}, {});
tree.addAtom(Node.createValueNode("literal", "a", "a"));
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
tree.addAtom(Node.createValueNode("literal", "b", "b"));
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
tree.addAtom(Node.createValueNode("literal", "c", "c"));
tree.addBinary("bool", Node.createValueNode("literal", "||", "||"));
const result = tree.commit();
const expected = Node.createNode("expression", "add", [
Node.createValueNode("literal", "a", "a"),
Node.createValueNode("literal", "+", "+"),
Node.createNode("expression", "mul", [
Node.createValueNode("literal", "b", "b"),
Node.createValueNode("literal", "*", "*"),
Node.createValueNode("literal", "c", "c"),
]),
]);
expect(result?.toString()).toBe("a+b*c");
expect(result?.isEqual(expected));
});
test("add Partial Binary With Equal Precedence", () => {
const tree = new PrecedenceTree({
mul: 0,
add: 1,
bool: 2
}, {});
tree.addAtom(Node.createValueNode("literal", "a", "a"));
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
tree.addAtom(Node.createValueNode("literal", "b", "b"));
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
tree.addAtom(Node.createValueNode("literal", "c", "c"));
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
const result = tree.commit();
const expected = Node.createNode("expression", "add", [
Node.createValueNode("literal", "a", "a"),
Node.createValueNode("literal", "+", "+"),
Node.createNode("expression", "mul", [
Node.createValueNode("literal", "b", "b"),
Node.createValueNode("literal", "*", "*"),
Node.createValueNode("literal", "c", "c"),
]),
]);
expect(result?.toString()).toBe("a+b*c");
expect(result?.isEqual(expected));
});
test("add Partial Binary With Equal Precedence And Right Associated", () => {
const tree = new PrecedenceTree({
mul: 0,
add: 1,
bool: 2
}, { mul: Association.right });
tree.addAtom(Node.createValueNode("literal", "a", "a"));
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
tree.addAtom(Node.createValueNode("literal", "b", "b"));
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
tree.addAtom(Node.createValueNode("literal", "c", "c"));
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
const result = tree.commit();
const expected = Node.createNode("expression", "add", [
Node.createValueNode("literal", "a", "a"),
Node.createValueNode("literal", "+", "+"),
Node.createNode("expression", "mul", [
Node.createValueNode("literal", "b", "b"),
Node.createValueNode("literal", "*", "*"),
Node.createValueNode("literal", "c", "c"),
]),
]);
expect(result?.toString()).toBe("a+b*c");
expect(result?.isEqual(expected));
});
test("mul Partial Binary With Greater Precedence", () => {
const tree = new PrecedenceTree({
mul: 0,
add: 1,
bool: 2
}, {});
tree.addAtom(Node.createValueNode("literal", "a", "a"));
tree.addBinary("add", Node.createValueNode("literal", "+", "+"));
tree.addAtom(Node.createValueNode("literal", "b", "b"));
tree.addBinary("mul", Node.createValueNode("literal", "*", "*"));
const result = tree.commit();
const expected = Node.createNode("expression", "add", [
Node.createValueNode("literal", "a", "a"),
Node.createValueNode("literal", "+", "+"),
Node.createValueNode("literal", "b", "b"),
]);
expect(result?.toString()).toBe("a+b");
expect(result?.isEqual(expected));
});
});