Is there a tool for parsing a string to create a C

2019-02-25 03:08发布

I need to know if there is any library out there that will allow me to, given a certain string representing a mathematical function, say, x^2+x+1, (don't care about how the string format, any will work for me) generates a C# func that will represent said function.

5条回答
老娘就宠你
2楼-- · 2019-02-25 03:18

You can use the CSharpCodeProvider class to compile code to a file/assembly and dynamically load the compiled assembly. Using the compiler from your program is described here. This Stackoverflow questions shows how to load the compiled assembly. Keep in mind that you need to wrap your function in a class to load and execute it later on.

Alternatively you can use CS-Script to do the dirty assembly compiling, loading and executing job.

查看更多
萌系小妹纸
3楼-- · 2019-02-25 03:18

You can use the CodeDOM to dynamic compile a type, about this, here you can find a fluent interface to simply the writing of the code, e.g:

var compileUnit = new FluentCodeCompileUnit()
    .Namespace("Sample1")
                .Class("Program")
                    .Method(MemberAttributes.Public | MemberAttributes.Static, "Main").Parameter(typeof(string[]), "args")
                        .CallStatic(typeof(Console), "WriteLine", Expr.Primitive("Hello Fluent CodeDom"))
                    .EndMethod

                    .Method(MemberAttributes.Public | MemberAttributes.Static, "Linq2CodeDomSupport").Parameter(typeof(string[]), "args")
                        .Stmt(ExprLinq.Expr(() => Console.WriteLine("Hello Linq2CodeDOM")))
                        .Declare(typeof(int), "random", ExprLinq.Expr(() => new Random().Next(10)))
                        .If((int random) => random <= 5)
                            .Stmt(ExprLinq.Expr(() => Console.WriteLine("Smaller or equal to 5.")))
                        .Else
                            .Stmt(ExprLinq.Expr(() => Console.WriteLine("Bigger than 5.")))
                        .EndIf
                    .EndMethod
               .EndClass
            .EndNamespace
        .EndFluent();

        var assembly = Helper.CodeDomHelper.CompileInMemory(compileUnit);
        assembly.GetType("Sample1.Program").GetMethod("Main").Invoke(null, new object[] { null });

I've to release on CodePlex a better fluent interface API that will use Roslyn also when it will be released in RTM.

查看更多
倾城 Initia
4楼-- · 2019-02-25 03:29

Take a look at the Roslyn API. It will allow you to compile strings at runtime

查看更多
ゆ 、 Hurt°
5楼-- · 2019-02-25 03:35

Been using FLEE (Fast Lightweight Expression Evaluator) for a while now and it's been working great. They have a version that maintains most functionality for Silverlight as well. It's designed to do pretty much exactly what you're asking for and more.

http://flee.codeplex.com/

Flee is an expression parser and evaluator for the .NET framework. It allows you to compute the value of string expressions such as sqrt(a^2 + b^2) at runtime. It uses a custom compiler, strongly-typed expression language, and lightweight codegen to compile expressions directly to IL. This means that expression evaluation is extremely fast and efficient.

Given your example from your comment to evaluate x^2+x+1 (written in Notepad):

public Func<double, double> CreateExpressionForX(string expression)
{

    ExpressionContext context = new ExpressionContext();
    // Define some variables
    context.Variables["x"] = 0.0d;

    // Use the variables in the expression
    IDynamicExpression e = context.CompileDynamic(expression);


    Func<double, double> expressionEvaluator = (double input) =>
    {
        content.Variables["x"] = input;
        var result = (double)e.Evaluate();
        return result;
    }

    return expressionEvaluator;
}



Func<double, double> expression = CreateExpressionForX("x^2 + x + 1");

double result1 = expression(1); //3
double result2 = expression(20.5); //441.75
double result3 = expression(-10.5); //121.75

Func<double, double> expression2 = CreateExpressionForX("3 * x + 10");

double result4 = expression2(1); //13
double result5 = expression2(20.5); //71.5
double result6 = expression2(-10.5); //-21.5
查看更多
Emotional °昔
6楼-- · 2019-02-25 03:35

This looks like a nice solution. Of course, it also can be solved with the usage of Expression Trees and a parse from strings to expressions, which later can be compiled (in run time), and executed.

查看更多
登录 后发表回答