Простая библиотека или реализация для оценщика математических выражений

У меня есть один текстовый файл, содержащий только одну строку, строка содержит только одно математическое выражение например, 12+ (3,0 * (4) -1)/sqrt (121)

моя программа должна прочитать это выражение как строку, а затем дать результат
13

есть ли какой-либо простой способ или сторонняя dll/lib, чтобы это сделать?

КОММЕНТАРИЙ ДОБАВЛЕН:

Оценка строки простых математических выражений

вот решение, но многие из решений содержат только + -/* acturally, мне нужны операторы как можно больше, такие как квадратный корень квадрата и мощность()

так что эта ссылка может быть лучшим решением
http://www.codeproject.com/KB/recipes/sota_expression_evaluator.aspx

Ответы

Ответ 1

Используя ExprTk, можно легко получить следующее простое решение:

#include <cstdio>
#include <string>

#include "exprtk.hpp"

int main()
{
   typedef exprtk::expression<double> expression_t;
   typedef exprtk::parser<double>         parser_t;

   std::string expression_string = "12 + (3.0 * (4) - 1) / sqrt(121)";

   expression_t expression;

   parser_t parser;

   if (parser.compile(expression_string,expression))
   {
     double result = expression.value();

     printf("Result: %19.15\n",result);
   }
   else
     printf("Error in expression\n.");

   return 0;
}

Ответ 2

.NET-решения:

Здесь пара тем на SO:


Также два проекта, которые я уже использовал раньше:

С#: NCalc - Оценщик математических выражений для .NET

NCalc - это оценщик математических выражений в .NET. NCalc может анализировать любое выражение и оценивать результат, включая статические или динамические параметры и пользовательские функции.


VB.NET: Быстрое облегчение оценки экспрессии

Flee является парсером выражения и оценщиком для платформы .NET. Он позволяет вам вычислить значение строковых выражений, таких как sqrt (a ^ 2 + b ^ 2) во время выполнения. Он использует собственный компилятор, строго типизированный язык выражения и легкий код для компиляции выражений непосредственно в IL. Это означает, что оценка экспрессии очень быстро и эффективно. Попробуйте demo, который позволяет создавать изображения на основе выражений и видеть сами.

Вы можете использовать его с С#, так как он в любом случае (через ссылку на сборку).

Ответ 3

Для C et al, здесь быстрый n-грязный и очень опасный чит, который требует Perl:

double eval(const char* expr) {
    char buf[1024];
    snprintf(buf, sizeof(buf), "perl -e 'print (%s)'", expr);
    FILE* p = popen(buf, "r");
    double d;
    fscanf(p, "%lf", &d);
    fclose(p);
    return d;
}

Ответ 4

В среде программирования UNIX, я думаю, это был простой калькулятор под названием hoc (IIRC). Возможно, его исходный код доступен где угодно.

Приветствия и hth.,

Ответ 5

Я бы подумал о вложении lua. Его быстрый, легкий и ansi C. И он был специально разработан для встраивания. Используется многими играми как их язык сценариев. (IMO гораздо проще встраивать, чем python или perl)

Вот полный пример, показывающий, насколько тривиальным является

extern "C"
{
  #include "lua.h"
  #include "lauxlib.h"
  #include "lualib.h"
}

#include <string>
#include <iostream>

int main()
{
   std::string expression = "12+(3.0*(4)-1)/math.sqrt(121)";
   lua_State * L = lua_open();
   luaopen_math(L);
   if( luaL_dostring(L, ("return "+expression).c_str()) != 0 )
   {
      std::cout<<"ERROR : "<<lua_tostring(L,-1)<<std::endl;
   }
   if( lua_type(L,-1) == LUA_TNUMBER )
   {
      std::cout<<"GOT "<<lua_tonumber(L,-1)<<std::endl;
   }
   lua_close(L);
}

Ответ 6

Если вы хотите отважиться на исходный код, вы всегда можете посмотреть bc. Он обрабатывает всю доброту Lex/Yacc для вас. И если вы хотите чистое решение на С++, вы можете попробовать кодирование в Boost Spirit.