LINUX.ORG.RU

Ищу интерпретатор формул для C++ с предварительным парсингом

 , , ,


0

1

Добрый день, ЛОР.
Ищу класс/библиотеку для C++, которому можно сначала скармливать формулы с арифметическими действиями и общеупотребительными математическими функциями (тригонометрия, логарифмы, всё вот это вот), а потом прокачивать через него массив аргументов и получать результат обработки по этим формулам.
Давным-давно был неплохой класс Parser от Jos de Jong, у которого объём нужных функций был близок к идеалу. Но во-первых, в сохранившихся у меня файлах нет информации о лицензии, а актуальные файлы в интернете не находятся. Тот же автор потом написал программу SpeqMath и все открытые наработки, похоже, из Сети убрал (ну или я плохо искал). Во-вторых, оптимальность реализации у него была так себе: формула парсилась всякий раз при вычислении очередного значения.
А хотелось бы найти интерпретатор с предварительным парсингом — к примеру, в конструктор передаётся строка с формулой, тут же парсится и преобразуется в последовательность кодов операций, отдельными методами передаются дополнительные переменные, и наконец, аргумент (или даже массив аргументов) для собственно расчётов.
Есть такие библиотеки? Желательно под LGPL или вообще под пермиссивной лицензией, ибо будет использоваться в проприетарном коде (но если найду, что улучшить в самой библиотеке, патчи автору зашлю, разумеется).

P.S. Читерство в виде вызова компилятора из своей программы не предлагать.

★★★★★

Последнее исправление: hobbit (всего исправлений: 1)

Я такое велосипедил на связке с++ и питон. В питоне был класс с перегруженными операциями, при вызове eval это все конвертилось в байткод (свой) задающий формулу в обратной польской нотации. Плюсы этот байткод жевали и считали для каждого набора аргументов. Хотя генерацию байткода можно было сделать и через модуль ast.

С т.з. соотношения гибкость/производительности это имно оптимум, что бы сделать лучше придется уже дергать компайлер.

Питон тут был затем чтобы парсить формулу малой кровью. Это моно и на плюсах конечно сделать, но гораздо геморнее, а так что бы весь стек собрать уходило умеючи день-два. И питон у меня там все равно использовался.

AntonI ★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

С т.з. соотношения гибкость/производительности это имно оптимум, что бы сделать лучше придется уже дергать компайлер.

вы просто не измеряли и выдали желаемое за действительное. На самом деле это медленнее. Это прямо таки дикий тормоз

к тому python ставит раком многопоточные приложения. (его интерпретатор как дункан маклауд может быть только один)

тогда уже эффективнее юзать tcc (Tiny С compiler) :-) но это тоже дичайший оверхед если надо всего-то «приготовить формулу вычислений и натравить её на массив/поток данных»

MKuznetsov ★★★★★
()
Ответ на: комментарий от AntonI

Можете предложить более быстрый вариант без вызова компилятора?

в самом начале предлагал exprtk - он (как и многие подобные) сначала строит байт-код, и даже отчасти его оптимизирует. А потом его исполняет над данными.

они («мат.парсеры») существенно быстрее py отчасти за счёт того что не делают ничего лишнего. Просто и тупо считают. Для них объект данных - непосредственно 64 бита double (или 32 float), а не некий универсальный контейнер objXXX с ссылками.

MKuznetsov ★★★★★
()

Писал в универе как-то такую библиотеку. Оно разбирало выражение переданное в строке, генерило код для fpu в область памяти, потом вызывало виндовый аналог mprotect чтобы сделать этот кусок памяти исполняемым ну и дальше можно было скастить указатель на буфер памяти с кодом к указателю на функцию и вызывать нужное количество раз с разным аргументом. Собственно я ее делал для того чтобы можно было рисовать график функции, а функция в окошке ввода формулой задавалась

cobold ★★★★★
()