www.pudn.com > 组态软件的动画处理.rar > FormelParser.cpp


////////////////////////////////////////////////////////////////////// 
// FormulaParser.cpp: implementation of the CFormulaParser class. 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "math.h" 
#include "rw_gfa.h" 
#include "FormelParser.h" 
 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CFormulaParser::CFormulaParser() 
{	 
	m_strStandardFunction.Add(""); 
	m_strStandardFunction.Add("ABS"); 
	m_strStandardFunction.Add("SQR"); 
	m_strStandardFunction.Add("SINH"); 
	m_strStandardFunction.Add("COSH"); 
	m_strStandardFunction.Add("TANH"); 
	m_strStandardFunction.Add("ARCTAN"); 
	m_strStandardFunction.Add("LN"); 
	m_strStandardFunction.Add("LOG"); 
	m_strStandardFunction.Add("EXP"); 
	m_strStandardFunction.Add("SIN"); 
	m_strStandardFunction.Add("COS"); 
	m_strStandardFunction.Add("TAN"); 
	m_strStandardFunction.Add("ARCSIN"); 
	m_strStandardFunction.Add("ARCCOS"); 
	m_strStandardFunction.Add("INT"); 
	m_strStandardFunction.Add("RAD"); 
	m_strStandardFunction.Add("DEG"); 
	m_strStandardFunction.Add("ARSINH"); 
	m_strStandardFunction.Add("ARCOSH"); 
	m_strStandardFunction.Add("ARTANH"); 
} 
 
CFormulaParser::~CFormulaParser() 
{ 
 
} 
 
////////////////////////////////////////////////////////////////////// 
// Methoden 
////////////////////////////////////////////////////////////////////// 
 
double CFormulaParser::SignFactor(WORD& nPosition, CString& strCharacter) 
{ 
  if (strCharacter == "-") 
	{ 
	  Char_n(nPosition, strCharacter); 
    return (-1.0) * Factor(nPosition, strCharacter); 
	} 
  else return Factor(nPosition, strCharacter); 
} 
 
double CFormulaParser::Calculation(CString strFormula, double xValue, WORD& ErrorPosition, CString& Errortext) 
{ 
  WORD nPosition; 
	CString strCharacter; 
	double	ergebnis; 
	char buffer[32]; 
 
	m_strErrortext.Empty(); 
 
	try 
	{ 
		strFormula.TrimLeft(); 
		strFormula.TrimRight(); 
		m_strFunction = strFormula + strChar_(0); 
		m_dFktValue = xValue; 
		if (m_dFktValue == 0)	 
			m_dFktValue = 1.0E-99; 
		nPosition = 0; 
		Char_n(nPosition, strCharacter); 
		ergebnis = Expression(nPosition, strCharacter); 
		if (strCharacter == strChar_(0)) 
		{ 
			Errortext = m_strErrortext; 
			ErrorPosition = 0; 
		} 
		else 
		{ 
			ErrorPosition = nPosition; 
			sprintf(buffer, "Error an Position %d gefunden", (int) ErrorPosition); 
			Errortext = buffer; 
			Errortext += m_strErrortext; 
			Errortext += "!"; 
		} 
 
		return ergebnis; 
	} 
	catch (CException* ex) 
	{ 
		TCHAR szCause[255];         
		ex->GetErrorMessage(szCause, 255); 
		Errortext = _T("Error in Calculation() weil "); 
		Errortext += szCause;         
		return 0; 
	} 
} 
 
double CFormulaParser::Expression(WORD& nPosition, CString& strCharacter) 
{ 
  CString strOperator; 
  double erg = SimpleExpression(nPosition, strCharacter); 
  while (strCharacter == "+" || strCharacter == "-") 
  { 
    strOperator = strCharacter; 
    Char_n(nPosition, strCharacter); 
    if (strOperator == "+") 
		  erg += SimpleExpression(nPosition, strCharacter); 
		else if (strOperator == "-") 
		  erg -= SimpleExpression(nPosition, strCharacter); 
	} 
  return erg; 
} 
 
double CFormulaParser::SimpleExpression(WORD& nPosition, CString& strCharacter) 
{ 
  double s,dum; 
	CString strOperator; 
  s = Term(nPosition, strCharacter); 
  while (strCharacter == "*" || strCharacter == "/") 
	{ 
    strOperator = strCharacter; 
    Char_n(nPosition, strCharacter); 
    if (strOperator == "*") 
			s = s * Term(nPosition, strCharacter); 
    else if (strOperator == "/")  
		{ 
			dum = Term(nPosition, strCharacter); 
			if (dum != 0)   
				s = s / dum; 
			else 
				m_strErrortext = " (Division durch Null)"; 
		}   
	} 
  return s; 
} 
 
