0.0.11 • Published 8 months ago

@tkfnetwork/expression-parser v0.0.11

Weekly downloads
-
License
ISC
Repository
github
Last release
8 months ago

@tkfnetwork/expression-parser

code style: prettier

A small AST expression parser that parses natural AND/OR expressions, handling nested expressions, negative expressions and field expressions.

Installation

npm i @tkfnetwork/expression-parser

Usage

const parser = new ExpressionParser({
  defaultOperator: 'OR',
});

Syntax

Logical Operators

Logical operators are used to combine left and right expressions to create an order. The following logical expressions are accepted:

OperatorAliasDescription
AND&&& If using a space, see default operator configuration below
OR\|\|\| If using a space, see default operator configuration below
AND NOTWill result in the right operation being negative
OR NOTWill result in the right operation being negative

Negation

To negate an expression you can use either of the AND NOT or OR NOT operators, or you can negate either side of the by prefixing the expression with a -. For example:

parser.parse('foo AND NOT bar');
parser.parse('foo OR NOT bar');
parser.parse('foo AND -bar'); // Becomes 'foo AND NOT bar'
parser.parse('-foo AND bar'); // Becomes 'NOT foo AND bar'
parser.parse('-foo AND -bar'); // Becomes 'NOT foo AND NOT bar'
parser.parse('-field:foo AND -field:bar'); // Becomes 'NOT field:foo AND NOT field:bar'

Multiple words

Because spaces are used as identifiers to insert an operator, if you have a value that needs to span multiple words, these can be surrounded in quotes, for example:

parser.parse('"foo bar" AND "boo bar"');

This will allow the value to contain spaces. This can work with fields as well, for example:

parser.parse('field1:"foo bar" AND field2:"boo bar"');

Fields

Fields can be parsed by joining field name to the value, for example:

parser.parse('field1:foo AND field2:bar');

Exact

You can indicate if a parsed values needs an exact match by prefixing with !, for example:

parser.parse('!foo');
parser.parse('foo AND !field1:bar');

This will set a flag in the LiteralExpression to say isExact: true.

Configuration options

defaultOperator: 'AND' | 'OR'

When passing an expression that has implicit operator, e.g. a space, then this operator is used to determine the logical expression.

For example:

const parser = new ExpressionParser({
  defaultOperator: 'OR',
});

parser.parse('foo bar'); // Becomes 'foo OR bar'
const parser = new ExpressionParser({
  defaultOperator: 'AND', // default
});

parser.parse('foo bar'); // Becomes 'foo AND bar'

AST

Parsed expressions are returned as an AST which can be used to traverse the tree and see how the expression was parsed. The returned object is an Expression class which can be one of the following with nested properties:

LiteralExpression

A literal expression holds the literal value and whether it has been negated or not.

For example:

parser.parse('foo');

Would become:

{
    type: 'Literal',
    value: 'foo'
}

Using negation, for example:

parser.parse('-foo');

Would become:

{
    type: 'Literal',
    value: 'foo',
    isNegative: true
}

Using fields, for example:

parser.parse('foo:bar');

Would become:

{
    type: 'Literal',
    value: 'bar',
    field: 'foo'
}

LogicalExpression

The logical expression object holds the left and right values that were parsed as well as the base operator.

For example:

parser.parse('foo AND bar');

Would become:

{
    type: 'Logical',
    left: {
        type: 'Literal',
        value: 'foo'
    },
    operator: 'AND',
    right: {
        type: 'Literal',
        value: 'bar'
    },
}

Using negation operator, for example:

parser.parse('foo AND NOT bar');

Would become:

{
    type: 'Logical',
    left: {
        type: 'Literal',
        value: 'foo'
    },
    operator: 'AND',
    right: {
        type: 'Literal',
        value: 'bar',
        isNegative: true
    },
}
0.0.10

8 months ago

0.0.11

8 months ago

0.0.9

9 months ago

0.0.8

10 months ago

0.0.7

10 months ago

0.0.6

10 months ago

0.0.5

10 months ago

0.0.4

10 months ago

0.0.3

10 months ago

0.0.2

10 months ago

0.0.1

10 months ago