Para o pessoal que trabalha com .Net, existe a biblioteca [Flee].(https://github.com/mparlak/Flee)

Ela é sensacional, permite resolver expressões em tempo de execução além de permitir ser estendida, criando suas próprias funções personalizadas.

  • Resolvendo expressões:
using Flee.PublicTypes;

public class DynamicExpressions
{
    private readonly ExpressionContext expressionContext = new();

    public DynamicExpressions()
    {
        // Exemplo de inclusão de funções customizadas
        expressionContext.Imports.AddType(typeof(CustomFunctions));

        // Inclusão da System.Math, para permitir utilizar todos os seus métodos
        expressionContext.Imports.AddType(typeof(Math), "Math");

        //Configurações de regionalidade
        expressionContext.ParserOptions.DecimalSeparator = '.';
        expressionContext.ParserOptions.FunctionArgumentSeparator = ',';
        expressionContext.ParserOptions.RecreateParser();
    }

    /// <summary>
    /// Recebe uma expressão booleana em formato string e retorna o resultado
    /// </summary>
    /// <param name="expression"></param>
    /// <returns></returns>
    public bool EvaluateBoolExpression(string expression)
    {
        bool result;

        try
        {
            IGenericExpression<bool> e = expressionContext.CompileGeneric<bool>(expression);
            result = e.Evaluate();
        }
        catch (Exception ex)
        {
            throw new Exception("Erro ao validar a expressão booleana: (" + expression + ") - '" + ex.Message + "'");
        }
        return result;
    }


    /// <summary>
    /// Recebe uma expressão matemática em formato string e retorna o resultado
    /// </summary>
    /// <param name="expression"></param>
    /// <returns></returns>
    public double EvaluateDoubleExpression(string expression)
    {
        double result;

        try
        {            
            // Exemplo de utilização de método da System.Math
            // double valorArredondado = expressionContext.CompileGeneric<double>("Math.Round(1.55540040, 2)").Evaluate();

            // Exemplos de utilização de método personalizado
            
            //Arredonda(
            //    3.0 * MaiorValor(10.90 - 5.0, 0.0) + (10.0 + 15.0 + 20.0)
            //, 2)
            
            //double somaArray = expressionContext.CompileGeneric<double>("Soma(1.5, 2, 3, 4, 5, 6)").Evaluate();
            
            //double valorArredondadoAbnt5891 = expressionContext.CompileGeneric<double>("ArredondaAbnt5891(1.55540040, 2)").Evaluate();

            IGenericExpression<double> e = expressionContext.CompileGeneric<double>(expression);
            result = e.Evaluate();
        }
        catch (Exception ex)
        {
            throw new Exception("Erro ao validar a expressão matemática: (" + expression + ") - '" + ex.Message + "'");
        }
        return result;
    }
}
  • Estendendo:
    /// <summary>
    /// Funções personalizadas 
    /// Todos os métodos incluídos nesta classe, estarão disponíveis para uso nas expressoes
    /// </summary>
    public static class CustomFunctions
    {    
        /// <summary>
        /// Método de arredondamento "round-half-even"
        /// Ou "arredondamento do banqueiro"
        /// </summary>
        /// <param name="value"></param>
        /// <param name="digits"></param>
        /// <returns></returns>
        public static double ArredondaAbnt5891(double value, int digits)
        {
            return Math.Round(value, digits, MidpointRounding.ToEven);
        }
    
        /// <summary>
        /// Método de arredondamento "AwayFromZero"
        /// </summary>
        /// <param name="value"></param>
        /// <param name="digits"></param>
        /// <returns></returns>
        public static double Arredonda(double value, int digits)
        {
            return Math.Round(value, digits, MidpointRounding.AwayFromZero);
        }

        /// <summary>
        /// Executa a soma de todos os itens do array de doubles
        /// </summary>
        /// <param name="valores"></param>
        /// <returns></returns>
        public static double Soma(params double[] valores)
        {
            double resultado = 0;

            for (int i = 0; i < valores.Length; i++)
            {
                resultado += valores[i];
            }

            return resultado;
        }
    }