2

I'm currently making a calculator. I know how to write the logic but I'm curious if it can be done the way I'm going to explain.

String str = "12 + 43 * (12 / 2)";
int answer;

answer = str.magic(); 

//str.magic is the same as 
answer =   12 + 43 * (12 / 2);

now what I want is how I can turn str into executible code.

leppie
  • 115,091
  • 17
  • 196
  • 297
Peymon
  • 41
  • 1
  • 7
  • Yes it can be done. Google _expression parsers_ –  Jan 13 '16 at 05:12
  • have a look http://stackoverflow.com/questions/2853907/how-to-parse-math-expressions-in-c – SSH Jan 13 '16 at 05:14
  • Check this http://stackoverflow.com/questions/5838918/evaluate-c-sharp-string-with-math-operators – Nitin Varpe Jan 13 '16 at 05:15
  • I'm a bit confused - what are you trying to ask? You say you "know how to write the logic" but then ask how you can actually perform the task? – ajshort Jan 13 '16 at 05:17

2 Answers2

5

You can use CodeDom to get a 'native' C# parser. (You should improve the error handling.)

using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Reflection;

...

static void Main()
{
    double? result = Calculate("12 + 43 * (12 / 2)");
}

static double? Calculate(string formula)
{
    double result;
    try
    {
        CompilerParameters compilerParameters = new CompilerParameters
        {
            GenerateInMemory = true, 
            TreatWarningsAsErrors = false, 
            GenerateExecutable = false, 
        };

        string[] referencedAssemblies = { "System.dll" };
        compilerParameters.ReferencedAssemblies.AddRange(referencedAssemblies);

        const string codeTemplate = "using System;public class Dynamic {{static public double Calculate(){{return {0};}}}}";
        string code = string.Format(codeTemplate, formula);

        CSharpCodeProvider provider = new CSharpCodeProvider();
        CompilerResults compilerResults = provider.CompileAssemblyFromSource(compilerParameters, new string[]{code});
        if (compilerResults.Errors.HasErrors)
            throw new Exception();

        Module module = compilerResults.CompiledAssembly.GetModules()[0];
        Type type = module.GetType("Dynamic");
        MethodInfo method = type.GetMethod("Calculate");

        result = (double)(method.Invoke(null, null));
    }
    catch (Exception)
    {
        return null;
    }

    return result;
}
Fratyx
  • 5,717
  • 1
  • 12
  • 22
  • As a note: This does not work in .net core or .net5+. For this I recommend [this](https://stackoverflow.com/a/37531000/6560579) – Ackdari Mar 08 '22 at 12:24
1

You can simply use NCalc library Click here for more information. you can download that dll file from here

Example:

NCalc.Expression exp= new NCalc.Expression("(12*3)-29");
object obj = exp.Evaluate();
MessageBox.Show(obj.ToString());
Darshan Faldu
  • 1,471
  • 2
  • 15
  • 32