Я ищу библиотеку C/C++, которая вычисляет и выполняет математические выражения. Python был бы хорошим началом, но поскольку C-Python или PyPy имеют GIL, это не решение. Clang сработал бы, так как он очень быстрый и даже создает собственные инструкции процессора, но использование всего компилятора только для этой цели, на мой взгляд, слишком много.
Требования:
Любое предложение приветствуется
Я знаю три библиотеки для этой задачи. Почти уверен, что никто из них не делает JIT.
Использует парсер на основе yacc и bison. Может вычислять простые математические выражения с помощью нескольких предопределенных функций и символов. Это библиотека C, которая должна быть скомпилирована и слинкована. Лицензия: 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';
}
Использует Boost.Spirit и Boost.Fusion для анализа и оценки. Поддерживает все стандартные функции математической библиотеки C++11. Определяет несколько констант. Библиотека шаблонов только для заголовков одного файла, требуется C++11, время компиляции будет порядка секунд из-за Boost.Spirit. Лицензия: Boost. (отказ от ответственности: я автор)
#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)})
}
Настоящий монстр с почти 40000 строк в одном заголовочном файле. Он реализует полный конечный автомат, включая такие вещи, как логические операции, управляющие структуры и даже файловый ввод-вывод. Время компиляции даже больше, чем с 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';
}
Если вам нужно нечто большее, чем просто математические выражения, рассмотрите возможность встраивания в вашу программу языка расширения, такого как Lua (для которого существует LuaJIT).
0x01
Привет мир