#include "stdafx.h" #include #include #include "KTExpressCalc.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #define EPS 1.0e-10 #ifndef _ttof #ifdef _UNICODE #define _ttof(s) wcstod(s, NULL) #else #define _ttof(s) strtod(s, NULL) #endif // _UNICODE #endif // _ttof typedef double (* lpfnCalcFun1)(double); typedef double (* lpfnCalcFun2)(double, double); static double _or(double dX1, double dX2) { return (fabs(dX1) > EPS || fabs(dX2) > EPS); } static double _xor(double dX1, double dX2) { return (((fabs(dX1) > EPS ? 1 : -1) * (fabs(dX2) > EPS ? 1 : -1) < 0) ? 1 : 0); } static double _and(double dX1, double dX2) { return (fabs(dX1) > EPS && fabs(dX2) > EPS); } static double _not(double dX) { return (fabs(dX) < EPS); } static double greatthan(double dX1, double dX2) { return (dX1 > dX2); } static double lessthan(double dX1, double dX2) { return (dX1 < dX2); } static double equal(double dX1, double dX2) { return (fabs(dX1 - dX2) < EPS); } static double greatequal(double dX1, double dX2){ return (dX1 >= dX2); } static double lessequal(double dX1, double dX2) { return (dX1 <= dX2); } static double notequal(double dX1, double dX2) { return (fabs(dX1 - dX2) > EPS); } static double add(double dX1, double dX2) { return (dX1 + dX2); } static double subtract(double dX1, double dX2) { return (dX1 - dX2); } static double multiple(double dX1, double dX2) { return (dX1 * dX2); } static double divide(double dX1, double dX2) { return (dX1 / dX2); } static double integer(double dX) { return (long(dX)); } static double cot(double dX) { return (1.0 / tan(dX)); } static double factorial(double dX) { return dX;} static double f_mod(double dX1, double dX2) { return fmod(dX1, dX2);} static double f_pow(double dX1, double dX2) { return pow(dX1, dX2);} static double f_abs(double dX) { return fabs(dX); } static double f_sqrt(double dX) { return sqrt(dX); } static double f_exp(double dX) { return exp(dX); } static double f_log(double dX) { return log(dX); } static double f_log10(double dX) { return log10(dX); } static double f_sin(double dX) { return sin(dX); } static double f_cos(double dX) { return cos(dX); } static double f_tan(double dX) { return tan(dX); } static double f_cot(double dX) { return cot(dX); } static double f_asin(double dX) { return asin(dX); } static double f_acos(double dX) { return acos(dX); } static double f_atan(double dX) { return atan(dX); } static double f_sinh(double dX) { return sinh(dX); } static double f_cosh(double dX) { return cosh(dX); } static double f_tanh(double dX) { return tanh(dX); } static KTExpressCalc::CElement::COperator g_pOperator[] = { {_T("("), KTExpressCalc::eOpeLeftPthis, KTExpressCalc::ePriLeftPthis, 0, NULL}, {_T(")"), KTExpressCalc::eOpeRightPthis, KTExpressCalc::ePriRightPthis,0, NULL}, {_T("IF"), KTExpressCalc::eOpeIf, KTExpressCalc::ePriIfElse, 0, NULL}, {_T("THEN"), KTExpressCalc::eOpeThen, KTExpressCalc::ePriIfElse, 0, NULL}, {_T("ELSE"), KTExpressCalc::eOpeElse, KTExpressCalc::ePriIfElse, 0, NULL}, {_T("OR"), KTExpressCalc::eOpeOr, KTExpressCalc::ePriOr, 2, _or}, {_T("XOR"), KTExpressCalc::eOpeXor, KTExpressCalc::ePriOr, 2, _xor}, {_T("AND"), KTExpressCalc::eOpeAnd, KTExpressCalc::ePriAnd, 2, _and}, {_T("NOT"), KTExpressCalc::eOpeNot, KTExpressCalc::ePriNot, 1, _not}, {_T(">"), KTExpressCalc::eOpeGreatThan, KTExpressCalc::ePriCompare, 2, greatthan}, {_T("<"), KTExpressCalc::eOpeLessThan, KTExpressCalc::ePriCompare, 2, lessthan}, {_T("="), KTExpressCalc::eOpeEqual, KTExpressCalc::ePriCompare, 2, equal}, {_T(">="), KTExpressCalc::eOpeGreatEqual, KTExpressCalc::ePriCompare, 2, greatequal}, {_T("<="), KTExpressCalc::eOpeLessEqual, KTExpressCalc::ePriCompare, 2, lessequal}, {_T("!="), KTExpressCalc::eOpeNotEqual, KTExpressCalc::ePriCompare, 2, notequal}, {_T("+"), KTExpressCalc::eOpeAdd, KTExpressCalc::ePriSum, 2, add}, {_T("-"), KTExpressCalc::eOpeSubtract, KTExpressCalc::ePriSum, 2, subtract}, {_T("*"), KTExpressCalc::eOpeMultiply, KTExpressCalc::ePriMultiple, 2, multiple}, {_T("/"), KTExpressCalc::eOpeDivide, KTExpressCalc::ePriMultiple, 2, divide}, {_T("%"), KTExpressCalc::eOpeRemainder, KTExpressCalc::ePriMultiple, 2, f_mod}, {_T("^"), KTExpressCalc::eOpePower, KTExpressCalc::ePriPower, 2, f_pow}, {_T("!"), KTExpressCalc::eOpeFactorial, KTExpressCalc::ePriFactorial, -1, factorial}, {_T("int"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, integer}, {_T("abs"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_abs}, {_T("sqrt"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_sqrt}, {_T("exp"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_exp}, {_T("ln"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_log}, {_T("log"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_log10}, {_T("sin"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_sin}, {_T("cos"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_cos}, {_T("tan"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_tan}, {_T("cot"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_cot}, {_T("asin"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_asin}, {_T("acos"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_acos}, {_T("atan"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_atan}, {_T("sinh"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_sinh}, {_T("cosh"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_cosh}, {_T("tanh"), KTExpressCalc::eOpeFunction, KTExpressCalc::ePriFunction, 1, f_tanh}, }; KTExpressCalc::CElement::CElement() { m_eEleType = KTExpressCalc::eEleUnknown; m_cOperate.m_pszOperate = NULL; m_cOperate.m_eOpeType = KTExpressCalc::eOpeUnknown; m_cOperate.m_ePriType = KTExpressCalc::ePriUnknown; m_cOperate.m_iEleNum = 0; m_cOperate.m_pfnCalc = NULL; m_pszVariable = NULL; m_dValue = 0.0; } KTExpressCalc::CElement::CElement(const KTExpressCalc::CElement& cEle) { m_eEleType = KTExpressCalc::eEleUnknown; m_cOperate.m_pszOperate = NULL; m_cOperate.m_eOpeType = KTExpressCalc::eOpeUnknown; m_cOperate.m_ePriType = KTExpressCalc::ePriUnknown; m_cOperate.m_iEleNum = 0; m_cOperate.m_pfnCalc = NULL; m_pszVariable = NULL; m_dValue = 0.0; (*this) = cEle; } KTExpressCalc::CElement::~CElement() { Clear(); } void KTExpressCalc::CElement::Clear() { if (m_eEleType == KTExpressCalc::eEleVariable && m_pszVariable != NULL) { delete [] m_pszVariable; m_pszVariable = NULL; } m_eEleType = KTExpressCalc::eEleUnknown; m_cOperate.m_pszOperate = NULL; m_cOperate.m_eOpeType = KTExpressCalc::eOpeUnknown; m_cOperate.m_ePriType = KTExpressCalc::ePriUnknown; m_cOperate.m_iEleNum = 0; m_cOperate.m_pfnCalc = NULL; m_dValue = 0.0; } KTExpressCalc::CElement& KTExpressCalc::CElement::operator=(const KTExpressCalc::CElement& cEle) { Clear(); m_eEleType = cEle.m_eEleType; switch (m_eEleType) { case KTExpressCalc::eEleConstant: // 数值 m_dValue = cEle.m_dValue; break; case KTExpressCalc::eEleVariable: // 变量 m_pszVariable = _tcsdup(cEle.m_pszVariable); break; case KTExpressCalc::eEleOperate: // 操作符 CopyMemory(&m_cOperate, &(cEle.m_cOperate), sizeof(COperator)); break; } return (*this); } BOOL KTExpressCalc::CElement::SetElement(CString sElement, BOOL bConstant) { Clear(); // 常数 if (bConstant) { m_eEleType = KTExpressCalc::eEleConstant; int iFind = sElement.Find(_T('e')) + 1; if (iFind > 0 || (iFind = sElement.Find(_T('E')) + 1) > 0) m_dValue = _ttof(sElement.Left(iFind)) * pow(10.0, _ttof(sElement.Mid(iFind))); else m_dValue = _ttof(sElement); return TRUE; } // 函数 int iSize = sizeof(g_pOperator) / sizeof(COperator); for (int i = 0; i < iSize; i++) { if (sElement.CompareNoCase(g_pOperator[i].m_pszOperate) == 0) { m_eEleType = KTExpressCalc::eEleOperate; CopyMemory(&m_cOperate, &(g_pOperator[i]), sizeof(COperator)); return TRUE; } } // 变量 m_eEleType = KTExpressCalc::eEleVariable; m_pszVariable = _tcsdup(sElement); return TRUE; } ///////////////////////////////////////////////////////////////// KTExpressCalc::KTExpressCalc() { m_pfnGetVariable = NULL; m_wParam = 0; m_lParam = 0l; m_eErrorCode = KTExpressCalc::eOk; } KTExpressCalc::~KTExpressCalc() { } // 计算表达式 BOOL KTExpressCalc::Calculate(LPCTSTR pszExpress, double& dResult) { dResult = 0.0; m_eErrorCode = KTExpressCalc::eOk; CListElement lstElement; OnCreateElementList(pszExpress, lstElement); if (lstElement.IsEmpty()) m_eErrorCode = KTExpressCalc::eNullExpress; if (m_eErrorCode != KTExpressCalc::eOk) return FALSE; OnCalcElementList(lstElement, dResult); if (m_eErrorCode != KTExpressCalc::eOk) return FALSE; return TRUE; } // 创建元素列表 BOOL KTExpressCalc::OnCreateElementList(CString sExpress, CListElement& lstElement) { CElement cElement; int i = 0, iStart; int iLen = sExpress.GetLength(); TCHAR ch; CString sVariable; BOOL bExp, bSign, bPoint, bDigit; while (i < iLen) { iStart = i; bExp = FALSE; bSign = FALSE; bPoint = FALSE; bDigit = FALSE; ch = sExpress[i++]; // 去除空格 if (ch == _T(' ')) continue; // 判断是否是数字 if (_istdigit(ch) || (bPoint = (ch == _T('.')))) { for (; i < iLen; i++) { ch = sExpress[i]; if (_istdigit(ch)) { bDigit = TRUE; continue; } if (bExp) { if (!bPoint && (bPoint = (ch == _T('.')))) continue; if (!bDigit && !bPoint && !bSign && (bSign = (ch == _T('+') || ch == _T('-'))) && i+1 < iLen && _istdigit(sExpress[i+1])) continue; } else { if (!bPoint && (bPoint = (ch == _T('.')))) continue; if ((bExp = (ch == _T('e') || ch == _T('E')))) { bSign = FALSE; bPoint = FALSE; bDigit = FALSE; continue; } } break; } cElement.SetElement(sExpress.Mid(iStart, i-iStart), TRUE); lstElement.AddTail(cElement); continue; } // 判断是否是括号 if (ch == _T('(') || ch == _T(')')) { cElement.SetElement(ch, FALSE); lstElement.AddTail(cElement); continue; } // 判断是否是符号 if (_istprint(ch) && !_istalnum(ch)) { for (; i < iLen; i++) { ch = sExpress[i]; if (_istprint(ch) && !_istalnum(ch) && ch != _T(' ') && ch != _T('.') && ch != _T('(') && ch != _T(')')) continue; break; } cElement.SetElement(sExpress.Mid(iStart, i-iStart), FALSE); lstElement.AddTail(cElement); continue; } // 判断是否为汉字 if (!_istprint(ch) && i < iLen) i++; // 判断是否是字母字串 for (; i < iLen; i++) { ch = sExpress[i]; if (_istalnum(ch) || ch == _T('_')) continue; if (!_istprint(ch) && i+1 < iLen) { i++; continue; } break; } sVariable = sExpress.Mid(iStart, i-iStart); if (sVariable.CompareNoCase(_T("ELSEIF")) == 0) { cElement.SetElement(_T("ELSE"), FALSE); lstElement.AddTail(cElement); sVariable = _T("IF"); } cElement.SetElement(sVariable, FALSE); lstElement.AddTail(cElement); } return TRUE; } // 计算元素列表 BOOL KTExpressCalc::OnCalcElementList(CListElement& lstElement, double& dResult) { CListElement lstStack; double dValue1, dValue2; CElement cElement, cEleVar, cEleOpe; while (!lstElement.IsEmpty()) { cElement = lstElement.RemoveHead(); // 操作符 if (cElement.m_eEleType == KTExpressCalc::eEleOperate) { switch (cElement.m_cOperate.m_eOpeType) { case KTExpressCalc::eOpeLeftPthis: // 左括号 (... // 压栈 lstStack.AddTail(cElement); continue; case KTExpressCalc::eOpeRightPthis: // 右括号 ) // 取出操作数 if (!OnPopTailVariable(lstStack, cEleVar)) return FALSE; // 取出操作符 if (!OnPopTailOperator(lstStack, cEleOpe)) return FALSE; // 如果不是左括号 while (cEleOpe.m_cOperate.m_eOpeType != KTExpressCalc::eOpeLeftPthis) { // 取出变量值 if (!OnGetElementValue(cEleVar, dValue2)) return FALSE; // 是否是单目运算 switch (cEleOpe.m_cOperate.m_iEleNum) { case 1: // 计算 dValue2 = ((lpfnCalcFun1)(cEleOpe.m_cOperate.m_pfnCalc))(dValue2); if (!_finite(dValue2)) { m_eErrorCode = KTExpressCalc::eOutOfBound; dValue2 = 0.0; return FALSE; } break; case 2: // 取出操作数 if (!OnPopTailVariable(lstStack, cEleVar)) { if (cEleOpe.m_cOperate.m_eOpeType == KTExpressCalc::eOpeAdd || cEleOpe.m_cOperate.m_eOpeType == KTExpressCalc::eOpeSubtract) { cEleVar.Clear(); cEleVar.m_eEleType = KTExpressCalc::eEleConstant; cEleVar.m_dValue = 0.0; m_eErrorCode = KTExpressCalc::eOk; } else return FALSE; } // 取出变量值 if (!OnGetElementValue(cEleVar, dValue1)) return FALSE; // 计算 dValue2 = ((lpfnCalcFun2)(cEleOpe.m_cOperate.m_pfnCalc))(dValue1, dValue2); if (!_finite(dValue2)) { m_eErrorCode = KTExpressCalc::eOutOfBound; dValue2 = 0.0; return FALSE; } break; default: m_eErrorCode = KTExpressCalc::eMissOperator; return FALSE; } // 构造操作数 cEleVar.Clear(); cEleVar.m_eEleType = KTExpressCalc::eEleConstant; cEleVar.m_dValue = dValue2; // 取出操作符 if (!OnPopTailOperator(lstStack, cEleOpe)) return FALSE; } // 操作数压栈 lstElement.AddHead(cEleVar); // 栈为空 if (lstStack.IsEmpty()) continue; // 取出操作符 if (!OnPopTailOperator(lstStack, cElement)) return FALSE; // (, if if (cElement.m_cOperate.m_eOpeType == KTExpressCalc::eOpeLeftPthis || cElement.m_cOperate.m_eOpeType == KTExpressCalc::eOpeIf) { // 压回栈 lstStack.AddTail(cElement); continue; } break; case KTExpressCalc::eOpeIf: // if... // 压栈 lstStack.AddTail(cElement); continue; case KTExpressCalc::eOpeThen: // then... // 取出操作数 if (!OnPopTailVariable(lstStack, cEleVar)) return FALSE; // 取出操作符 if (!OnPopTailOperator(lstStack, cEleOpe)) return FALSE; // 如果不是if,则必定是单目运算 while (cEleOpe.m_cOperate.m_eOpeType != KTExpressCalc::eOpeIf) { // 取出变量值 if (!OnGetElementValue(cEleVar, dValue2)) return FALSE; // 是否是单目运算 switch (cEleOpe.m_cOperate.m_iEleNum) { case 1: // 计算 dValue2 = ((lpfnCalcFun1)(cEleOpe.m_cOperate.m_pfnCalc))(dValue2); if (!_finite(dValue2)) { m_eErrorCode = KTExpressCalc::eOutOfBound; dValue2 = 0.0; return FALSE; } break; case 2: // 取出操作数 if (!OnPopTailVariable(lstStack, cEleVar)) { if (cEleOpe.m_cOperate.m_eOpeType == KTExpressCalc::eOpeAdd || cEleOpe.m_cOperate.m_eOpeType == KTExpressCalc::eOpeSubtract) { cEleVar.Clear(); cEleVar.m_eEleType = KTExpressCalc::eEleConstant; cEleVar.m_dValue = 0.0; m_eErrorCode = KTExpressCalc::eOk; } else return FALSE; } // 取出变量值 if (!OnGetElementValue(cEleVar, dValue1)) return FALSE; // 计算 dValue2 = ((lpfnCalcFun2)(cEleOpe.m_cOperate.m_pfnCalc))(0.0, dValue2); if (!_finite(dValue2)) { m_eErrorCode = KTExpressCalc::eOutOfBound; dValue2 = 0.0; return FALSE; } break; default: m_eErrorCode = KTExpressCalc::eMissOperator; return FALSE; } // 构造操作数 cEleVar.Clear(); cEleVar.m_eEleType = KTExpressCalc::eEleConstant; cEleVar.m_dValue = dValue2; // 取出操作符 if (!OnPopTailOperator(lstStack, cEleOpe)) return FALSE; } // 分支判断,去除不执行的分支 if (!OnGetElementValue(cEleVar, dValue1) || !OnCutOneOfIfThenElse(lstElement, fabs(dValue1) < EPS)) return FALSE; // 栈为空 if (lstStack.IsEmpty()) continue; // 取出操作符 if (!OnPopTailOperator(lstStack, cElement)) return FALSE; // (, if if (cElement.m_cOperate.m_eOpeType == KTExpressCalc::eOpeLeftPthis || cElement.m_cOperate.m_eOpeType == KTExpressCalc::eOpeIf) { // 压回栈 lstStack.AddTail(cElement); continue; } break; case KTExpressCalc::eOpeElse: // else... m_eErrorCode = KTExpressCalc::eMissThen; return FALSE; } cEleOpe = cElement; while (!lstElement.IsEmpty()) { // 将后面运算符比当前优先级还高的运算符压栈 if (OnNextPriTypeIsHigherThis(lstElement, cEleOpe)) { lstStack.AddTail(cEleOpe); break; } // 其他操作符运算,碰到( if 即结束 switch (cEleOpe.m_cOperate.m_iEleNum) { case -1: // 取出操作数 if (!OnPopTailVariable(lstStack, cEleVar)) return FALSE; // 取出变量值 if (!OnGetElementValue(cEleVar, dValue2)) return FALSE; // 计算 dValue2 = ((lpfnCalcFun1)(cEleOpe.m_cOperate.m_pfnCalc))(dValue2); if (!_finite(dValue2)) { m_eErrorCode = KTExpressCalc::eOutOfBound; dValue2 = 0.0; return FALSE; } break; case 1: // 取出操作数 if (!OnPopHeadVariable(lstElement, cEleVar)) return FALSE; // 取出变量值 if (!OnGetElementValue(cEleVar, dValue2)) return FALSE; // 计算 dValue2 = ((lpfnCalcFun1)(cEleOpe.m_cOperate.m_pfnCalc))(dValue2); if (!_finite(dValue2)) { m_eErrorCode = KTExpressCalc::eOutOfBound; dValue2 = 0.0; return FALSE; } break; case 2: // 取出第2个操作数 if (!OnPopHeadVariable(lstElement, cEleVar)) return FALSE; // 取出变量值 if (!OnGetElementValue(cEleVar, dValue2)) return FALSE; // 取出第1个操作数 if (!OnPopTailVariable(lstStack, cEleVar)) { if (cEleOpe.m_cOperate.m_eOpeType == KTExpressCalc::eOpeAdd || cEleOpe.m_cOperate.m_eOpeType == KTExpressCalc::eOpeSubtract) { cEleVar.Clear(); cEleVar.m_eEleType = KTExpressCalc::eEleConstant; cEleVar.m_dValue = 0.0; m_eErrorCode = KTExpressCalc::eOk; } else return FALSE; } // 取出变量值 if (!OnGetElementValue(cEleVar, dValue1)) return FALSE; // 计算 dValue2 = ((lpfnCalcFun2)(cEleOpe.m_cOperate.m_pfnCalc))(dValue1, dValue2); if (!_finite(dValue2)) { m_eErrorCode = KTExpressCalc::eOutOfBound; dValue2 = 0.0; return FALSE; } break; default: m_eErrorCode = KTExpressCalc::eInvalidOperator; return FALSE; } // 压回栈中 cElement.Clear(); cElement.m_eEleType = KTExpressCalc::eEleConstant; cElement.m_dValue = dValue2; lstElement.AddHead(cElement); if (lstStack.IsEmpty()) break; // 取出栈中元素 cElement = lstStack.GetTail(); // 是否是操作符 if (cElement.m_eEleType != KTExpressCalc::eEleOperate) { m_eErrorCode = KTExpressCalc::eMissOperator; return FALSE; } // 如果是if和( if (cElement.m_cOperate.m_eOpeType == KTExpressCalc::eOpeIf || cElement.m_cOperate.m_eOpeType == KTExpressCalc::eOpeLeftPthis) break; cEleOpe = lstStack.RemoveTail(); } continue; } // 判断是否有操作符 if (!lstStack.IsEmpty() && lstStack.GetTail().m_eEleType != KTExpressCalc::eEleOperate) { m_eErrorCode = KTExpressCalc::eMissOperator; return FALSE; } lstStack.AddTail(cElement); } // 取出操作数 if (!OnPopTailVariable(lstStack, cEleVar)) return FALSE; // 如果栈中有多项 while (!lstStack.IsEmpty()) { // 取出操作符 if (!OnPopTailOperator(lstStack, cEleOpe)) return FALSE; // 取出变量值 if (!OnGetElementValue(cEleVar, dValue2)) return FALSE; // 是否是单目运算 switch (cEleOpe.m_cOperate.m_iEleNum) { case 1: // 计算 dValue2 = ((lpfnCalcFun1)(cEleOpe.m_cOperate.m_pfnCalc))(dValue2); if (!_finite(dValue2)) { m_eErrorCode = KTExpressCalc::eOutOfBound; dValue2 = 0.0; return FALSE; } break; case 2: // 取出操作数 if (!OnPopTailVariable(lstStack, cEleVar)) { if (cEleOpe.m_cOperate.m_eOpeType == KTExpressCalc::eOpeAdd || cEleOpe.m_cOperate.m_eOpeType == KTExpressCalc::eOpeSubtract) { cEleVar.Clear(); cEleVar.m_eEleType = KTExpressCalc::eEleConstant; cEleVar.m_dValue = 0.0; m_eErrorCode = KTExpressCalc::eOk; } else return FALSE; } // 取出变量值 if (!OnGetElementValue(cEleVar, dValue1)) return FALSE; // 计算 dValue2 = ((lpfnCalcFun2)(cEleOpe.m_cOperate.m_pfnCalc))(dValue1, dValue2); if (!_finite(dValue2)) { m_eErrorCode = KTExpressCalc::eOutOfBound; dValue2 = 0.0; return FALSE; } break; default: m_eErrorCode = KTExpressCalc::eMissOperator; return FALSE; } // 构造操作数 cEleVar.Clear(); cEleVar.m_eEleType = KTExpressCalc::eEleConstant; cEleVar.m_dValue = dValue2; } // 取出变量值 if (!OnGetElementValue(cEleVar, dResult)) return FALSE; return TRUE; } // 弹出尾部操作符 BOOL KTExpressCalc::OnPopTailOperator(CListElement& lstElement, CElement& cEleOpe) { // 是否为空 if (lstElement.IsEmpty()) { m_eErrorCode = KTExpressCalc::eMissOperator; return FALSE; } // 弹出操作符 cEleOpe = lstElement.RemoveTail(); // 判断操作符是否合法 if (cEleOpe.m_eEleType == KTExpressCalc::eEleOperate) return TRUE; // 压回栈 lstElement.AddTail(cEleOpe); m_eErrorCode = KTExpressCalc::eMissOperator; return FALSE; } // 弹出头部操作数 BOOL KTExpressCalc::OnPopHeadVariable(CListElement& lstElement, CElement& cEleVar) { // 是否为空 if (lstElement.IsEmpty()) { m_eErrorCode = KTExpressCalc::eMissVariable; return FALSE; } // 弹出操作数 cEleVar = lstElement.RemoveHead(); // 判断操作数是否合法 if (cEleVar.m_eEleType == KTExpressCalc::eEleConstant || cEleVar.m_eEleType == KTExpressCalc::eEleVariable) return TRUE; // 压回栈 lstElement.AddHead(cEleVar); m_eErrorCode = KTExpressCalc::eMissVariable; return FALSE; } // 弹出尾部操作数 BOOL KTExpressCalc::OnPopTailVariable(CListElement& lstElement, CElement& cEleVar) { // 是否为空 if (lstElement.IsEmpty()) { m_eErrorCode = KTExpressCalc::eMissVariable; return FALSE; } // 弹出操作数 cEleVar = lstElement.RemoveTail(); // 判断操作数是否合法 if (cEleVar.m_eEleType == KTExpressCalc::eEleConstant || cEleVar.m_eEleType == KTExpressCalc::eEleVariable) return TRUE; // 压回栈 lstElement.AddTail(cEleVar); m_eErrorCode = KTExpressCalc::eMissVariable; return FALSE; } // 取得元素值 BOOL KTExpressCalc::OnGetElementValue(CElement& cEleVar, double& dValue) { if (cEleVar.m_eEleType == KTExpressCalc::eEleConstant) { dValue = cEleVar.m_dValue; return TRUE; } if (cEleVar.m_eEleType == KTExpressCalc::eEleVariable && OnGetVariable(cEleVar.m_pszVariable, dValue)) return TRUE; m_eErrorCode = KTExpressCalc::eInvalidVariable; return FALSE; } // 根据条件去除if-then-else分支中的一条 BOOL KTExpressCalc::OnCutOneOfIfThenElse(CListElement& lstElement, BOOL bElse) { int iStack = 1; CElement cElement; POSITION posBak = NULL; POSITION pos = lstElement.GetHeadPosition(); while (pos != NULL) { posBak = pos; cElement = lstElement.GetNext(pos); if (cElement.m_eEleType == KTExpressCalc::eEleOperate) { // 嵌套if if (cElement.m_cOperate.m_eOpeType == KTExpressCalc::eOpeIf) iStack++; else if (cElement.m_cOperate.m_eOpeType == KTExpressCalc::eOpeElse) { iStack--; if (iStack == 0) pos = NULL; } } if (bElse) lstElement.RemoveAt(posBak); } if (iStack > 0) { m_eErrorCode = KTExpressCalc::eMissElse; return FALSE; } if (bElse) return TRUE; iStack = 1; pos = posBak; while (pos != NULL) { posBak = pos; cElement = lstElement.GetNext(pos); if (cElement.m_eEleType == KTExpressCalc::eEleOperate) { // 嵌套( if (cElement.m_cOperate.m_eOpeType == KTExpressCalc::eOpeLeftPthis) iStack++; else if (cElement.m_cOperate.m_eOpeType == KTExpressCalc::eOpeRightPthis) { iStack--; if (iStack == 0) break; } } lstElement.RemoveAt(posBak); } return TRUE; } // 判断是否后面的运算符比给定的优先级高 BOOL KTExpressCalc::OnNextPriTypeIsHigherThis(CListElement& lstElement, CElement& cEleOpe) { CElement cElement; POSITION pos = lstElement.GetHeadPosition(); while (pos != NULL) { cElement = lstElement.GetNext(pos); if (cElement.m_eEleType == KTExpressCalc::eEleOperate) { if (cElement.m_cOperate.m_ePriType > cEleOpe.m_cOperate.m_ePriType) return TRUE; else return FALSE; } } return FALSE; } // 设置变量数据 void KTExpressCalc::SetVariableData(LPCTSTR pszVariable, double dValue) { ASSERT(pszVariable != NULL && _tcslen(pszVariable) > 0); m_mapVariable.SetAt(pszVariable, dValue); } // 取得变量数据 BOOL KTExpressCalc::GetVariableData(LPCTSTR pszVariable, double& dValue) const { ASSERT(pszVariable != NULL && _tcslen(pszVariable) > 0); return m_mapVariable.Lookup(pszVariable, dValue); } // 设置变量数据,当传入为NULL时,清除变量数据 void KTExpressCalc::SetVariableData(const CMapStringToDouble* pMapVariable) { if (pMapVariable == NULL) { m_mapVariable.RemoveAll(); } else { double dValue; CString sVariable; POSITION pos = pMapVariable->GetStartPosition(); while (pos != NULL) { pMapVariable->GetNextAssoc(pos, sVariable, dValue); m_mapVariable.SetAt(sVariable, dValue); } } } // 设置取变量值回调函数,当传入为NULL时,清除回调函数 void KTExpressCalc::SetVariableProc(lpfnGetVariableProc pfnProc, WPARAM wParam, LPARAM lParam) { m_pfnGetVariable = pfnProc; m_wParam = wParam; m_lParam = lParam; } // 取得变量值 BOOL KTExpressCalc::OnGetVariable(LPCTSTR pszVariable, double& dValue) { if (m_mapVariable.Lookup(pszVariable, dValue)) return TRUE; if (m_pfnGetVariable != NULL && m_pfnGetVariable(pszVariable, dValue, m_wParam, m_lParam)) return TRUE; m_eErrorCode = KTExpressCalc::eVarialbeNotFind; return FALSE; } // 取得错误代码 KTExpressCalc::EErrorCode KTExpressCalc::GetErrorCode() { return m_eErrorCode; }