ExpressionBuilder<T> class

A builder that allows the simple definition of expression grammars with prefix, postfix, and left- and right-associative infix operators.

The following code creates the empty expression builder producing values of type num:

final builder = ExpressionBuilder<num>();

Every ExpressionBuilder needs to define at least one primitive type to parse. In this example these are the literal numbers. The mapping function converts the string input into an actual number.

builder.primitive(digit()
    .plus()
    .seq(char('.').seq(digit().plus()).optional())
    .flatten()
    .trim()
    .map(num.parse));

Then we define the operator-groups in descending precedence. The highest precedence have parentheses. The mapping function receives both the opening parenthesis, the value, and the closing parenthesis as arguments:

builder.group().wrapper(
    char('(').trim(), char(')').trim(), (left, value, right) => value);

Then come the normal arithmetic operators. We are using cascade notation to define multiple operators on the same precedence-group. The mapping functions receive both, the terms and the parsed operator in the order they appear in the parsed input:

// Negation is a prefix operator.
builder.group().prefix(char('-').trim(), (operator, value) => -value);

// Power is right-associative.
builder.group().right(char('^').trim(), (left, operator, right) => math.pow(left, right));

// Multiplication and addition are left-associative, multiplication has
// higher priority than addition.
builder.group()
  ..left(char('*').trim(), (left, operator, right) => left * right)
  ..left(char('/').trim(), (left, operator, right) => left / right);
builder.group()
  ..left(char('+').trim(), (left, operator, right) => left + right)
  ..left(char('-').trim(), (left, operator, right) => left - right);

Finally we can build the parser:

final parser = builder.build();

After executing the above code we get an efficient parser that correctly evaluates expressions like:

parser.parse('-8');      // -8
parser.parse('1+2*3');   // 7
parser.parse('1*2+3');   // 5
parser.parse('8/4/2');   // 2
parser.parse('2^2^3');   // 256

Constructors

ExpressionBuilder()

Properties

hashCode int
The hash code for this object.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

build() Parser<T>
Builds the expression parser.
group() ExpressionGroup<T>
Creates a new group of operators that share the same priority.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
primitive(Parser<T> parser) → void
Defines a new primitive, literal, or value parser.
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited