Вопрос по parsing, c#, string – Есть ли инструмент для разбора строки для создания функции C #?

3

Мне нужно знать, есть ли какая-нибудь библиотека, которая позволит мне, учитывая определенную строку, представляющую математическую функцию, скажем,x^2+x+1, (не волнует, как формат строки, любой будет работать для меня) генерирует функцию C #, которая будет представлять указанную функцию.

Нет, я говорю о библиотеке, которая, например, берет строку: x ^ 2 + x + 1 и генерирует функцию c #, которая дает X, соответственно, оценивает ее. user1432653
Вы говорите о чем-то вродеeval функция для C #?stackoverflow.com/questions/4629/… codeproject.com/Articles/11939/Evaluate-C-Code-Eval-Function Tim S.
Я имею в виду парсинг математических функций для функции в C #. user1432653

Ваш Ответ

5   ответов
4

Посмотрите наРослин API, Это позволит вам скомпилировать строки во время выполнения

Error: User Rate Limit Exceeded
1

Вы можете использоватьCodeDOM динамически скомпилировать тип, об этом,Вот Вы можете найти свободный интерфейс для простого написания кода, например:

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 });

Я хочу выпустить на CodePlex более удобный интерфейс API, который будет использоватьРослин также когда это будет выпущено в RTM.

2

Вы можете использоватьCSharpCodeProvider класс для компиляции кода в файл / сборку и динамической загрузки скомпилированной сборки. Использование компилятора из вашей программы описаноВот, этоВопросы Stackoverflow показывает, как загрузить скомпилированную сборку. Имейте в виду, что вам нужно обернуть свою функцию в класс, чтобы загрузить и выполнить ее позже.

В качестве альтернативы вы можете использоватьCS-Script делать грязную сборку, компилировать, загружать и выполнять работу.

Error: User Rate Limit Exceeded user1432653
Error: User Rate Limit Exceeded
9

Некоторое время назад использовал FLEE (Fast Lightweight Expression Evaluator), и он отлично работал. У них есть версия, которая поддерживает большую часть функциональности и для Silverlight. Он предназначен для того, чтобы делать в точности то, что вы просите, и даже больше.

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.

Учитывая ваш пример из вашего комментария, чтобы оценитьx^2+x+1 (написано в блокноте):

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
0

это выглядит как хорошее решение. Конечно, это также может быть решено с использованиемДеревья выражения и синтаксический анализ строк и выражений, которые впоследствии можно скомпилировать (во время выполнения) и выполнить.

Error: User Rate Limit Exceeded user1432653

Похожие вопросы