Equivalentfunktion zur Eval()-Funktion
-
Ihr seid meine letzte Rettung!
Also, ich suche ein Equivalent zur eval()-Funktion in Java\1: Das heisst, eine Funktion die einen Formelausdruck interpretiert und berechnet.
Beispiel: Der User gibt "6+sqrt(49)" ein. Die Eval-Funktion errechnet hieraus den Wert 13.Ich habe schon vergebens gesucht habe aber nichts gefunden. ich benötige das ganze für einen Funktions-Plotter.
Danke!
chris90
-
Equivalent - falsch
Äquivalent - richtigWas ist ein Funktions-Plotter?
Ist ein Funktionsplotter ein Drucker??MfG CSS
-
Selbst programmieren oder eine Library dafür suchen.
Sowas bieten meistens nur interpretierte Sprachen an. C++ hat sowas nicht.
-
ein Funktionsplotter malt den graph der Funktion.
So eine eval-Funktion gibt es nicht in C++ bzw. man müsste sie selber schreiben.
-
hat denn niemand selbst schonmal dieses Problem gehabt und eine Lösung dafür? Selber programmieren ist ja allein schon ein projekt für sich... zumindestens weil es in C++ keine gescheiten Suchfunktionen und dergleichen gibt ( z.b. reguläre Ausdrücke)
-
chris90 schrieb:
zumindestens weil es in C++ keine gescheiten Suchfunktionen und dergleichen gibt ( z.b. reguläre Ausdrücke)
wie wärs denn mal damit?
-
Vielleicht kannst Du auch das hier fuer Deine eigenen Beduerfnisse anpassen:
#include <string> #include <math.h> #include <stdio.h> // EBNF fuer Eval: // // number := /[0-9]+\.?[0-9]*[eE]?[+-]?[0-9]*/ ; // func := 'sqrt' . // // base-expr := number | '(' expr ')' | func '(' expr ')' . // unary-expr := [ '-' ] base-expr . // mult-expr := unary-expr { ( '**' | '*' | '/' | '%' ) unary-expr } . // add-expr := mult-expr { ( '+' | '-' ) mult-expr } . // expr := add-expr . typedef std::string String; class Eval { public: String s; int ix; int sz; double n; Eval( const String& _s ); ~Eval( void ); bool skipws( void ); bool number( void ); bool func( void ); bool base_expr( void ); bool unary_expr( void ); bool mult_expr( void ); bool add_expr( void ); bool expr( void ); }; Eval::Eval( const String& _s ) : s(_s), ix(0), sz(static_cast<int>(s.size())), n(0.0) { } Eval::~Eval( void ) { } bool Eval::skipws( void ) { // leerzeichen ueberlesen while ( ix < sz && ( s[ix] == ' ' || s[ix] == '\t' || s[ix] == '\n' || s[ix] == '\r' ) ) ++ix; return true; } bool Eval::number( void ) { // number := /[0-9]+\.?[0-9]*[eE]?[+-]?[0-9]*/ ; skipws(); if ( ix < sz && s[ix] >= '0' && s[ix] <= '9' ) { const char* t = s.c_str() + ix; int cnt = 0; if ( sscanf( t, "%lf%n", &n, &cnt ) == 1 ) { ix += cnt; return true; } } return false; } bool Eval::func( void ) { // func := 'sqrt' . skipws(); if ( ix < sz && s[ix] >= 'a' && s[ix] <= 'z' ) { const char* t = s.c_str() + ix; char name[128]; int cnt = 0; int old_ix = ix; if ( sscanf( t, "%[a-z]%n", name, &cnt ) == 1 ) { ix += cnt; do { skipws(); if ( ix < sz && s[ix] == '(' ) { ++ix; if ( expr() && skipws() && ix < sz && s[ix] == ')' ) { ++ix; if ( strcmp( name, "sqrt" ) == 0 ) { n = sqrt( n ); return true; } else { printf( "? invalid function '%s' near '%s'\n", name, t ); } } else { printf( "? ')' expected near '%s'\n", t ); } } else { printf( "? '(' expected near '%s'\n", t ); } } while ( 0 ); } ix = old_ix; return false; } } bool Eval::base_expr( void ) { // base-expr := number | '(' expr ')' | func '(' expr ')' . if ( number() ) return true; skipws(); if ( ix < sz && s[ix] == '(' ) { int old_ix = ix; ++ix; do { if ( expr() && skipws() && ix < sz && s[ix] == ')' ) { ++ix; return true; } else { printf( "? ')' expected near '%s'\n", s.c_str() + ix ); } } while (0); ix = old_ix; return false; } return func(); } bool Eval::unary_expr( void ) { // unary-expr := [ '-' ] base-expr . skipws(); if ( ix < sz && s[ix] == '-' ) { int old_ix = ix; ++ix; if ( base_expr() ) { n = -n; return true; } ix = old_ix; return false; } else { return base_expr(); } } bool Eval::mult_expr( void ) { // mult-expr := unary-expr { ( '**' | '*' | '/' | '%' ) unary-expr } . if ( !unary_expr() ) return false; skipws(); while ( ix < sz && ( ( s[ix] == '*' && ix+1 < sz && s[ix+1] == '*' ) || s[ix] == '*' || s[ix] == '/' || s[ix] == '%' ) ) { int op = 0; double n1 = n; int old_ix = ix; if ( s[ix] == '*' && ix+1 < sz && s[ix+1] == '*' ) { op = 1; ix += 2; } else if ( s[ix] == '*' ) { op = 2; ++ix; } else if ( s[ix] == '/' ) { op = 3; ++ix; } else if ( s[ix] == '%' ) { op = 4; ++ix; } if ( op > 0 ) { if ( unary_expr() ) { switch ( op ) { case 1: n = pow( n1, n ); break; case 2: n = n1 * n; break; case 3: n = n1 / n; break; case 4: n = fmod( n1, n ); break; } skipws(); continue; } else { printf( "? expression expected near '%s'\n", s.c_str() + ix ); } } else { printf( "? internal error: unknown operator near '%s'\n", s.c_str() + old_ix ); } ix = old_ix; return false; } return true; } bool Eval::add_expr( void ) { // add-expr := mult-expr { ( '+' | '-' ) mult-expr } . if ( !mult_expr() ) return false; skipws(); while ( ix < sz && ( s[ix] == '+' || s[ix] == '-' ) ) { int op = 0; double n1 = n; int old_ix = ix; if ( s[ix] == '+' ) { op = 1; ++ix; } else if ( s[ix] == '-' ) { op = 2; ++ix; } if ( op > 0 ) { if ( mult_expr() ) { switch ( op ) { case 1: n = n1 + n; break; case 2: n = n1 - n; break; } skipws(); continue; } else { printf( "? expression expected near '%s'\n", s.c_str() + ix ); } } else { printf( "? internal error: unknown operator near '%s'\n", s.c_str() + old_ix ); } ix = old_ix; return false; } return true; } bool Eval::expr( void ) { // expr := add-expr . return add_expr(); } int main( int argc, char** argv ) { for (;;) { char buf[1024]; printf( "formel> " ); fflush(stdout); buf[0] = '\0'; if ( fgets( buf, 1024, stdin ) == 0 ) break; if ( buf[0] == '\0' || buf[0] == '\n' ) break; String str(buf); int sz = str.size(); while ( sz != 0 && ( str[sz-1U] == '\n' || str[sz-1U] == '\r' ) ) { str.resize(sz-1U); sz = str.size(); } Eval e(str); if ( !e.expr() ) { printf( "? expression expected: '%s'\n", str.c_str() ); } else { printf( "result = %g\n", e.n ); } } return 0; }
(hoffe, es ist nicht zu lang)