expression-calculator
Version:
Calculate expressions without using `eval()`, using LL(1) syntax analyzer.
320 lines (176 loc) • 7.25 kB
Markdown
<a name='english'></a>
expression-calculator
=====================
[English](#english) | [中文](#chinese)
A simple expression parser, using LL(1) syntax analyzer.
Useful to parse and calculate expression without using `eval()`, so as to avoid all the security risks caused by `eval()`.
[Click here to open demo page](https://frank-deng.github.io/expression-calculator/)
Installation
------------
npm install --save expression-calculator
Import
------
ES6/Webpack
import Calc from 'expression-calculator';
Node.js
const Calc=require('expression-calculator');
Script Tag
<script type='text/javascript' src='./dist/exprcalc.js'></script>
Initialization
--------------
### `const calc = new Calc();`
Initialize a new instance of `Calc()` with empty RPN expression.
### `const calc = new Calc(expression);`
Initialize a new instance of `Calc()`, then compile the given expression into RPN (`compile()` method is called internally).
### `const calc = new Calc(RPN);`
Initialize a new instance of `Calc()`, then load the given RPN data (`setRPN()` method is called internally).
### `const calc = new Calc(calcInstance);`
Get a copy of the given `Calc()` instance.
Methods
-------
### `compile(expr)`
Compile an expression into an RPN expression.
**Parameters**
* `expr` - The string to be compiled.
**Returns**
A reference to this instance for chaining.
**Throws**
* `SyntaxError` - If the given expression contains error.
### `calc(vars)`
Calculate the previously compiled expression.
The compiled expression may contain variables, use a key-value dict to specify values for variables in the expression. Variable names are case sensitive.
**Parameters**
* `vars` - A dict contains key-value pairs (Required when the RPN contains variables, and all the variables in the RPN expression must have a value here).
**Returns**
The calculation result, or `null` if no RPN is loaded or compiled from expression.
**Throws**
* `TypeError` - When the value of a variable is not a number.
* `ReferenceError` - When the value of a variable is not given in the `vars` parameter.
**Example**
var calc = new Calc();
calc.compile('3+4').calc(); //Result: 7
calc.compile('3+4-a').calc({a:-10}); //Result: 17
### `getRPN()`
Get the compiled RPN expression.
**Returns**
Returns the compiled RPN which can be converted into JSON, or `null` for empty RPN.
**Example**
var calc = new Calc();
calc.compile('3*(5+a)').getRPN();
The code above will generate the following JSON data:
[
{type:1, value:3},
{type:1, value:5},
{type:2, value:"a"},
{type:3, value:"+"},
{type:3, value:"*"}
]
In the expression above, each token's type value has an alias, you may refer to **Aliases** section for detail.
### `toJSON()`
Alias of `getRPN()` method, used for serialization via `JSON.stringify()`.
### `setRPN(expr)`
Load previously compiled RPN from other source like database or memcache/redis.
**Parameters**
* `expr` - The RPN expression, with the same format as data returned by method `getRPN()`.
**Returns**
A reference to this instance for chaining.
**Throws**
* `TypeError` - If the given RPN contains tokens with invalid type or value.
* `SyntaxError` - If the given RPN contains invalid tokens or errors.
### `compress()`
Reduce the size of RPN by precalculating the numbers.
**Returns**
A reference to this instance for chaining.
Aliases
-------
* `Calc.TOKEN_NUM` - Value is `1`, marks RPN tokens as number type.
* `Calc.TOKEN_VAR` - Value is `2`, marks RPN tokens as variable type.
* `Calc.TOKEN_OPER` - Value is `3`, marks RPN tokens as operand type.
<a name='chinese'></a>
expression-calculator
=====================
[English](#english) | [中文](#chinese)
一个简单的表达式解析器,使用LL(1)语法分析器。
可用于代替`eval()`函数来实现表达式的解析和计算,以避免`eval()`带来的相关安全风险。
[单击此处打开演示页面](https://frank-deng.github.io/expression-calculator/)
安装
----
npm install --save expression-calculator
引入
----
ES6/Webpack
import Calc from 'expression-calculator';
Node.js
const Calc=require('expression-calculator');
Script标签
<script type='text/javascript' src='path/to/exprcalc.js'></script>
初始化
------
### `const calc = new Calc();`
初始化一个逆波兰式为空的`Calc()`实例。
### `const calc = new Calc(expression);`
初始化一个新的`Calc()`实例,然后将给定的算式编译成逆波兰式(初始化时会在内部调用`compile()`方法)。
### `const calc = new Calc(RPN);`
初始化一个新的`Calc()`实例,然后加载给定的逆波兰式(初始化时会在内部调用`setRPN()`方法)。
### `const calc = new Calc(calcInstance);`
复制参数中指定的`Calc()`实例。
方法说明
--------
### `compile(expr)`
将给定的算式编译成逆波兰式。
**参数**
* `expr` - 待编译的表达式字符串。
**返回**
当前对象的引用,可供链式操作。
**异常**
* `SyntaxError` - 当给定的表达式有错误时。
### `calc(vars)`
计算被编译的表达式。
被编译的表达式中可能含有变量,可用含键值对的`Object`指定各个变量的值。变量名区分大小写,支持中文变量名。
**参数**
* `vars` - `Object`格式的键值对,用于给变量指定值(当表达式中有变量时,该参数为必要参数,且表达式中所有变量的值都必须在此指定)。
**返回**
计算结果,如果逆波兰式为空则返回`null`。
**异常**
* `TypeError` - 存在值不为数字类型的变量。
* `ReferenceError` - 表达式中有变量未指定值。
**范例**
var calc = new Calc();
calc.compile('3+4').calc(); //Result: 7
calc.compile('3+4-a').calc({a:-10}); //Result: 17
### `getRPN()`
获取编译过的逆波兰式。
**返回**
返回编译过的逆波兰式,可直接转换成JSON字符串。如果逆波兰式为空则返回`null`。
**范例**
var calc = new Calc();
calc.compile('3*(5+a)').getRPN();
以上代码将返回以下数据:
[
{type:1, value:3},
{type:1, value:5},
{type:2, value:"a"},
{type:3, value:"+"},
{type:3, value:"*"}
]
在以上逆波兰式中,所有项目的`type`值都有对应的别名,可参考**常用别名**小节。
### `toJSON()`
`getRPN()`方法的别名,在使用`JSON.stringify()`序列化时用到。
### `setRPN(expr)`
从外部加载已编译的逆波兰式。
**参数**
* `expr` - 待加载的逆波兰式数据,格式和`getRPN()`方法返回的相同。
**返回**
当前对象的引用,可供链式操作。
**异常**
* `TypeError` - 给定的逆波兰式中存在含有错误数据格式的数据项。
* `SyntaxError` - 给定的逆波兰式存在非法数据项或存在错误。
### `compress()`
压缩逆波兰式,通过提前对数字进行运算的方式。
**返回**
当前对象的引用,可供链式操作。
常用别名
-------
* `Calc.TOKEN_NUM` - 值为`1`,将当前逆波兰式项目标记为数字类型。
* `Calc.TOKEN_VAR` - 值为`2`,将当前逆波兰式项目标记为变量类型。
* `Calc.TOKEN_OPER` - 值为`3`,将当前逆波兰式项目标记为运算符类型。