Simple Numerical Formula Parser

Environment: VC6 SP3, Windows 95/98/NT/2000

The class CFormulaParser encapsulates a very useful mathematical parser for analytic/numerical formula transformation.

The formula dialog above is actually not necessary for the functionality but allows you comfortable to put in a formula string.

Hereby an extract from the header file:

class CFormulaParser  
{
private:
 //Implementation
 CString m_strFormula;
 CString m_strFunction;
 CString m_strErrortext;
 double m_dFktValue;
 double m_dFunctionConstant[ANZFUNKTKONST];
 CStringArray m_strStandardFunction;

 double SignFactor(WORD& nPosition, CString& strCharacter);
 double Expression(WORD& nPosition, CString& strCharacter);

 double SimpleExpression(WORD& nPosition, 
                         CString& strCharacter);

 double Term(WORD& nPosition, CString& strCharacter);
 double Factor(WORD& nPosition, CString& strCharacter);
 double Char_n(WORD& nPosition, CString& strCharacter);
				 
public:
 CString GetFormula();
 void SetFormula(CString Formula);
 void SetFunctConst(int index, double val);
	
 CFormulaParser();
 virtual ~CFormulaParser();

//Interface
 double Calculation(CString strFormula, 
                    double xValue, 
                    WORD& 
                    ErrorPosition, 
                    CString& 
                    Errortext);
};
The main method in CFormulaParser for the evaluation is:
double Calculation(CString strFormula, 
                   double xValue, 
                   WORD& 
                   ErrorPosition, 
                   CString& 
                   Errortext);
where
  • strFormula is the formula string, e.g. "b*sin(x)/x"
  • xValue is in this case x, e.g. 3.14 (point instead comma!)
  • ErrorPosition gives back the error position in the string
  • Errortext gives back the corresponding error text
The parser is part of the program SimplexNumerica. For more information, please see my German website http://www.SimplexNumerica.de.

Download

Download demo project (with source) - 104 Kb


Comments

  • Hmm

    Posted by NN_PP on 10/13/2004 03:17am

    Hey this can be done by any one, u r simply going and checking each character one by one. Isnt there any other simple means of doing this, for e.g. does the Excel also use the same way?

    Reply
  • Nice, but minor mistakes.

    Posted by Legacy on 09/03/2003 12:00am

    Originally posted by: oleg63

    If you type something like (2+3)*
    the parser wan't give an error and point on extra character
    "*".
    Thanks.

    Reply
  • Added function to check parenthesys

    Posted by Legacy on 01/07/2003 12:00am

    Originally posted by: Jordi Duatis

    As a response to the author hereby a function to check parenthesys correctness, function is added to the calculation function in this way:

    if (!CheckParenthesis())
    {
    // Formula has an error in parenthesys
    ErrorPosition = -1;
    Errortext = m_strErrortext;
    return 0;
    }
    /.../

    BOOL CFormulaParser::CheckParenthesis()
    {
    // Count open and close parenthesis to check correctness and forget about it
    // for the rest of the process.
    char cInput;
    int iOpenPar = 0, iClosePar = 0;
    // Go through all characters in the expression and check each char
    for( int ii=0; ii<m_strFormula.GetLength();ii++)
    {
    // Get current char
    cInput = m_strFormula.GetAt(ii);
    // register parenthesis number and avoid tokenize it
    if (cInput == '(')
    {
    iOpenPar++;
    }
    else if (cInput == ')')
    {
    iClosePar++;
    }
    }
    // Check number of open parenthesys is OK
    if (iOpenPar > iClosePar)
    {
    // missing close parenthesys
    m_strErrortext.LoadString(IDS_MISSING_CLOSE_PAR);
    return FALSE;
    }
    // Check number of close parenthesys is OK
    else if (iOpenPar < iClosePar)
    {
    // missing open parenthesys
    m_strErrortext.LoadString(IDS_MISSING_OPEN_PAR);
    return FALSE;
    }
    return TRUE;
    }


    In Calculation function, error position is changed from dword to int to allow negative values. In fact, error checking has been improved adding exception handling and in the function calculation a complete try{}catch block has been implemented.

    I've sent the complete module modified to the author, expecting he would update the post.

    Best whishes.

    Reply
  • Nice work: Fix for text insertion

    Posted by Legacy on 12/24/2002 12:00am

    Originally posted by: Jan S. Yoder

    Nice work, and a pretty good calculator.  However, I tried to insert parentheses around your default text and had to go to the keyboard to do it.  I added a CEdit variable named m_EditInputControl to the header file and a DDX_Control call, then changed your function as shown here.  This retains the current selection location and inserts the character pressed on the on-screen keyboard at the appropriate location in the existing string.
    
    

    In SimplexParserDlg.h
    CEdit m_EditInputControl;

    In SimplexParserDlg.cpp

    DDX_Control(pDX, IDC_FORMELEINGABE, m_EditInputControl);


    void CSimplexParserDlg::SetEingabe(CString str)
    {
    UpdateData(true);

    int nStart = -1, nEnd = -1;
    m_EditInputControl.GetSel(nStart, nEnd);

    CString strExistingText(m_strFormulainput);

    int nLength = strExistingText.GetLength();

    if (nLength > 0)
    {
    strExistingText = strExistingText.Mid(0,
    nStart) + str + strExistingText.Mid(nEnd);
    }
    else
    {
    strExistingText += str;
    }

    nStart += str.GetLength();
    nEnd = nStart;

    m_strFormulainput_vorher = strExistingText;
    m_strFormulainput = strExistingText;
    UpdateData(false);

    m_EditInputControl.SetFocus();
    m_EditInputControl.SetSel(nStart, nEnd);
    }

    Reply
  • Good work! Only some minor problems fixed.

    Posted by Legacy on 12/05/2002 12:00am

    Originally posted by: Jordi Duatis

    Firstable, thanks for this code. Is exactly what I could expect for a math formula parser and interpreter. Works quite fine, but there was some minor problems in the CFormulaParser class I had to fix to add this code to my project:

    1- Errors where not correctly reported. I added an exception that catches error message and position and can be trapped in the Calculation function.

    2- There was a trick for division by 0 not suitable in all cases. I prefer to issue an error in this case.

    3- Did not check for parenthesys.

    4- Char_n returned an unused value

    As you can see minor problems. I can provide the code if needed.

    Good work!

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • All businesses have a core set of applications that are critical to successful growth. These applications require a higher level of availability than other applications and services in the organization. There is a trade-off, however, to increasing application availability through traditional high-availability clustering. Businesses can see costs surge in terms of additional hardware and clustering software/support, as well as additional costs and complexities due to increased operational management …

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds