lib/test.js
import * as assert from 'assert';
import Lexer from 'perplex';
import { Parser } from './index';
const lex = new Lexer('')
.token('NUM', /\d+/)
.token('+', /\+/)
.token('-', /-/)
.token('*', /\*/)
.token('/', /\//)
.token('^', /\^/)
.token('(', /\(/)
.token(')', /\)/)
.token('WS', /\s+/, true);
const parser = new Parser(lex)
.builder()
.bp('EOF', -1)
.nud('NUM', 100, t => parseInt(t.match))
.nud('(', 10, (t, bp) => {
const expr = parser.parse(bp);
lex.expect(')');
return expr;
})
.bp(')', 0)
.led('^', 20, (left, t, bp) => Math.pow(left, parser.parse(bp - 1)))
.led('+', 30, (left, t, bp) => left + parser.parse(bp))
.either('-', 30, (left, t, bp) => (left || 0) - parser.parse(bp))
.led('*', 40, (left, t, bp) => left * parser.parse(bp))
.led('/', 40, (left, t, bp) => left / parser.parse(bp))
.build();
function evaluate(s) {
lex.source = s;
return parser.parse();
}
assert.equal(evaluate('1 + 2 * (3 + 1) * 3'), 25);
assert.equal(evaluate('1^2^3'), 1);
assert.equal(evaluate('(1/2)^-1'), 2);
assert.equal(evaluate('4^3^2^1'), Math.pow(4, 9));
assert.equal(evaluate('-1-3'), -4);
assert.equal(evaluate('2*-3'), -6);
assert.equal(evaluate('-2*3'), -6);
assert.throws(() => evaluate('1+ +'), /Unexpected token: \+ \(at 1:4\)/);
console.log('All tests passed');
//# sourceMappingURL=test.js.map