Estoy buscando una biblioteca C/C++ que evalúe y ejecute expresiones matemáticas. Python sería un buen comienzo, pero dado que C-Python o PyPy tienen un GIL, esta no es una solución. Clang habría funcionado ya que es muy rápido e incluso crea instrucciones de procesador nativas, pero en mi opinión, usar un compilador completo solo para este objetivo es demasiado.
Requisitos:
Cualquier sugerencia es apreciada
Conozco tres bibliotecas para esta tarea. Bastante seguro de que ninguno de ellos hace JIT.
Utiliza un analizador basado en yacc y bison. Puede evaluar expresiones matemáticas simples con pocas funciones y símbolos predefinidos. Es una biblioteca C que debe compilarse y vincularse. Licencia: GPL
#include <cassert>
#include <iostream>
#include <string>
#include <matheval.h>
int main() {
std::string expr = "1+x";
char *buf = const_cast<char*>(expr.c_str());
void *f = evaluator_create (buf);
assert(f);
int x = 1;
std::cout << evaluator_evaluate_x (f, x) << '\n';
}
Utiliza Boost.Spirit y Boost.Fusion para analizar y evaluar. Tiene soporte para todas las funciones de la biblioteca matemática estándar de C++11. Define algunas constantes. Biblioteca de plantillas de solo encabezado de archivo único, requiere C++ 11, el tiempo de compilación será del orden de segundos debido a Boost.Spirit. Licencia: Boost. (descargo de responsabilidad: soy el autor)
#include <iostream>
#include <string>
#include <matheval.hpp>
int main() {
std::string expr = "1+x";
matheval::Parser<double> parser;
parser.parse(expr);
std::cout << parser.evaluate({std::make_pair("x",1)}) << '\n';
// // or even simpler
// matheval::parse<double>(expr,{std::make_pair("x",1)})
}
Un verdadero monstruo con casi 40000 líneas en un solo archivo de cabecera. Implementa una máquina de estado completa que incluye cosas como operaciones lógicas, estructuras de control e incluso archivo IO. El tiempo de compilación es incluso más largo que con Boost Matheval.
#include <iostream>
#include <string>
#include <exprtk.hpp>
int main() {
std::string expr = "1+x";
double x = 1;
exprtk::symbol_table<double> symbol_table;
symbol_table.add_variable("x",x);
exprtk::expression<double> expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<double> parser;
parser.compile(expr,expression);
std::cout << expression.value() << '\n';
}
Si necesita algo más que expresiones matemáticas, considere integrar un lenguaje de extensión en su programa, como Lua (para el cual existe LuaJIT).
0x01
Hola Mundo