double CFormulaParser::Term(WORD& nPosition, CString& strCharacter) 
{ 
  double t,vz; 
  t = SignFactor(nPosition, strCharacter); 
  while (strCharacter == "^") 
  { 
	  Char_n(nPosition, strCharacter); 
    vz = SignFactor(nPosition, strCharacter); 
     
		if ((t <= 0 && fabs(vz) <= 1) || (t <= 0 && vz != int(vz))) 
			m_strErrortext = " (keine Wurzel aus neg. Zahl)"; 
    else  
			t = pow(t,vz);		 
	} 
  return t; 
} 
 
double CFormulaParser::Char_n(WORD& nPosition, CString& strCharacter) 
{ 
  do 
	{ 
    nPosition ++;	// evtl. nach strCharacter 
		if (nPosition <= m_strFunction.GetLength()) 
			//war ge鋘dert auf:  strCharacter = MID(m_strFunction, nPosition, 1); 
			strCharacter = m_strFunction.Mid(nPosition - 1, 1);			 
		else  
			strCharacter = strChar_(0); 
 
	//	TRACE("strCharacter= "+ strCharacter); 
 	} 
  while (strCharacter == " ");  
 
	return nPosition; 
} 
 
void CFormulaParser::SetFormula(CString Formula) 
{ 
	m_strFormula = Formula; 
} 
 
CString CFormulaParser::GetFormula() 
{ 
	return m_strFormula; 
} 
 
