Math parser

  • Thread starter Thread starter Janiek Buysrogge
  • Start date Start date
J

Janiek Buysrogge

Hello,

Does anyone know if there is a library or a sample project that can
parse strings with mathematical expressions inside ?

eg. string math = "(23 + 48) ^ 2 - (7.76 * 3.14)";
parser should calculate the result of this.

Atm I have my own parser, but it can only handle very simple
expressions with 2 operands eg. (34 * 89), I tried to expand the
functionality, but it's getting ugly (loads of substrings).

Any pointers ?

Thanks,

Janiek
 
wouldn't it just be best to do the math then convert the answer to string?

double math = Math.Pow((23 + 48) , 2) - (7.76 * 3.14);
Console.WriteLine (Convert.ToString(math));
 
Mike,

The expression will be formed at runtime as opposed to compile time.
That's why the OP is looking for an expression evaluator.

Brian
 
Janiek,

I'm just throwing out some more options here.

1) You could use a compiler compiler. ANTLR is a popular one that
generates C# code. It would take some time to familiarize yourself
with EBNF grammars and how ANTLR works in general though.

<http://www.antlr.org>

2) Write your own parser. For an arithmetic expression evaluator it's
really not too difficult. There is a simple approach that inolves 3
basic steps. First, tokenize the expression. Second, convert the
infix notation to postfix notation. Finally, perform the evaluation
using postfix notation. There are other algorithms as well, but I
think infix to postfix is pretty easy to learn and it works well.

3) Download. Personally, I haven't seen any free ones written in C#
that I thought were worth downloading. The problem with the ones I've
seen is that they don't implement operator precedence and associativity
correctly, they don't accept user defined function, etc. It was an
issue for me, but it may not be an issue for you.

Brian
 
If you don't mind dynamic code, you could do something like so:

string code = "Math.Pow(23 + 48, 2) - (7.76 * 3.14)";
string result = Eval.StringEval(code);
Console.WriteLine("Results: " + result);

Output
-------------------
Results: 5016.6336

Eval Class
--------------------
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;

public static class Eval
{
private static string funcprefix = "using System;\r\n"
+ "public delegate void Proc();\r\n"
+ "public class Wrapper { \r\n"
+ " public static object Set(string name, object value) { \r\n"
+ " AppDomain.CurrentDomain.SetData(name, value);\r\n"
+ " return value; \r\n"
+ " }\r\n"
+ " public static object Get(string name) { \r\n"
+ " return AppDomain.CurrentDomain.GetData(name);\r\n"
+ " }\r\n"
+ " public static object Invoke(Proc proc) { \r\n"
+ " proc();\r\n"
+ " return null; \r\n"
+ " }\r\n"
+ " public static object Eval() { return \r\n";
static string funcsuffix = "; \r\n} }";


public static string StringEval(string expr)
{
string program = funcprefix + expr + funcsuffix;
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;

CompilerResults results =
CodeDomProvider.CreateProvider("C#").CompileAssemblyFromSource(cp, new
string[]{program});
if ( results.Errors.HasErrors )
{
if ( results.Errors[0].ErrorNumber == "CS0029" )
return StringEval("Invoke(delegate { " + expr + "; })");
throw new Exception(results.Errors[0].ErrorText);
}
else
{
Assembly assm = results.CompiledAssembly;
Type target = assm.GetType("Wrapper");
MethodInfo method = target.GetMethod("Eval");
object result = method.Invoke(null, null);
return result == null ? null : result.ToString();
}
}
}
 
Hello,

Thank you all for your contribution, I really appreciate it.

I will investigate further, the extendable parser seems the quickest
way, but the dynamic code also seems very interesting, it was a topic
of C# which I hadn't explored yet.

Again, thx for all the info,

Janiek
 
Janiek,

One thing to keep in mind if you decide to use the dynamic code
approach is security. Many of the BCL method calls could be used
maliciously.

Brian
 
Hello,


There are math parser components for C# (csharp), java, COM, and Delphi
at
<a href="http://www.bestcode.com">http://www.bestcode.com</a>


<a
href="http://www.bestcode.com/html/bcparser_net.html">http://www.bestcod
e.com/html/bcparser_net.html</a>is bcParser.NET, a Math Parser Component
for .NET Developers. Written in C# (CSharp) is excellent match for
Visual Studio .NET and Delphi.NET users. VB.NET and C# examples
included. (C# Source code included.)

<a
href="http://www.bestcode.com/html/tbcparser.html">http://www.bestcode.c
om/html/tbcparser.html</a> is TbcParser, a VCL math expression parser
component for Delphi and C++ Builder.

<a
href="http://www.bestcode.com/html/bcparserx.html">http://www.bestcode.c
om/html/bcparserx.html</a> is bcParserX, a Math Parser COM component for
Visual Basic, Visual C++ Developers.

<a
href="http://www.bestcode.com/html/jbcparser.html">http://www.bestcode.c
om/html/jbcparser.html</a>is JbcParser, a Math Parser for Java
Developers.
 
He is trying to evaluate the expression that is given at runtime. It is
not known at compile time.


There are math parser components for C# (csharp), java, COM, and Delphi
at
<a href="http://www.bestcode.com">http://www.bestcode.com</a>


<a
href="http://www.bestcode.com/html/bcparser_net.html">http://www.bestcod
e.com/html/bcparser_net.html</a>is bcParser.NET, a Math Parser Component
for .NET Developers. Written in C# (CSharp) is excellent match for
Visual Studio .NET and Delphi.NET users. VB.NET and C# examples
included. (C# Source code included.)

<a
href="http://www.bestcode.com/html/tbcparser.html">http://www.bestcode.c
om/html/tbcparser.html</a> is TbcParser, a VCL math expression parser
component for Delphi and C++ Builder.

<a
href="http://www.bestcode.com/html/bcparserx.html">http://www.bestcode.c
om/html/bcparserx.html</a> is bcParserX, a Math Parser COM component for
Visual Basic, Visual C++ Developers.

<a
href="http://www.bestcode.com/html/jbcparser.html">http://www.bestcode.c
om/html/jbcparser.html</a>is JbcParser, a Math Parser for Java
Developers.
 
Back
Top