@abdullah2993/expression-parser 中文文档教程

发布于 3年前 浏览 27 项目主页 更新于 3年前

expression-parser Build

用打字稿编写的表达式求值器,目标是支持 SQL 之类的 WHERE 子句。

Installation

npm install --save @abdullah2993/expression-parser

Supported Operations and Functions

Arithmetics

  • +
  • -
  • *
  • /

Comparison

  • =
  • <>
  • >
  • >=
  • <=

Logical

  • and
  • or

SQL

  • IS NULL
  • IS NOT NULL
  • BETWEEN [NUMBER] AND [NUMBER]
  • CASE WHEN expression THEN expression [WHEN expression] [ELSE expression] END

Functions

目前唯一被评估的函数是 LENGTH(variable) 函数,但支持解析器级别的函数调用,因此添加更多 SQL 函数相当容易。

Examples

/** Basic Math **/
evaluate('1+2'));
// 3
evaluate('10 + 2 * 6'));
// 22
evaluate('100 * 2 + 12'));
// 212
evaluate('100 * ( 2 + 12 )'));
// 1400
evaluate('100 * ( 2 + 12 ) / 14'));
// 100


/** Basic Math With Variable Substitution**/

const context = {
  a: 1, b: 2, c: 10, d: 6, e: 100, f: 12, g: 14,
};

evaluateObject('a+b', context));
// 3
evaluateObject('c + b * d', context));
// 22
evaluateObject('e * b + f', context));
// 212
evaluateObject('e * ( b + f )', context));
// 1400
evaluateObject('e * ( b + f ) / g', context));
// 100

/** Other Operations **/
const val: any = { a: null };
evaluateObject('a is not null and length(a) between 4 and 10', val);
// false
const val = { a: '123' };
evaluateObject('a is not null and length(a) between 4 and 10', val);
// false
const val = { a: '1234' };
evaluateObject('a is not null and length(a) between 4 and 10', val);
// true
const val = { a: '1234567890' };
evaluateObject('a is not null and length(a) between 4 and 10', val);
// true
const val = { a: '12345678901' };
evaluateObject('a is not null and length(a) between 4 and 10', val);
// false
const val: any = { a: 1, b: 1 };
evaluateObject('a is not null and b is not null', val);
// true
evaluateObject('a is not null and b is null', val);
// false
const val = { a: 1, b: null };
evaluateObject('a is not null and b is null', val);
// true
const val = { a: 1, b: 1 };
evaluateObject('a=b', val));
// true
evaluateObject('a>b', val));
// false
evaluateObject('a<b', val));
// false
const val = { a: 1, b: 2 };
evaluateObject('a=b', val);
// false
evaluateObject('a>b', val);
// false
evaluateObject('a<b', val);
// true

Sample AST

//Expression: a is not null and length(a) between 4 and 10
{
  "operator": "and",
  "left": {
    "operator": "<>",
    "left": {
      "name": "a",
      "type": "IdentifierExpression"
    },
    "right": {
      "value": null,
      "type": "ValueExpression"
    },
    "type": "BinaryExpression"
  },
  "right": {
    "operator": "and",
    "left": {
      "operator": ">=",
      "left": {
        "name": "length",
        "args": [
          {
            "name": "a",
            "type": "IdentifierExpression"
          }
        ],
        "type": "FunctionCallExpression"
      },
      "right": {
        "value": 4,
        "type": "ValueExpression"
      },
      "type": "BinaryExpression"
    },
    "right": {
      "operator": "<=",
      "left": {
        "name": "length",
        "args": [
          {
            "name": "a",
            "type": "IdentifierExpression"
          }
        ],
        "type": "FunctionCallExpression"
      },
      "right": {
        "value": 10,
        "type": "ValueExpression"
      },
      "type": "BinaryExpression"
    },
    "type": "BinaryExpression"
  },
  "type": "BinaryExpression"
}

Test Coverage

13 specs, 0 failures
Finished in 0.069 seconds
Randomized with seed 62175 (jasmine --random=true --seed=62175)
--------------|---------|----------|---------|---------|-----------------------------------
File          | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------|---------|----------|---------|---------|-----------------------------------
All files     |   93.24 |    83.33 |   92.73 |   93.19 |
 ast.ts       |   89.66 |      100 |      90 |      90 | 16-18
 evaluator.ts |      85 |    69.23 |     100 |   84.21 | 14,18,27,47-49,64
 lexer.ts     |   99.04 |       98 |     100 |   99.03 | 86
 parser.ts    |   89.89 |       70 |   89.47 |   89.41 | 83,91,103,121,133,137,144,181,184
 token.ts     |   97.06 |      100 |      75 |   96.97 | 44
