Home

Download

Features

Screenshots

Handbook

Browse Source

Authors

SourceForge.net Logo
Hosted by SourceForge.net

OSI Certified


Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   Related Pages   Search  

fungparser.cpp

00001 /***************************************************************************
00002                           fungparser.cpp  -  wrapper for fparser to add a few extra functions
00003                              -------------------
00004     begin                : Wed Oct 9 2002
00005     copyright            : (C) 2002-03 by Fungmeista
00006     email                : mizunoami44@users.sourceforge.net
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #ifndef NO_QT
00019 #include <qregexp.h>
00020 #endif //NO_QT
00021 
00022 #include "fungparser.h"
00023 
00024 FungParser::FungParser() : FunctionParser()
00025 {
00026 }
00027 FungParser::~FungParser()
00028 {
00029 }
00030 
00031 int FungParser::Parse( std::string & _string, const char * vars, const char * name, std::vector<Expression*> &expressions, bool isDegrees)
00032 {
00033     AddConstant("pi",3.14159265358979323);
00034     AddConstant("e",2.718281828);
00035 
00036     QString varss = QString(vars).mid(0,strlen(vars)-2); //ignore animator value
00037 
00038     QStringList variables;
00039 
00040     int t = -1;
00041     variables<<varss.mid(0,varss.find(','));
00042     while ((t = varss.find(',',t+1)) != -1)         //extract all variables from "vars" which are seperated by commas and
00043         variables<<varss.mid(t+1,varss.find(',',t+1));//store them in the string list
00044     
00045     QString result(_string.c_str());
00046 
00047     bool recurse = false;
00048 
00049     for (unsigned int i=0; i<expressions.size(); i++)
00050     {
00051         int begin = result.find(QRegExp(QString(name)+QString("%1\\(").arg(i+1)));
00052         if (begin == -1){continue;}
00053         else {recurse = true;}
00054         begin += 1 + QString::number(i+1).length();
00055 
00056         int left_p = 0, right_p = 0, n = 0;
00057 
00058         if (result.contains("(") != result.contains(")")){ParseErrorType=1; return 1;} //can't parse this, bad syntax
00059         while (true)
00060         {
00061             if (QString::compare(result.mid(begin+n,1),"(") == 0)
00062                 left_p++;
00063             if (QString::compare(result.mid(begin+n,1),")") == 0)
00064                 right_p++;
00065             if (left_p == right_p)
00066                 break;
00067             n++;
00068         }
00069 
00070         QString args = result.mid(begin+1,n-1);
00071 
00072         QStringList arguments;
00073         t = -1;
00074         arguments<<args.mid(0,args.find(','));
00075         while ((t = args.find(',',t+1)) != -1)
00076             arguments<<args.mid(t+1,args.find(',',t+1));
00077 
00078         if (QString(QString(expressions[i]->getExpression(name).c_str())+"(").contains(QString(name)+QString("%1(").arg(i+1))) //prevent infinite recursion
00079             return FunctionParser::Parse(result.latin1(),vars,isDegrees);
00080         if (arguments.size() != variables.size() ){ParseErrorType=8; return 8;}  //wrong number of parameters
00081 
00082         QString subfunction = "("+QString(expressions[i]->getExpression(name).c_str())+")";
00083 
00084         QStringList::Iterator var_it = variables.begin();
00085         for ( QStringList::Iterator arg_it = arguments.begin(); arg_it != arguments.end(); ++arg_it)
00086         {
00087             subfunction = subfunction.replace(QRegExp(QString("%1(?![a-z])").arg(*var_it)),*arg_it); //don't match functions that contain possible variables (tan(), exp(), etc.)
00088             ++var_it;
00089         }
00090 
00091         result = result.replace(begin-1-QString::number(i+1).length(),n+2+QString::number(i+1).length(),subfunction);
00092     }
00093     if (!recurse)  //function has been parsed to be recognized by base parser, now give it to the base parser
00094         return FunctionParser::Parse( result.latin1(), vars, isDegrees );
00095     else
00096     {
00097         qDebug("calling FunctionParser::parse() recursively");
00098         std::string s(result.latin1()); 
00099         return Parse( s, vars, name, expressions, isDegrees );  //still has FungParser specifics - can't send to base parser - continue parsing
00100     }
00101 
00102     #if 0
00103     AddConstant("pi",3.14159265358979323);
00104     AddConstant("e",2.718281828);
00105 
00106     for ( unsigned int i = 0; i < expressions.size(); i++ )
00107     {
00108         FungParser *fp = expressions[i]->getParsedExpression(name);
00109         std::string func_name = QString("%1%2").arg(name).arg(i).latin1();
00110         AddFunction(func_name,*fp);
00111     }
00112 
00113     return FunctionParser::Parse(_string,vars,isDegrees);
00114     #endif
00115 
00116 
00117 }