expression parser
npm install @adifkz/exp-p
The Expression Parser library, also known as "@adifkz/exp-p," is a powerful tool for parsing and evaluating mathematical and logical expressions. It provides a flexible and extensible solution for integrating expression parsing capabilities into your projects. This documentation will guide you through the usage, customization options, and API of the library. You can find the library on npm under the package name "@adifkz/exp-p" and the source code on GitHub at https://github.com/adyfk/exp-p.
- Evaluate mathematical expressions with operators like +, -, *, /, %, ^, etc.
- Evaluate logical expressions with operators like AND, OR, NOT, etc.
- Support for parentheses to control the order of operations.
- Define and use variables in your expressions.
- Define custom functions to extend the functionality of the parser.
- Evaluate string literals.
- Evaluate array literals and perform operations on arrays.
- Evaluate object literals and access properties dynamically.
You can install ExpressionParser using npm:
``bash`
npm install @adifkz/exp-p
`typescript
import { createParser } from '@adifkz/exp-p';
const parser = createParser();
`
`typescript
const parser = createParser();
const result = parser.evaluate('2 + 3 * 4'); // 14
`
`typescript
const parser = createParser();
// Define variables
const variables = {
x: 5,
y: 10,
};
// Evaluate expression with variables
const result = parser.evaluate("x + y", variables);
console.log(result); // Output: 15
`
`typescript
const parser = createParser();
// Define custom function
const functions = {
square: (_, value: number) => value * value,
};
parser.setFunctions(functions)
// Evaluate expression with custom function
const result = parser.evaluate("square(5)");
console.log(result); // Output: 25
`
`typescript
import moment from 'moment'
import { createParser, FunctionMap } from '../'
describe('example', () => {
it('basic operator', () => {
const parser = createParser({
})
expect(parser.evaluate('(2 + 3) * 4 - 4')).toBe(16)
expect(parser.evaluate('-4 + 5')).toBe(1)
expect(parser.evaluate('4 <= (5 + 2)')).toBe(true)
expect(parser.evaluate('4 > 5')).toBe(false)
expect(parser.evaluate('5 ^ 2 + 2')).toBe(27)
expect(parser.evaluate('5 + 4 * 4')).toBe(21)
expect(parser.evaluate('5 % 3')).toBe(2)
expect(parser.evaluate('5.5 * 3')).toBe(16.5)
expect(parser.evaluate('5 == 5')).toBe(true)
});
it('function', () => {
// Usage example
const variables = { x: 5 };
const functions: FunctionMap = {
add: (_, a: number, b: number) => a + b,
length: (_, str: string) => str.length,
length_all: (_, str1: string, str2: string, str3: string) => [str1.length, str2.length, str3.length],
};
const parser = createParser({ variables });
parser.setFunctions(functions)
expect(parser.evaluate('add(1 + 1, 5) + x')).toBe(12)
expect(parser.evaluate('length("ADI") + 5', variables)).toBe(8)
expect(parser.evaluate('length_all("ADI", "FA", "TK")', variables)).toEqual([3, 2, 2])
});
it('string', () => {
const parser = createParser();
expect(parser.evaluate('"ADI"')).toBe("ADI")
expect(parser.evaluate('\'ADI\'')).toBe("ADI")
expect(parser.evaluate('regex("ddd212sdf","\\d\\w\\d")')).toBe(true)
expect(parser.evaluate('regex("ddd212sdf","\\d\\w\\d","y")')).toBe(false)
})
it('boolean', () => {
const parser = createParser();
expect(parser.evaluate('true and false')).toBe(false)
expect(parser.evaluate('true or false')).toBe(true)
expect(parser.evaluate('!true')).toBe(false)
expect(parser.evaluate('!!true')).toBe(true)
})
it('array', () => {
const parser = createParser();
expect(parser.evaluate("[1, 2, 3, 4]")).toEqual([1, 2, 3, 4])
expect(parser.evaluate("[\"2\", 5]")).toEqual(["2", 5])
expect(parser.evaluate("[2 + 5, 5]")).toEqual([7, 5])
expect(parser.evaluate("[5, x]", { x: 2 })).toEqual([5, 2])
})
it('array method', () => {
const parser = createParser();
const products = [
{ name: 'Product 1', price: 150, quantity: 2 },
{ name: 'Product 2', price: 80, quantity: 0 },
{ name: 'Product 3', price: 200, quantity: 5 },
{ name: 'Product 4', price: 120, quantity: 1 }
];
expect(
parser.evaluate('filter(products, "_item_.price > 100 and _item_.quantity > 0")', {
products
})
).toEqual([
{ name: 'Product 1', price: 150, quantity: 2 },
{ name: 'Product 3', price: 200, quantity: 5 },
{ name: 'Product 4', price: 120, quantity: 1 }
])
expect(
parser.evaluate('map(products, "_item_.name")', {
products
})
).toEqual([
'Product 1',
'Product 2',
'Product 3',
'Product 4',
])
expect(
parser.evaluate('find(products, "_item_.price > 0")', {
products
})
).toEqual({
"name": "Product 1",
"price": 150,
"quantity": 2
})
expect(
parser.evaluate('some(products, "_item_.price == 200")', {
products
})
).toBe(true)
expect(
parser.evaluate('reduce(products, "_curr_ + _item_.price", 0)', {
products
})
).toBe(550)
})
it('object', () => {
const parser = createParser();
expect(parser.evaluate("{ name: 'ADI', age: 20 }")).toEqual({
name: "ADI",
age: 20
})
expect(parser.evaluate("{ name: 'ADI', age: 5 + 2 }")).toEqual({
name: "ADI",
age: 7
})
expect(parser.evaluate("object.name", { object: { name: 'ADI' } })).toEqual('ADI')
expect(parser.evaluate("object.name", { object: { name: 'ADI' } })).toEqual('ADI')
expect(parser.evaluate("object.0.name", { object: [{ name: 'ADI' }] })).toEqual('ADI')
expect(parser.evaluate("object.0.object.0.name", { object: [{ name: 'ADI', object: [{ name: "ADI" }] }] })).toEqual('ADI')
})
it('date', () => {
const parser = createParser();
// expect(parser.evaluate(date())).toBe(moment().toISOString())date("2020-01-01")
expect(parser.evaluate()).toBe('2019-12-31T17:00:00.000Z')date_day(date("2020-01-01"))
expect(parser.evaluate()).toBe(1)date_month(date("2020-01-01"))
expect(parser.evaluate()).toBe(1)date_year(date("2020-01-01"))
expect(parser.evaluate()).toBe(2020)date_format("DD-MM-YYYY", "2020-01-01")
expect(parser.evaluate()).toBe("01-01-2020")date_in_format("YYYY-MM-DD", "2020-01-01")
expect(parser.evaluate()).toBe('2019-12-31T17:00:00.000Z')date_in_millis(${moment("2020/01/01", 'YYYY/MM/DD').valueOf()})
expect(parser.evaluate()).toBe('2019-12-31T17:00:00.000Z')date_millis("2020-01-01")
expect(parser.evaluate()).toBe(1577811600000)date_format("DD-MM-YYYY", date_plus(1, "day", "2020-01-05"))
expect(parser.evaluate()).toBe("06-01-2020")date_format("DD-MM-YYYY", date_plus(-1, "day", "2020-01-05"))
expect(parser.evaluate()).toBe("04-01-2020")date_format("DD-MM-YYYY", date_minus(1, "day", "2020-01-05"))
expect(parser.evaluate()).toBe("04-01-2020")date_format("DD-MM-YYYY", date_minus(-1, "day", "2020-01-05"))
expect(parser.evaluate()).toBe("06-01-2020")``
})
});