--------------|---------|----------|---------|---------|-----------------------------------

expression-parser Build

An expression evaluator written in typescript with the goal to support SQL like WHERE clauses.

Installation

npm install --save @abdullah2993/expression-parser

Supported Operations and Functions

Arithmetics

  • +
  • -
  • *
  • /

Comparison

  • =
  • <>
  • >
  • >=
  • <=

Logical

  • and
  • or

SQL

  • IS NULL
  • IS NOT NULL
  • BETWEEN [NUMBER] AND [NUMBER]
  • CASE WHEN expression THEN expression [WHEN expression] [ELSE expression] END

Functions

Currently only function that is evaluated is the LENGTH(variable) function but supports function calls at the parser level so it is fairly easy to add more SQL functions.

Examples

/** Basic Math **/
evaluate('1+2'));
// 3
evaluate('10 + 2 * 6'));
// 22
evaluate('100 * 2 + 12'));
// 212
evaluate('100 * ( 2 + 12 )'));
// 1400
evaluate('100 * ( 2 + 12 ) / 14'));
// 100


/** Basic Math With Variable Substitution**/

const context = {
  a: 1, b: 2, c: 10, d: 6, e: 100, f: 12, g: 14,
};

evaluateObject('a+b', context));
// 3
evaluateObject('c + b * d', context));
// 22
evaluateObject('e * b + f', context));
// 212
evaluateObject('e * ( b + f )', context));
// 1400
evaluateObject('e * ( b + f ) / g', context));
// 100

/** Other Operations **/
const val: any = { a: null };
evaluateObject('a is not null and length(a) between 4 and 10', val);
// false
const val = { a: '123' };
evaluateObject('a is not null and length(a) between 4 and 10', val);
// false
const val = { a: '1234' };
evaluateObject('a is not null and length(a) between 4 and 10', val);
// true
const val = { a: '1234567890' };
evaluateObject('a is not null and length(a) between 4 and 10', val);
// true
const val = { a: '12345678901' };
evaluateObject('a is not null and length(a) between 4 and 10', val);
// false
const val: any = { a: 1, b: 1 };
evaluateObject('a is not null and b is not null', val);
// true
evaluateObject('a is not null and b is null', val);
// false
const val = { a: 1, b: null };
evaluateObject('a is not null and b is null', val);
// true
const val = { a: 1, b: 1 };
evaluateObject('a=b', val));
// true
evaluateObject('a>b', val));
// false
evaluateObject('a<b', val));
// false
const val = { a: 1, b: 2 };
evaluateObject('a=b', val);
// false
evaluateObject('a>b', val);
// false
evaluateObject('a<b', val);
// true

Sample AST

//Expression: a is not null and length(a) between 4 and 10
{
  "operator": "and",
  "left": {
    "operator": "<>",
    "left": {
      "name": "a",
      "type": "IdentifierExpression"
    },
    "right": {
      "value": null,
      "type": "ValueExpression"
    },
    "type": "BinaryExpression"
  },
  "right": {
    "operator": "and",
    "left": {
      "operator": ">=",
      "left": {
        "name": "length",
        "args": [
          {
            "name": "a",
            "type": "IdentifierExpression"
          }
        ],
        "type": "FunctionCallExpression"
      },
      "right": {
        "value": 4,
        "type": "ValueExpression"
      },
      "type": "BinaryExpression"
    },
    "right": {
      "operator": "<=",
      "left": {
        "name": "length",
        "args": [
          {
            "name": "a",
            "type": "IdentifierExpression"
          }
        ],
        "type": "FunctionCallExpression"
      },
      "right": {
        "value": 10,
        "type": "ValueExpression"
      },
      "type": "BinaryExpression"
    },
    "type": "BinaryExpression"
  },
  "type": "BinaryExpression"
}

Test Coverage

13 specs, 0 failures
Finished in 0.069 seconds
Randomized with seed 62175 (jasmine --random=true --seed=62175)
--------------|---------|----------|---------|---------|-----------------------------------
File          | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------|---------|----------|---------|---------|-----------------------------------
All files     |   93.24 |    83.33 |   92.73 |   93.19 |
 ast.ts       |   89.66 |      100 |      90 |      90 | 16-18
 evaluator.ts |      85 |    69.23 |     100 |   84.21 | 14,18,27,47-49,64
 lexer.ts     |   99.04 |       98 |     100 |   99.03 | 86
 parser.ts    |   89.89 |       70 |   89.47 |   89.41 | 83,91,103,121,133,137,144,181,184
 token.ts     |   97.06 |      100 |      75 |   96.97 | 44
--------------|---------|----------|---------|---------|-----------------------------------
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文