Files
envi-code/SourceCode/Code2026/inc/KTExpressCalc.h
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

188 lines
4.9 KiB
C++

#if !defined(__KTEXPRESSCALC_H__)
#define __KTEXPRESSCALC_H__
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifdef AECRXBASE_EXPORT
#define AECDLLIMPEXP __declspec(dllexport)
#else
#define AECDLLIMPEXP __declspec(dllimport)
#endif
#include <afxtempl.h>
typedef CMap<CString, LPCTSTR, double, double> CMapStringToDouble;
typedef BOOL (* lpfnGetVariableProc)(LPCTSTR pszVariable, double& dValue, WPARAM wParam, LPARAM lParam);
class AECDLLIMPEXP KTExpressCalc
{
public:
// 错误码定义
enum EErrorCode
{
eOk = 0, // 没有错误
eVarialbeNotFind , // 变量没有找到
eNullExpress , // 表达式为空
eMissLeftPthis , // 缺少左括号
eMissVariable , // 缺少操作数
eMissOperator , // 缺少操作符
eMissIf , // 缺少if
eMissThen , // 缺少then
eMissElse , // 缺少else
eInvalidOperator , // 错误的操作符
eInvalidVariable , // 错误的操作数
eOutOfBound , // 计算值溢出
};
// 元素类型定义
enum EEleType
{
eEleUnknown = 0, // 未定义
eEleConstant , // 数值
eEleVariable , // 变量
eEleOperate , // 操作符
};
// 操作类型定义
enum EOpeType
{
eOpeUnknown = 0, // 未定义
eOpeLeftPthis , // 左括号 (
eOpeRightPthis , // 右括号 )
eOpeIf , // 分支 IF
eOpeThen , // 分支 THEN
eOpeElse , // 分支 ELSE
eOpeOr , // 逻辑或 OR
eOpeXor , // 逻辑异或 XOR
eOpeAnd , // 逻辑与 AND
eOpeNot , // 逻辑非 NOT
eOpeGreatThan , // 大于 >
eOpeLessThan , // 小于 <
eOpeEqual , // 等于 =
eOpeGreatEqual , // 大于等于 >=
eOpeLessEqual , // 小于等于 <=
eOpeNotEqual , // 不等于 !=
eOpeAdd , // 加法 +
eOpeSubtract , // 减法 -
eOpeMultiply , // 乘法 *
eOpeDivide , // 除法 /
eOpeRemainder , // 求余 %
eOpePower , // 乘方 ^
eOpeFactorial , // 阶乘 !
eOpeFunction , // 函数 sin(x), ...
};
// 优先级定义,由小到大(由低到高)
enum EPriType
{
ePriUnknown = 0, // 未定义
ePriRightPthis , // 右括号 )
ePriIfElse , // 分支 IF...THEN...ELSE...
ePriOr , // 逻辑或 OR XOR
ePriAnd , // 逻辑与 AND
ePriNot , // 逻辑非 NOT
ePriCompare , // 比较 > < = >= <= !=
ePriSum , // 求和 + -
ePriMultiple , // 求积 * / %
ePriPower , // 乘方 ^
ePriFunction , // 函数 sin(x), ...
ePriFactorial , // 阶乘 !
ePriLeftPthis , // 左括号 (
};
class CElement
{
public:
struct COperator
{
LPCTSTR m_pszOperate; // 操作符
EOpeType m_eOpeType; // 操作符类型
EPriType m_ePriType; // 优先级类型
int m_iEleNum; // 操作数个数
void* m_pfnCalc; // 操作函数
};
CElement();
CElement(const CElement& cEle);
virtual ~CElement();
void Clear();
CElement& operator=(const CElement& cEle);
BOOL SetElement(CString sElement, BOOL bContant);
EEleType m_eEleType; // 元素类型
union
{
COperator m_cOperate; // 操作符
LPTSTR m_pszVariable; // 变量
double m_dValue; // 数值
};
};
typedef CList<CElement, CElement&> CListElement;
KTExpressCalc();
virtual ~KTExpressCalc();
// 计算表达式
BOOL Calculate(LPCTSTR pszExpress, double& dResult);
// 设置变量数据
void SetVariableData(LPCTSTR pszVariable, double dValue);
// 取得变量数据
BOOL GetVariableData(LPCTSTR pszVariable, double& dValue) const;
// 设置变量数据,当传入为NULL时,清除变量数据
void SetVariableData(const CMapStringToDouble* pMapVariable);
// 设置取变量值回调函数,当传入为NULL时,清除回调函数
void SetVariableProc(lpfnGetVariableProc pfnProc, WPARAM wParam, LPARAM lParam);
// 取得错误代码
KTExpressCalc::EErrorCode GetErrorCode();
protected:
// 创建元素列表
BOOL OnCreateElementList(CString sExpress, CListElement& lstElement);
// 计算元素列表
BOOL OnCalcElementList(CListElement& lstElement, double& dResult);
// 根据条件去除if-then-else分支中的一条
BOOL OnCutOneOfIfThenElse(CListElement& lstElement, BOOL bElse);
// 判断是否后面的运算符比给定的优先级高
BOOL OnNextPriTypeIsHigherThis(CListElement& lstElement, CElement& cEleOpe);
// 弹出尾部操作符
BOOL OnPopTailOperator(CListElement& lstElement, CElement& cEleOpe);
// 弹出头部操作数
BOOL OnPopHeadVariable(CListElement& lstElement, CElement& cEleVar);
// 弹出尾部操作数
BOOL OnPopTailVariable(CListElement& lstElement, CElement& cEleVar);
// 取得元素值
BOOL OnGetElementValue(CElement& cEleVar, double& dValue);
// 取得变量值
virtual BOOL OnGetVariable(LPCTSTR pszVariable, double& dValue);
// 变量数据
CMapStringToDouble m_mapVariable;
// 取变量值回调函数
lpfnGetVariableProc m_pfnGetVariable;
// 回调函数用户参数
WPARAM m_wParam;
LPARAM m_lParam;
// 错误代码
KTExpressCalc::EErrorCode m_eErrorCode;
};
#endif // !defined(__KTEXPRESSCALC_H__)