parser top-level property

Parser<Expression> parser
final

A mathematical expression parser supporting arithmetic, functions, and variables.

Evaluates expressions using standard operator precedence: parentheses, function calls, exponentiation (^), multiplication/division (*, /), and addition/subtraction (+, -).

Returns an Expression AST node that can be evaluated against a variable map.

For example:

final result = parser.parse('3 * (x + 2) ^ 2');
final expression = result.value;
print(expression.eval({'x': 4})); // 108.0

Implementation

final parser = () {
  final builder = ExpressionBuilder<Expression>();
  builder
    // Numbers
    ..primitive(
      seq3(
        digit().plus(),
        seq2(char('.'), digit().plus()).optional(),
        seq3(pattern('eE'), anyOf('+-').optional(), digit().plus()).optional(),
      ).flatten(message: 'number expected').trim().map(_createValue),
    )
    // Constant, variables, and functions
    ..primitive(
      seq2(
        seq2(
          letter(),
          word().starString(),
        ).flatten(message: 'name expected').trim(),
        builder.loopback
            .starSeparated(char(',').trim())
            .map((list) => list.elements)
            .skip(before: char('(').trim(), after: char(')').trim())
            .optionalWith(const <Expression>[]),
      ).map2((name, args) => _createBinding(name, args)),
    );
  // Parentheses (highest precedence wrapper)
  builder.group().wrapper(
    char('(').trim(),
    char(')').trim(),
    (left, value, right) => value,
  );
  // Unary prefix operators (+, -)
  builder.group()
    ..prefix(char('+').trim(), (op, a) => a)
    ..prefix(char('-').trim(), (op, a) => Application('-', [a], (x) => -x));
  // Exponentiation (right-associative)
  builder.group().right(
    char('^').trim(),
    (a, op, b) => Application('^', [a, b], math.pow),
  );
  // Multiplicative operators (*, /, left-associative)
  builder.group()
    ..left(
      char('*').trim(),
      (a, op, b) => Application('*', [a, b], (x, y) => x * y),
    )
    ..left(
      char('/').trim(),
      (a, op, b) => Application('/', [a, b], (x, y) => x / y),
    );
  // Additive operators (+, -, left-associative)
  builder.group()
    ..left(
      char('+').trim(),
      (a, op, b) => Application('+', [a, b], (x, y) => x + y),
    )
    ..left(
      char('-').trim(),
      (a, op, b) => Application('-', [a, b], (x, y) => x - y),
    );
  return resolve(builder.build()).end();
}();