Cpp DocsTable of ContentsComplex Numbers
Deriving Your Own Math Parser Class

Extending Math Parser C++ Class

This example shows how to derive your own Math Parser class to add fields that are specific to your application. The math parser instance is passed to the user defined function at runtime. You can cast it to your type to access the application specific fields. This way your custom functions can easily access different sets of data that are specific to a math parser instance. For example, if you have a spreadsheet application, you can assign a separate Math Parser instance to each spreadsheet and each parser instance will work independently of each other.

#include <iostream>
#include "MathParser.h"

using namespace std;

//define a Math Parser that works with char strings for
//variable and function names, and double values.
typedef CMathParser<char, double> MathParser;

/**
 * Define a custom math parser class that knows about our spread sheet application.
 * (Keep it simple for the sake of example)
 */

class MyParser : public MathParser {
public:
        //a variable that holds some app specific value, such as the cells of a spread sheet.
        double **m_CellValues; //row, column.
        //number of elements in above array.
        int m_RowCount;
        int m_ColCount;
};

/**
 * User defined function that returns some app specific value.
 */

double cell(MathParser* pParentParser, const double p[], const int count){
        if(count!=2){ //if not two params, throw err.
                //(This should never happen if we tell the parser that this function takes 2 parameters at the time we define it)
        throw MathParser::ParserException("Invalid number of parameters.");
        }
    int cellRowIndex = floor(p[0]);
    if(cellRowIndex<0 || cellRowIndex>=((MyParser*)pParentParser)->m_RowCount){
        throw MathParser::ParserException("Invalid cell row.");
    }
    int cellColIndex = floor(p[1]);
    if(cellColIndex<0 || cellColIndex>=((MyParser*)pParentParser)->m_ColCount){
        throw MathParser::ParserException("Invalid cell column.");
    }
        return ((MyParser*)pParentParser)->m_CellValues[cellRowIndex][cellColIndex];
}

int main(char **args){
        cout << "Math Parser Example Expressions" << endl;
        try{
                MyParser p;
                //Register a user defined function:
                //First parameter is function name that will appear in expressions.
                //Second parameter is number of parameters the function takes.
                //-1 means any number of parameters is allowed.
                //When the number of parameters to a function is known, it is better
                //to specify it so that the expression parser can detect in valid number
                //of parameters, instead of leaving parameter count validation to the
                //function itself.
                //Last parameter is the function address.
                p.CreateFunc(_T("CELL"), 2, cell);
               
                //pretend that we have cells.
                double * myCells[10];
                for(int i=0; i<10; i++){
                        myCells[i]=new double[20];
                        for(int j=0; j<20; j++){
                                myCells[i][j]=i*j; //put some data as cell values.
                        }
                }
               
                //Introduce our application context to our custom math parser:
                p.m_CellValues = myCells;
                p.m_RowCount = 10;
                p.m_ColCount = 20;
               
                cout << "-------------------------------------------------------" << endl;
                p.SetExpression("CELL(2,5)+1");
                cout << p.GetExpression() << endl;
                cout << p.GetValue() << endl;
               
                cout << "-------------------------------------------------------" << endl;
                p.SetExpression("10/CELL(5,5)+2");
                cout << p.GetExpression() << endl;
                cout << p.GetValue() << endl;

                cout << "-------------------------------------------------------" << endl;
                cout << "Done.";
               
                //delete memory. (will leak on exception).
                for(int i=0; i<10; i++){
                        delete[] myCells[i];
                }              
        }catch(MathParser::ParserException &ex ){
                cout << ex.GetMessage() << endl;
                cout << "Invalid portion of expression is <" << ex.GetInvalidPortionOfExpression() << ">." << endl;
        }catch(...){
                cout << "Unexpected error in math parser." << endl;
        }
}
 

webmaster@gobestcode.com