It is a challenge to evaluate expressions given at runtime with compiled languages. Some interpreted languages like Python, PHP, JavaScript has an eval() function that can be used for similar purposes.
You can think of bcParser.NET as a safe eval() function to evaluate math formulas. bcParser.NET is a Math Parser Library for the .NET Platform. bcParser.NET parses and evaluates mathematical expressions given as strings at runtime.
C# language, with it’s expressive syntax and capable libraries and data structures makes it possible to implement a re-usable solution for the expression parsing problem. bcParser.NET – .NET Math Parser – simplifies the task for us by implementing the parse and evaluate algorithm. bcParser.NET saves you valuable time so that you can focus on other aspects of your application and not spend time re-inventing the wheel by re-using bcParser.NET.
bcParser.NET Math parser is implemented in C#. It allows the programmer set the expression as a string, create user defined variables, set their values, create user defined functions and get expression value with one function call. The expression can contain arithmetic operators, logical operators, variables, functions, numeric and string literals.
bcParser.NET can be used with Visual Studio on Windows and it can be also be compiled for Xamarin on Windows and MacOS with minimal changes.
A simple example looks like this:
MathParser parser = new MathParser(); parser.SetExpression("x+sin(y)"); parser.SetX(3); // X and Y are pre-defined (but can be undefined if you like). parser.SetY(2); double value = parser.GetValueAsDouble();
Working with variables:
//create a variable and set initial value: parser.CreateVar("J", 1, null); //above null is for valueProvider for the variables. Will be discussed later. //you can assign value of x or y like this: parser.X = 5; //another way is this: parser.SetVariable("Y", 3);
The programmer can implement his own functions in any .NET language and hook them up to the Math Parser object so that they can be used in expressions all with few lines of code.
The Math Parser reports errors via ParserException. This exception object carries out syntax errors that indicate invalid portion of the mathematical expression.
User Defined Functions in Math Parser
bcParser.NET allows defining your own functions and variables. If a function definition declares the number of variables it requires, this will be enforced during parse time.
Here is how to register your own functions:
MathParser parser = new MathParser(); //example of creating a one double precision parameter user defined function: parser.CreateOneParamFunc("SQUARE", new OneParamFunc(Square)); //user defined function that takes two double precision parameters: parser.CreateTwoParamFunc("POWER", new TwoParamFunc(Power)); //user defined function that takes any number of parameters: parser.CreateFunc("MULTN", new MyMultiplyN()); parser.Expression = "SQUARE(2)+POWER(3,2)+MULTN(3,4,5)"; double val = parser.ValueAsDouble;
In above code, OneParamFunc and TwoParamFunc are delegates for your convenience. A function can also be defined by implementing IFunction interface. We will see it shortly when we display “MULTN” implementation. First let’s take a look at how the “Square” function looks like:
static public double Square(IParameter x) { double val = x.GetValueAsDouble(); return val * val; }
In above code snippet, a detail to note is that the parameters of your functions are being passed as IParameter, and not an actual value. The value is computed only when you call for example:
double val = x.GetValueAsDouble();
This design allows you to skip computing some parameters if your program logic allows, or requires it. For example in this expression:
IF(x > 0, y/x, sin(y))
if x is greater than 0, then sin(y) will not be evaluated at all. Only y/x will be evaluated. This will translate into speed gains and in some cases this capability helps avoid division by zero errors and other impossible situations.
Now let’s take a look at power function:
static public double Power(IParameter x, IParameter y) { return Math.Pow(x.GetValueAsDouble(), y.GetValueAsDouble()); }
This time we have two parameters being passed in as the delegate name implies, it is a TwoParamFunc.
Now let’s take a look at how MULTN function was implemented to make it possible to allow any number of parameters:
/// /// Example of user defined function that that takes unknown number of parameters. /// Requires 1 or more parameters at runtime and multiplies them all. /// class MyMultiplyN : IFunction { //Multiple parameters are passed as an array of IParameter public IConvertible Run(IParameter[] p) { if(p.Length < 1) { throw new Exception("MyMultiplyN requires at least 1 parameter."); } double total = 1.0; foreach (IParameter param in p) { total*= param.GetValueAsDouble(); } return total; } public int GetNumberOfParams() { // -1 means any number of params. // 2, or 3 would mean exactly that many should be expected during parse. return -1; } }
The Run() function is called during evaluation time, GetNumberOfParams function is called during parse time. That is pretty much all there is to it for user defined functions in bcParser.NET Math Parser.
VariableResolver / VariableDelegate
Sometimes variables that can be used in an expression are not known until the user types the expression. Earlier we gave examples of setting variable values before evaluating the expression. When this is not possible, you have the option to register a delegate VariableDelegate that will return values for unknown variables that the parser has encountered.
Here is an example of working with VariableResolver:
MathParser parser = new MathParser(); //Set the VariableResolver delegate: parser.VariableResolver = new VariableDelegate(GetVarValue); parser.Expression = "3+K"; Console.WriteLine(parser.Expression+" = " + parser.Value);
In above code snippet, imagine that K was not known at the time you wrote the program. How would that happen? For example some users have database column names as variables and you the programmer do not know the database columns, only the end user knows. But at runtime you are able to compute a value for it and proceed with it. To make it happen, you would write a GetVarValue function. To make it a simple example, let’s have a simple GetVarValue here:
public static IConvertible GetVarValue(MathParser p, String varName) { Console.WriteLine("Variable Resolver Called for: "+varName); if(varName=="K") { //Run some logic (for example db lookup) and return appropriate value. //Cache return value if necessary for performance. return 5; } throw new Exception("Invalid variable name: <"+varName+">"); }
Above case is overly simplified example of a VariableDelegate, but you can imagine there could be sophisticated logic that finds and returns the variable value on demand instead of having to SetVariable() for every possible variable before evaluation.
Here is an example of using culture specific decimal separators:
MathParser oParser = new MathParser(); oParser.CultureSpecificDecimals = true; oParser.CultureInfo = CultureInfo.GetCultureInfo("de-DE"); // Notice that if decimal separator is comma, // then we use colon : between function parameters oParser.Expression = "3,2+MIN(3,2:-3,2)+Y/X"; oParser.X = 1; oParser.Y = 2; double val = oParser.ValueAsDouble;
Visual Studio Support
bcParser.NET was tested with Visual Studio 2003, 2005 and 2008, 2010, 2013, 2015, 2019, 2022. bcParser.NET can be used with 32 and 64 bit Windows as well as with DotNet Distributions for Mac OS and Linux. .NET Core is supported.
C# Math Parser Documentation
The documentation of bcParser.NET is generated from the C# source code. You can view it online: Math Parser C# Documentation. Documentation is also included in the evaluation version and the paid version of the downloads.
bcParser.NET Math Parser Evaluation Download
bcParser.NET trial download comes as a zip file which contains a trial bcParser.NET.dll, C# and VB examples, and documentation. The trial version will expire after a short period, please do not ship the trial version with your products. If the evaluation expires too soon, please let us know and we will send you a new one. You can download bcParser.NET evaluation version here.
Tackling all of the challenges of implementing a parser is almost impossible within the scope of a broader project where there are pressing requirements in terms of time and functionality to be delivered. Most of us need to focus on the actual business problem at hand and view the mathematical expression parsing aspect of the problem as a side issue. Thus, it becomes very very hard to deliver correct, united tested, proven code on time and in budget. Trying to code a expression parser could take an experienced developer a month to write and to test. When such as road block appears, the best way is to find a good component that can easily be integrated into your development project, leaving you free time to focus on other aspects of your project or to simply go home and rest. There is peace of mind in using a component that many others have used for many years and flushed out the bugs for you.
bcParser.NET math parser is a well tested, broadly used, simple .NET Class that can save time and money for experienced or novice programmers alike. It comes with C# source code so you are never stuck with a black box.
Purchasing bcParser.NET Math Parser Library
You can pay with credit card and download bcParser.NET immediately from our online store for only $29.95. The download includes C# source code. Upgrades are free for registered users. Licensing is per developer. Site license option is available in the online store page. You can deploy the the component royalty free with your applications as many times as you want. Site license allows any number of developers use the component at your development site. Site License is $290.95. Site licenses can be purchased here.