double CFormulaParser::Factor(WORD& nPosition, CString& strCharacter) 
{ 
  double f = 0.0; 
	BOOL erfolg = false; 
	WORD wI=0, wL=0, wBeginn=0, wError=0; 
	wError = 0; 
 
//	if	(strCharacter == strChar_(0)) return 0.0; 
 
	//if ((BYTE) strCharacter[0] >= (BYTE) "0" && (BYTE) strCharacter[0] <= (BYTE) "9" || strCharacter == ".") 
	if (strCharacter >= "0" && strCharacter <= "9" || strCharacter == ".") 
	{ 
		wBeginn = nPosition; 
 
		do 
		{ 
			Char_n(nPosition, strCharacter); 
		}  
		while ((strCharacter >= "0" && strCharacter <= "9" || strCharacter == ".")); 
			// while (!((BYTE) strCharacter[0] >= (BYTE) "0") && ((BYTE) strCharacter[0] <= (BYTE) "9") || (strCharacter == ".")); 
			 
		if (strCharacter == ".") // Abfrage wird nie abgearbeitet 
		{ 
			do 
			{ 
				Char_n(nPosition, strCharacter); 
			}  
			while (!((BYTE)strCharacter[0] >= (BYTE)"0") && ((BYTE)strCharacter[0] <=  (BYTE)"9")  || ((BYTE)strCharacter[0] == (BYTE)".")); 
		} 
		f = atof(m_strFunction.Mid(wBeginn - 1, nPosition - wBeginn )); 
//original aus VB:            f = Val(Mid$(funktion$, beginn%, position% - beginn%)) 
 
	}  
	else 
	{ 
		CString strCharacterUpper = strCharacter; 
		strCharacterUpper.MakeUpper(); 
		if (strCharacter == "(") 
		{ 
			Char_n(nPosition, strCharacter); 
			f = Expression(nPosition, strCharacter); 
			if (strCharacter == ")") 
				Char_n(nPosition, strCharacter); 
		} 
		else if (strCharacterUpper == "X") 
		{ 
			Char_n(nPosition, strCharacter); 
			f = m_dFktValue; 
		} 
		else if (strCharacterUpper == "B") 
		{ 
			Char_n(nPosition, strCharacter); 
			f = m_dFunctionConstant[1]; 
		} 
		else if (strCharacterUpper == "F") 
		{ 
			Char_n(nPosition, strCharacter); 
			f = m_dFunctionConstant[2]; 
		} 
		else if (strCharacterUpper == "G") 
		{ 
			Char_n(nPosition, strCharacter); 
			f = m_dFunctionConstant[3]; 
		} 
		else if (strCharacterUpper == "H") 
		{ 
			Char_n(nPosition, strCharacter); 
			f = m_dFunctionConstant[4]; 
		} 
		else if (strCharacterUpper == "J") 
		{ 
			Char_n(nPosition, strCharacter); 
			f = m_dFunctionConstant[5]; 
		} 
		else if (strCharacterUpper == "K") 
		{ 
			Char_n(nPosition, strCharacter); 
			f = m_dFunctionConstant[6]; 
		} 
		else if (strCharacterUpper == "M") 
		{ 
			Char_n(nPosition, strCharacter); 
			f = m_dFunctionConstant[7]; 
		} 
		else if (strCharacterUpper == "N") 
		{ 
			Char_n(nPosition, strCharacter); 
			f = m_dFunctionConstant[8]; 
		} 
		else if (strCharacterUpper == "U")	 
		{ 
			Char_n(nPosition, strCharacter); 
			f = m_dFunctionConstant[9]; 
		} 
		else if (strCharacterUpper == "V") 
		{ 
			Char_n(nPosition, strCharacter); 
			f = m_dFunctionConstant[10]; 
		} 
		else 
		{ 
			erfolg = false; 
			int AnzStdFunctions = m_strStandardFunction.GetSize() - 1; 
			for (wI = 1; wI <= AnzStdFunctions; wI++) 
			{ 
				if (!erfolg) 
				{  
					wL = m_strStandardFunction[wI].GetLength(); 
					CString strFunktionUpper = m_strFunction.Mid(nPosition - 1, wL); 
					strFunktionUpper.MakeUpper(); 
					if (strFunktionUpper == m_strStandardFunction[wI]) 
					{ 
						nPosition = nPosition + wL - 1; 
						Char_n(nPosition, strCharacter); 
						f = Factor(nPosition, strCharacter); 
						if (strFunktionUpper == "ABS") 
							f = fabs(f); 
						else if (strFunktionUpper == "SQR") 
							if (f >= 0) 
								f = sqrt(f); 
							else 
								wError = -1; 
						else if (strFunktionUpper == "SINH") 
							f = sinh(f); 
						else if (strFunktionUpper == "COSH") 
							f = cosh(f); 
						else if (strFunktionUpper == "TANH") 
							f = tanh(f); 
						else if (strFunktionUpper == "ARCTAN") 
							f = atan(f); 
						else if (strFunktionUpper == "LN") 
						{ 
							if (f >= 0) 
								f = log(f); 
							else 
								wError = -1; 
						} 
						else if (strFunktionUpper == "LOG") 
						{ 
							if (f >= 0) 
								f = log10(f); 
							else 
								wError = -1; 
						} 
						else if (strFunktionUpper == "EXP") 
						{ 
							if (f <= 41) 
								f = exp(f); 
							else 
								wError = -1; 
						} 
						else if (strFunktionUpper == "SIN") 
							f = sin(f); 
						else if (strFunktionUpper == "COS") 
							f = cos(f); 
						else if (strFunktionUpper == "TAN") 
						{ 
							if (cos(f) != 0) 
								f = tan(f); 
							else  
								wError = -1; 
						} 
						else if (strFunktionUpper == "ARCSIN") 
						{ 
							if (fabs(f) < 1)  
								f = asin(f); 
							else 
								wError = -1; 
						} 
						else if (strFunktionUpper == "ARCCOS") 
						{ 
							if (fabs(f) <= 1) 
								f = acos(f); 
							else  
								wError = -1; 
						} 
						else if (strFunktionUpper == "INT")  
							f = int(f); 
						else if (strFunktionUpper == "RAD")  
							f = RAD(f); 
						else if (strFunktionUpper == "DEG")  
							f = DEG(f); 
						else if (strFunktionUpper == "ARSINH")  
							f = arsinh(f); 
						else if (strFunktionUpper == "ARCOSH") 
						{ 
							if (fabs(f) >= 1) 
								f = arcosh(f); 
							else  
								wError = -1; 
						}					 
						else if (strFunktionUpper == "ARTANH") 
						{ 
							if (fabs(f) <= 1) 
								f = artanh(f); 
							else  
								wError = -1; 
						} 
						erfolg = true; 
					} 
				} 
			} 
		} 
	} 
	 
	if (wError == -1)  
		m_strErrortext = " (Ein Error wurde abgefangen)"; 
 
  return f; 
} 
 
void CFormulaParser::SetFunctConst(int index, double val) 
{ 
	if (index >= 1 && index < 10) //zwischen 0 und 9 
		m_dFunctionConstant[index] = val; 
	else 
		AfxMessageBox("ProgrammError in SetFunctConst()"); 
}