Related
I need to locate a fast, lightweight expression parser.
Ideally I want to pass it a list of name/value pairs (e.g. variables) and a string containing the expression to evaluate. All I need back from it is a true/false value.
The types of expressions should be along the lines of:
varA == "xyz" and varB==123
Basically, just a simple logic engine whose expression is provided at runtime.
UPDATE
At minimum it needs to support ==, !=, >, >=, <, <=
Regarding speed, I expect roughly 5 expressions to be executed per request. We'll see somewhere in the vicinity of 100/requests a second. Our current pages tend to execute in under 50ms. Usually there will only be 2 or 3 variables involved in any expression. However, I'll need to load approximately 30 into the parser prior to execution.
UPDATE 2012/11/5
Update about performance. We implemented nCalc nearly 2 years ago. Since then we've expanded it's use such that we average 40+ expressions covering 300+ variables on post backs. There are now thousands of post backs occurring per second with absolutely zero performance degradation.
We've also extended it to include a handful of additional functions, again with no performance loss. In short, nCalc met all of our needs and exceeded our expectations.
Have you seen https://ncalc.codeplex.com/ and https://github.com/sheetsync/NCalc ?
It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:
Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi");
e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());
It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.
It also supports logical operators, date/time's strings and if statements.
How about the Fast Lightweight Expression Evaluator? It lets you set variables and supports logical operators.
If you need something beefier and have the time, you could also design your own expression language with Irony.
Hisystems' Interpreter supports custom functions, operators and literals, is lightweight pure c# portable code. Currently runs on iOS via MonoTouch and should run on any other Mono environment as well as windows. Free for commercial use. Available on GitHub at https://github.com/hisystems/Interpreter.
I fully appreciate how late this answer is however I would like to throw in my solution because I believe it can add more above the accepted answer of using NCalc should someone wish to use the expressions across multiple platforms.
-- Update --
I have created a parser for C# with plans to also implement it for Java and Swift over the next few months. This would mean that you can evaluate the expressions on multi-platforms without the need for tweaking per platform.
While Java and Swift was planned it never made it in to a fully fledge release. Instead there is now support for .NET Standard enabling support for Xamarin apps.
-- End update --
Expressive is the tool and it is available at:
GitHub or Nuget.
The site has a fair amount of documentation on it but to prevent link rot here is an example on how to use it:
Variable support
var expression = new Expression("1 * [variable]");
var result = expression.Evaluate(new Dictionary<string, object> { ["variable"] = 2);
Functions
var expression = new Expression("sum(1,2,3,4)");
var result = expression.Evaluate();
It was designed to match NCalc as best as possible however it has added support for things like a 'null' keyword.
self promotion here
i wrote aa generic parser generator for c# https://github.com/b3b00/csly
you can find an expression parseras example on my github. you may need to customize it to fit your needs
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
How do I go about writing a Parser (Recursive Descent?) in C#? For now I just want a simple parser that parses arithmetic expressions (and reads variables?). Though later I intend to write an xml and html parser (for learning purposes). I am doing this because of the wide range of stuff in which parsers are useful: Web development, Programming Language Interpreters, Inhouse Tools, Gaming Engines, Map and Tile Editors, etc. So what is the basic theory of writing parsers and how do I implement one in C#? Is C# the right language for parsers (I once wrote a simple arithmetic parser in C++ and it was efficient. Will JIT compilation prove equally good?). Any helpful resources and articles. And best of all, code examples (or links to code examples).
Note: Out of curiosity, has anyone answering this question ever implemented a parser in C#?
I have implemented several parsers in C# - hand-written and tool generated.
A very good introductory tutorial on parsing in general is Let's Build a Compiler - it demonstrates how to build a recursive descent parser; and the concepts are easily translated from his language (I think it was Pascal) to C# for any competent developer. This will teach you how a recursive descent parser works, but it is completely impractical to write a full programming language parser by hand.
You should look into some tools to generate the code for you - if you are determined to write a classical recursive descent parser (TinyPG, Coco/R, Irony). Keep in mind that there are other ways to write parsers now, that usually perform better - and have easier definitions (e.g. TDOP parsing or Monadic Parsing).
On the topic of whether C# is up for the task - C# has some of the best text libraries out there. A lot of the parsers today (in other languages) have an obscene amount of code to deal with Unicode etc. I won't comment too much on JITted code because it can get quite religious - however you should be just fine. IronJS is a good example of a parser/runtime on the CLR (even though its written in F#) and its performance is just shy of Google V8.
Side Note: Markup parsers are completely different beasts when compared to language parsers - they are, in the majority of the cases, written by hand - and at the scanner/parser level very simple; they are not usually recursive descent - and especially in the case of XML it is better if you don't write a recursive descent parser (to avoid stack overflows, and because a 'flat' parser can be used in SAX/push mode).
Sprache is a powerful yet lightweight framework for writing parsers in .NET. There is also a Sprache NuGet package. To give you an idea of the framework here is one of the samples that can parse a simple arithmetic expression into an .NET expression tree. Pretty amazing I would say.
using System;
using System.Linq.Expressions;
using Sprache;
namespace LinqyCalculator
{
static class ExpressionParser
{
public static Expression<Func<decimal>> ParseExpression(string text)
{
return Lambda.Parse(text);
}
static Parser<ExpressionType> Operator(string op, ExpressionType opType)
{
return Parse.String(op).Token().Return(opType);
}
static readonly Parser<ExpressionType> Add = Operator("+", ExpressionType.AddChecked);
static readonly Parser<ExpressionType> Subtract = Operator("-", ExpressionType.SubtractChecked);
static readonly Parser<ExpressionType> Multiply = Operator("*", ExpressionType.MultiplyChecked);
static readonly Parser<ExpressionType> Divide = Operator("/", ExpressionType.Divide);
static readonly Parser<Expression> Constant =
(from d in Parse.Decimal.Token()
select (Expression)Expression.Constant(decimal.Parse(d))).Named("number");
static readonly Parser<Expression> Factor =
((from lparen in Parse.Char('(')
from expr in Parse.Ref(() => Expr)
from rparen in Parse.Char(')')
select expr).Named("expression")
.XOr(Constant)).Token();
static readonly Parser<Expression> Term = Parse.ChainOperator(Multiply.Or(Divide), Factor, Expression.MakeBinary);
static readonly Parser<Expression> Expr = Parse.ChainOperator(Add.Or(Subtract), Term, Expression.MakeBinary);
static readonly Parser<Expression<Func<decimal>>> Lambda =
Expr.End().Select(body => Expression.Lambda<Func<decimal>>(body));
}
}
C# is almost a decent functional language, so it is not such a big deal to implement something like Parsec in it. Here is one of the examples of how to do it: http://jparsec.codehaus.org/NParsec+Tutorial
It is also possible to implement a combinator-based Packrat, in a very similar way, but this time keeping a global parsing state somewhere instead of doing a pure functional stuff. In my (very basic and ad hoc) implementation it was reasonably fast, but of course a code generator like this must perform better.
I know that I am a little late, but I just published a parser/grammar/AST generator library named Ve Parser. you can find it at http://veparser.codeplex.com or add to your project by typing 'Install-Package veparser' in Package Manager Console. This library is kind of Recursive Descent Parser that is intended to be easy to use and flexible. As its source is available to you, you can learn from its source codes. I hope it helps.
In my opinion, there is a better way to implement parsers than the traditional methods that results in simpler and easier to understand code, and especially makes it easier to extend whatever language you are parsing by just plugging in a new class in a very object-oriented way. One article of a larger series that I wrote focuses on this parsing method, and full source code is included for a C# 2.0 parser:
http://www.codeproject.com/Articles/492466/Object-Oriented-Parsing-Breaking-With-Tradition-Pa
Well... where to start with this one....
First off, writing a parser, well that's a very broad statement especially with the question your asking.
Your opening statement was that you wanted a simple arithmatic "parser" , well technically that's not a parser, it's a lexical analyzer, similar to what you may use for creating a new language. ( http://en.wikipedia.org/wiki/Lexical_analysis ) I understand however exactly where the confusion of them being the same thing may come from. It's important to note, that Lexical analysis is ALSO what you'll want to understand if your going to write language/script parsers too, this is strictly not parsing because you are interpreting the instructions as opposed to making use of them.
Back to the parsing question....
This is what you'll be doing if your taking a rigidly defined file structure to extract information from it.
In general you really don't have to write a parser for XML / HTML, beacuse there are already a ton of them around, and more so if your parsing XML produced by the .NET run time, then you don't even need to parse, you just need to "serialise" and "de-serialise".
In the interests of learning however, parsing XML (Or anything similar like html) is very straight forward in most cases.
if we start with the following XML:
<movies>
<movie id="1">
<name>Tron</name>
</movie>
<movie id="2">
<name>Tron Legacy</name>
</movie>
<movies>
we can load the data into an XElement as follows:
XElement myXML = XElement.Load("mymovies.xml");
you can then get at the 'movies' root element using 'myXML.Root'
MOre interesting however, you can use Linq easily to get the nested tags:
var myElements = from p in myXML.Root.Elements("movie")
select p;
Will give you a var of XElements each containing one '...' which you can get at using somthing like:
foreach(var v in myElements)
{
Console.WriteLine(string.Format("ID {0} = {1}",(int)v.Attributes["id"],(string)v.Element("movie"));
}
For anything else other than XML like data structures, then I'm afraid your going to have to start learning the art of regular expressions, a tool like "Regular Expression Coach" will help you imensly ( http://weitz.de/regex-coach/ ) or one of the more uptodate similar tools.
You'll also need to become familiar with the .NET regular expression objects, ( http://www.codeproject.com/KB/dotnet/regextutorial.aspx ) should give you a good head start.
Once you know how your reg-ex stuff works then in most cases it's a simple case case of reading in the files one line at a time and making sense of them using which ever method you feel comfortable with.
A good free source of file formats for almost anything you can imagine can be found at ( http://www.wotsit.org/ )
For the record I implemented parser generator in C# just because I couldn't find any working properly or similar to YACC (see: http://sourceforge.net/projects/naivelangtools/).
However after some experience with ANTLR I decided to go with LALR instead of LL. I know that theoretically LL is easier to implement (generator or parser) but I simply cannot live with stack of expressions just to express priorities of operators (like * goes before + in "2+5*3"). In LL you say that mult_expr is embedded inside add_expr which does not seem natural for me.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
I need a fast runtime expression parser
How do I make it that when someone types in x*y^z in a textbox on my page to calculate that equation in the code behind and get the result?
.NET does not have a built-in function for evaluating arbitrary strings. However, an open source .NET library named NCalc does.
NCalc is a mathematical expressions evaluator in .NET. NCalc can parse
any expression and evaluate the result, including static or dynamic
parameters and custom functions.
Answer from operators as strings by user https://stackoverflow.com/users/1670022/matt-crouch, using built-in .NET functionality:
"If all you need is simple arithmetic, do this.
DataTable temp = new DataTable();
Console.WriteLine(temp.Compute("15 / 3",string.Empty));
EDIT: a little more information. Check out the MSDN documentation for the Expression property of the System.Data.DataColumn class. The stuff on "Expression Syntax" outlines a list of commands you can use in addition to the arithmetic operators. (ex. IIF, LEN, etc.)."
EDIT 2: For convenience, you can put this into a little function like:
public string Eval(string expr)
{
var temp = new System.Data.DataTable();
string result = null;
try
{
result = $"{temp.Compute(expr, string.Empty)}";
}
catch (System.Data.EvaluateException ex)
{
if (ex.Message.ToLower().Contains("cannot find column"))
throw new System.Data.SyntaxErrorException($"Syntax error: Invalid expression: '{expr}'."
+ " Variables as operands are not supported.");
else
throw;
}
return result;
}
So you can use it like:
Console.WriteLine(Eval("15 * (3 + 5) / (7 - 2)"));
giving the expected output:
24
Note that the error handler helps to handle exceptions caused by using variables which are not allowed here. Example: Eval("a") - Instead of returning "Cannot find column [a]", which doesn't make much sense in this context (we're not using it in a database context) it is returning "Syntax error: Invalid expression: 'a'. Variables as operands are not supported."
Run it on DotNetFiddle
There are two main approaches to this problem, each with some variations, as illustrated in the variety of answers.
Option A: Find an existing mathematical expresssion evaluator
Option B: Write your own parser and the logic to compute the result
Before going into some details about this, it is appropriate to stress that interpreting arbitrary mathematical expressions is not a trivial task, for any expression grammar other than "toy" grammars such as these that only accept one or two arithmetic operations and do not allow parenthesis etc.
Understanding that such task is deceivingly trivial, and acknowledging that, after all, interpreting arithmetic expressions of average complexity is a relatively recurrent need for various applications [hence one for which mature solutions should be available], it is probably wise to try and make do with "Option A".
I'd therefore second Jed's recommendation of a ready-make expression evaluator such as NCalc.
It may be useful however to take the time and understand the various concepts and methods associated with parsing and interpreting arithmetic expressions, as if one were going to whip-up one's own implementation.
The key concept is that of a formal grammar. The arithmetic expressions which the evaluator will accept must follow a set of rules such as the list of arithmetic operations allowed. For example will the evaluator support, say, trigonometric functions, or if it does, will this also include say atan2(). The rules also indicate what consitutes an operand, for example will it be allowed to input numerical values as big as say 45 digits. etc. The point is that all these rules are formalized in a grammar.
Typically a grammar works on tokens which have previously been extracted from the raw input text. Essentially at some time in the process, some logic needs to analyze the input string, character by character, and determine which sequences of characters go together. For example in the 123 + 45 / 9.3 expression, the tokens are the integer value 123, the plus operator, the integer value 45, the division operator and finally the 9.3 real value. The task of identifying the tokens and associating them with a token type is the job a lexer. Lexers can be build themselves on a grammar (a grammar which "tokens" are single characters, as opposed to the grammar for the arithmetic expression parser which tokens are short strings produced by the lexer.)
BTW, grammars are used to define many other things beyond arithmetic expressions. Computer languages follow [rather sophiticated] grammars, but it is relatively common to introduce Domain Specific Languages aka DSLs in support of various features of computer applications.
For very simple grammars, one may be able to write the corresponding lexer and parser from scratch. But sooner than later the grammars may get complicated to the point that hand-writing these modules becomes fastidious, bug-prone and maybe more importantly difficult to read. Hence the existence of Lexer and Parser Generators which are stand-alone programs that produce the code of lexers and parsers (in a particular programming language such as C, Java or C#) from a list of rules (expressed in a syntax particular to the generator, though many generators tend to use similar syntaxes, loosely base on BNF).
When using such a lexer/parser generator, work in done in multiple steps:
- first one writes a definition of the grammar (in the generator-specific language/syntax)
- one runs this grammar through the generator.
- one often repeats the above two steps multiple times, because writing a grammar is an exacting exercise: the generator will complain of many possible ambiguities one may write into the grammar.
- eventually the generator produces a source file (in the desired target language such as C# etc.)
- this source is included in the overall project
- other source files in the project may invoke the functions exposed in the source files produced by the generator and/or some logic corresponding to various patterns identified during parsing may readily be may imbedded in the generator produced code.
- the project can then be build as usual, i.e. as if the parser and lexer had be hand-written.
And that's about it for a 20,000 feet high presentation of the process of working with formal grammars and code generators.
A list of parser-generators (aka compiler-compilers) can be found at this link. For simple work in C# I also want to mention Irony. It may be very insightful to peruse these sites, to get a better feel for these concept, even without the intent of becoming a practitioner at this time.
As said, I wish to stress that for this particular application, a ready-made arithmetic evaluator is likely the better approach. The main downside of these would be
some limitations as to what the allowed expression syntax is (either the grammar allowed is too restrictive: you also need say stddev() or is too broad: you don't want your users to use trig functions. With the more mature evaluators, there will be some form of configuration/extension feature which allows dealing with this problem.
the learning curve of such a 3rd party module. Hopefully many of them should be relatively "plug-and-play".
solved with this library http://www.codeproject.com/Articles/21137/Inside-the-Mathematical-Expressions-Evaluator
my final code
Calculator Cal = new Calculator();
txt_LambdaNoot.Text = (Cal.Evaluate(txt_C.Text) / fo).ToString();
now when some one type 3*10^11 he will get 300000000000
You will need to implement (or find a third-party source) an expression parser. This is not a trivial thing to do.
What you need - if you want to do it yourself - is a Scanner (also known as Lexer) + Parser in the code behind which interprets the expression. Alternatively, you can find a 3rd party library which does the job and works similar as the JavaScript eval(string) function does.
Please take a look here, it describes an recursive descent parser. The example is written in C, but you should be able to adapt it to C# easily once you got the idea described in the article.
It is less complicated than it sounds, especially if you have a limited amount of operators to support.
The advantage is that you keep full control on what expressions will be executed (to prevent malicious code injections by the end-user of your website).
I need to enable user that he can write own formula in datagridview. Something like a function in Excel.
Example of formula definition:
So, user write his own formula in formula cell and then in other table is shown result for each. How I can do this?
I would try NCalc
NCalc is a mathematical expressions evaluator in .NET. NCalc can parse any expression and evaluate the result, including static or dynamic parameters and custom functions.
Dictionary<string, int> dict = new Dictionary<string, int>() { { "Income", 1000 }, { "Tax", 5 } };
string expressionString = "Income * Tax";
NCalc.Expression expr = new NCalc.Expression(expressionString);
expr.EvaluateParameter += (name, args) =>
{
args.Result = dict[name];
};
int result = (int)expr.Evaluate();
Your formula could be manipulated to C# and dynamically compiled using SystemCodeCom.Compiler and you could run it on the fly feeding in your variable values.
Otherwise you are going to have to impliment some kind of mini parser/compiler - which is a rather particular skill and which could quickly get complicated - especially if your formulas become more complicated (which maybe likely).
There is are codeproject articles on dynamic complilation here and here. But there are plenty of other examples around on the web.
There are a number of ways you can do that, they all revolve around translating the formula into executable code.
Do you want to write your own parser or do you wnat to use an existing one. C# itself, IronPython, IronRuby, some off the shelf component. If you use a full parser you might want to look at how to restrict what the user can do with it, inadvertantly or otherwise...
If they are as simple as they look, some sort of expression builder, (pick two named values and an operator) might be the way to go, but modularise, both building the expression and evaluating it so you can beef up at some later point.
However given how simple they appear to be, I'd be tempted to predefine expressions (loaded as meta data from some sort of backing store, and make it select one of these as opposed to user entering it. You could easily spend months at this aspect of the design, is it worth it?
I had a similar requirement (dynamic parsing of expressions) recently in a project I am working on and ended up using VB expressions from WF (Windows Workflow Foundation). It certainly depends on how important this functionality is for you and how much effort are you willing to put into it. In my case it turned out better than NCalc for several reasons:
it supports more complex expressions than NCalc
the resulting expression trees can be analyzed to determine dependencies for individual expressions
it's the same language for expressions as in WF (which I already use elsewhere in the project)
Anyway, here is a short blogpost I've written on the subject.
I created the albatross expression parser a few years back. It has been open sourced for a while but I finally get around and published v2.02 and added documentation recently. It is being actively maintained. It has a couple nice features:
Circular reference detection
Source variable from external object directly
Reversed generation of expressions
Properly documented
Note: Mathematical expression evaluation is not the focus of this question. I want to compile and execute new code at runtime in .NET. That being said...
I would like to allow the user to enter any equation, like the following, into a text box:
x = x / 2 * 0.07914
x = x^2 / 5
And have that equation applied to incoming data points. The incoming data points are represented by x and each data point is processed by the user-specified equation. I did this years ago, but I didn't like the solution because it required parsing the text of the equation for every calculation:
float ApplyEquation (string equation, float dataPoint)
{
// parse the equation string and figure out how to do the math
// lots of messy code here...
}
When you're processing boatloads of data points, this introduces quite a bit of overhead. I would like to be able to translate the equation into a function, on the fly, so that it only has to be parsed once. It would look something like this:
FunctionPointer foo = ConvertEquationToCode(equation);
....
x = foo(x); // I could then apply the equation to my incoming data like this
Function ConvertEquationToCode would parse the equation and return a pointer to a function that applies the appropriate math.
The app would basically be writing new code at run time. Is this possible with .NET?
Yes! Using methods found in the Microsoft.CSharp, System.CodeDom.Compiler, and System.Reflection name spaces. Here is a simple console app that compiles a class ("SomeClass") with one method ("Add42") and then allows you to invoke that method. This is a bare-bones example that I formatted down to prevent scroll bars from appearing in the code display. It is just to demonstrate compiling and using new code at run time.
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Reflection;
namespace RuntimeCompilationTest {
class Program
{
static void Main(string[] args) {
string sourceCode = #"
public class SomeClass {
public int Add42 (int parameter) {
return parameter += 42;
}
}";
var compParms = new CompilerParameters{
GenerateExecutable = false,
GenerateInMemory = true
};
var csProvider = new CSharpCodeProvider();
CompilerResults compilerResults =
csProvider.CompileAssemblyFromSource(compParms, sourceCode);
object typeInstance =
compilerResults.CompiledAssembly.CreateInstance("SomeClass");
MethodInfo mi = typeInstance.GetType().GetMethod("Add42");
int methodOutput =
(int)mi.Invoke(typeInstance, new object[] { 1 });
Console.WriteLine(methodOutput);
Console.ReadLine();
}
}
}
You might try this: Calculator.Net
It will evaluate a math expression.
From the posting it will support the following:
MathEvaluator eval = new MathEvaluator();
//basic math
double result = eval.Evaluate("(2 + 1) * (1 + 2)");
//calling a function
result = eval.Evaluate("sqrt(4)");
//evaluate trigonometric
result = eval.Evaluate("cos(pi * 45 / 180.0)");
//convert inches to feet
result = eval.Evaluate("12 [in->ft]");
//use variable
result = eval.Evaluate("answer * 10");
//add variable
eval.Variables.Add("x", 10);
result = eval.Evaluate("x * 10");
Download Page
And is distributed under the BSD license.
Yes, definitely possible to have the user type C# into a text box, then compile that code and run it from within your app. We do that at my work to allow for custom business logic.
Here is an article (I haven't more than skimmed it) which should get you started:
http://www.c-sharpcorner.com/UploadFile/ChrisBlake/RunTimeCompiler12052005045037AM/RunTimeCompiler.aspx
You can also create a System.Xml.XPath.XPathNavigator from an empty, "dummy" XML stream,
and evaluate expressions using the XPath evaluator:
static object Evaluate ( string xp )
{
return _nav.Evaluate ( xp );
}
static readonly System.Xml.XPath.XPathNavigator _nav
= new System.Xml.XPath.XPathDocument (
new StringReader ( "<r/>" ) ).CreateNavigator ( );
If you want to register variables to use within this expression,
you can dynamically build XML that you can pass in the Evaluate overload
that takes a XPathNodeIterator.
<context>
<x>2.151</x>
<y>231.2</y>
</context>
You can then write expressions like "x / 2 * 0.07914" and then x
is the value of the node in your XML context.
Another good thing is, you will have access to all XPath core functions,
which includes mathematics and string manipulation methods, and more stuff.
If you want to take it further, you can even build your own XsltCustomContext(or ill post here on demand)
where you can resolve references to extension functions and variables:
object result = Evaluate ( "my:func(234) * $myvar" );
my:func is mapped to a C#/.NET method which takes a double or int as parameter.
myvar is registered as a variable within the XSLT context.
You can try looking at either CodeDom or Lambda Expression Trees. I think either one of those should allow you to accomplish this. Expression trees are probably the better way to go but also have a higher learning curve.
I've done this using CSharpCodeProvider by creating the boiler plate class and function stuff as a const string inside my generator class. Then I insert the user code into the boiler plate and compile.
It was fairly straightforward to do, but the danger to this approach is that the user entering the equation could enter just about anything which could be a security issue depending on your application.
If security is at all a concern, I would recommend using Lambda Expression Trees, but if not, using CSharpCodeProvider is a fairly robust option.
Have you seen http://ncalc.codeplex.com ?
It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:
Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi");
e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());
It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.
You could start here and if you really want to get into it, Boo can be modified to meet your needs. You could also integrate LUA with .NET. Any three of these could be utilized within the body of a delegate for your ConvertEquationToCode.
Try Vici.Parser: download it here (free) , it's the most flexible expression parser/evaluator I've found so far.
Here a more modern library for simple expressions: System.Linq.Dynamic.Core.
It's compatible with .NET Standard/.NET Core, it's available through NuGet, and the source is available.
https://system-linq-dynamic-core.azurewebsites.net/html/de47654c-7ae4-9302-3061-ea6307706cb8.htm
https://github.com/StefH/System.Linq.Dynamic.Core
https://www.nuget.org/packages/System.Linq.Dynamic.Core/
This is a very lightweight and dynamic library.
I wrote a simple wrapper class for this library that let's me do things like this:
string sExpression = "(a == 0) ? 5 : 10";
ExpressionEvaluator<int> exec = new ExpressionEvaluator<int>(sExpression);
exec.AddParameter("a", 0);
int n0 = exec.Invoke();
Once the expression is compiled, you can simply update the parameter values and re-invoke the expression.
If all else fails, there are classes under the System.Reflection.Emit namespace which you can use to produce new assemblies, classes, and methods.
You could implement a postfix stack calculator. Basically what you have to do is convert the expression to postfix notation, and then simply iterate over the tokens in your postfix to calculate.
I would do a recursive function that doesn't write code but instead applies basic operators to portions of a string based on special characters found in that string.
If more than one special character is found, it breaks up the string and calls itself on those two portions.
you can use system.CodeDom to generate code and compile it on the fly
have a look here
I don't know if it's possible to implement your ConvertEquationToCode function, however, you can generate a data structure that represents the calculation you need to perform.
For example, you could build a tree whose leaf nodes represent the input for your calculation, whose non-leaf nodes represent intermediate results, and whose root node represents the whole calculation.
It has some advantages. For example, if you're doing what-if analysis and want to change the value of one input at a time, you can recalculate the results that depend on the value that you have changed, while retaining the results that don't.