Table of Contents

Architecture

The entire process of evaluating an expression can be demonstrated at this flowchart:

flowchart TB

A["1+1"] -->|Parsing| B("new BinaryExpression(new ValueExpression(1), new ValueExpression(1), BinaryExpressionType.Plus)")
B --> |Evaluation|2

Parsing

Parsing is the process of analyzing the input expression and converting it into a structured format that can be easily evaluated. We use Parlot to handle parsing, but you can use any parser you want if you implement the interface ILogicalExpressionFactory. For our example, "1+1", the parsing step converts the string into an abstract syntax tree (AST). This tree is made up of different types of expressions, such as binary expressions, value expressions our even functions. Our AST is represented by LogicalExpression class.

Evaluation

Evaluation refers to the process of determining the value of an expression. We use the visitor pattern at evaluation. This pattern allows you to add new operations to existing object structures without modifying those structures. With the method Accept<T>(ILogicalExpressionVisitor<T>) is possible to accept any kind of visitor that implements ILogicalExpressionVisitor<T>. Example implementations include EvaluationVisitor that returns a object and SerializationVisitor that converts the AST into a string.

If you are creating your custom implementation, beware it should be stateless to be easier to debug and read. This is enforced by the PureAttribute and generic return at the Accept<T>(ILogicalExpressionVisitor<T>) method.

Expression Class

This is the main class of NCalc. It abstracts the process of parsing and evaluating the string. The method Evaluate() returns the actual value of its string representation.

Example:

  var expression = new Expression("2 * 3");
  var result = expression.Evaluate();
  
  Console.WriteLine(result);

This example above first creates an instance of Expression using a valued constructor. This constructor takes a string as parameter. Then the method Evaluate() is called to parse the string and returns the actual value represented by the string.

To create expressions you can combine several Operators and Values.

Learn More

For additional information on the technique we used to create this library please read this article.