Files
envi-code/SourceCode/Code2026/AecRxBase/KTExpressCalc.cpp
T
2026-09-28 15:28:50 +08:00

1009 lines
26 KiB
C++

#include "stdafx.h"
#include <math.h>
#include <float.h>
#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;
}