// Expression.cpp: implementation of the CExpression class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Expression.h"
#include "math.h"
const int funTableLen = 17; //函数表长度
double sign(double x);
static double ( * funTable[ ] )( double ) = {
acos, asin, atan,
ceil, cos, cosh, exp,
fabs, floor, log, log10,
sin, sinh, sqrt,
tan, tanh, sign
}; //单参数函数入口地址表
static char funNameTable[ ][6] = {
"acos", "asin", "atan", "ceil", "cos", "cosh", "exp", "fabs",
"floor", "log", "log10", "sin", "sinh", "sqrt", "tan", "tanh", "sign"
}; //函数名表
//////////////////////////////////////////////////////////////////////
// CVar Class
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CVar::CVar()
{
InitVar();
}
CVar::~CVar()
{
}
void CVar::InitVar()
{
m_cFlag=1;
m_strName="";
m_strSlave="";
m_dValue=0;
}
//////////////////////////////////////////////////////////////////////
// CVarList Class
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CVarList::CVarList()
{
}
CVarList::~CVarList()
{
list<CVar*>::iterator iter;
for(iter=m_VarList.begin();iter!=m_VarList.end();iter++)
{
delete (*iter);
}
m_VarList.clear();
}
bool CVarList::AddVar(CVar *pVar)
{
m_VarList.insert(m_VarList.end(),pVar);
return true;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CExpression::CExpression()
{
m_iErrFlag=0;
m_iFunFlag=0;
m_iMatchFlag=0;
m_dResult = 0;
m_bDegUnit=true;
m_strExp=NULL;
strcpy(m_strToken,"");
}
CExpression::~CExpression()
{
}
bool CExpression::CalExp()
{
bool ret;
m_iErrFlag=0;
m_iFunFlag=0;
m_iMatchFlag=0;
m_dResult = 0;
if( strlen(m_strExp)==0)
{
m_iErrFlag = 1;
Error();
return false;
}
UpdateSlaveVar();
//取表达式第一单元(利用m_strExp)
if(GetToken() == true)
{
//进入高优先级运算
ret = Level1(&m_dResult);
//若高级运算出现错误(m_iErrFlag被设置)
if(ret == false)
{
//打印错误信息
Error();
return false;
}
else
return true;
}
//从表达式中取符号错误
m_iErrFlag = 2;
Error();
return false;
}
void CExpression::Error()
{
switch(m_iErrFlag)
{
case 1:
Message( "表达式为空!" );
break;
case 2:
Message( "变量或函数非法或语法错误!\n表达式无法计算!" );
break;
case 3:
Message("括号不匹配!"); //"括号不匹配!"
break;
}
}
void CExpression::Message(const char *strMsg)
{
// printf("\n%s\n",strMsg);
}
bool CExpression::GetToken()
{
register char *temp;
m_cTokenType = 0;
//指针指向token的首地址
temp = m_strToken;
//跳过空格及TAB符
while(IsWhite(*m_strExp) == true)
m_strExp++;
//首字符是为运算符
if(IsInStr(*m_strExp,"+-*/%^=(),") == true)
{
m_cTokenType = DELIMITER;
*temp++ = *m_strExp++;
*temp = 0;
return true;
}
//首字符为ASSCI字符或汉字
else if( isalpha(*m_strExp) || (*m_strExp > 127) || (*m_strExp < 0) )
{
//找到字符串结尾
while(IsDelim(*m_strExp) != true)
*temp ++ = *m_strExp++;
*temp = 0;
if(IsFunc( m_strToken ) )
{
m_cTokenType = FUNCTION;
return true;
}
//搜索变量表,判断取得的符号是否为变量
string sToken = m_strToken;
list<CVar*>::iterator iter;
for(iter=m_VarList.m_VarList.begin();iter!=m_VarList.m_VarList.end();iter++)
{
if((*iter)->m_strName == sToken )
{
m_cTokenType = VARIABLE;
return true;
}
}
return false;
}
//首字符为数字
else if(isdigit(*m_strExp) || *m_strExp == '.')
{
//.5按0.5处理
if(*m_strExp == '.')
*temp++ = '0';
while(IsDelim(*m_strExp) != true)
*temp ++ = *m_strExp++;
*temp = 0;
m_cTokenType = NUMBER;
return true;
}
//首字符为NULL
if(*m_strExp == 0)
{
strcpy(m_strToken,"");
//到达结尾
return true;
}
return false;
}
//判断是否为空格或TAB
bool CExpression::IsWhite(char c)
{
if(c == ' ' || c == 9)
return true;
return false;
}
//判断是否为分隔符
bool CExpression::IsDelim(char c)
{
if(IsInStr(c,"+-*/%^=() ,") == true || c == 9 || c == '\r' || c == 0)
return true;
return false;
}
//判断是否为函数
bool CExpression::IsFunc(const char *fname)
{
int i;
for(i=0;i<funTableLen;i++)
{
if(strcmp(fname,funNameTable[i]) == 0)
return true;
}
return false;
}
//判断C是否在串S中
bool CExpression::IsInStr(char ch,char *s)
{
while(*s)
{
if(*s++ == ch)
return true;
}
return false;
}
double sign(double x)
{
if(x > 0)
return x;
else
return 0;
}
//赋值运算
bool CExpression::Level1(double *result)
{
int index,ttok_type;
char temp_token[80];
//变量单元,有可能是赋值的表达式运算
if(m_cTokenType == VARIABLE)
{
//保留该单元及单元类型
strcpy(temp_token,m_strToken);
ttok_type = m_cTokenType;
//若取不到变量在变量表中的索引值
if(GetVarIndex(m_strToken,&index) != true)
{
m_iErrFlag = 2;
return false;
}
if(GetToken() != true)
{
m_iErrFlag = 2; //m_iErrFlag = 1;
return false;
}
//若变量后紧跟'='号,则为赋值运算,否则为一般运算
if(*m_strToken != '=')
{
//将刚取得的单元回送到表达式中
PutBack();
//恢复当前单元变量及变量类型
strcpy(m_strToken,temp_token);
m_cTokenType = ttok_type;
}
//若为赋值运算进入下面运算
else
{
//取'='号后面的单元
if(GetToken() != true)
{
m_iErrFlag = 2; //m_iErrFlag = 1;
return false;
}
//进入高级的+-运算
if(Level2(result) == true)
{
list<CVar*>::iterator iter;
int i=0;
for(iter=m_VarList.m_VarList.begin();iter!=m_VarList.m_VarList.end();iter++)
{
if(i==index)
{
(*iter)->m_dValue=*result;
return true;
}
i++;
}
}
else
return false;
}
}
//第一单元不是变量,直接进入高优先级+-运算
if(Level2(result) == true)
return true;
else
return false;
}
//加减运算
bool CExpression::Level2(double *result)
{
register char op; //运算符
double hold=0; //保留运算中间结果
//直接进入高优先级的*/%运算,没有高级运算才进入下面运算
if(Level3(result) != true)
return false;
//若下一单元为+-号
while((op = *m_strToken) == '+' || op == '-')
{
//取得+-号后的单元
if(GetToken() == true)
{
//运算+-号后面的表达式值,有可能又取得+-号
if(Level3(&hold) == true)
{
//数学运算,结果直接放在*result中
bool
bRet = Arith(op,result,&hold);
if( bRet == false )
return false;
}
else
return false;
}
else
{
m_iErrFlag = 2; //m_iErrFlag = 1;
return false;
}
}
return true;
}
//乘除及求余数运算
bool CExpression::Level3(double *result)
{
register char op; //运算符
double hold=0; //保留中间运算结果
//直接进入高优先级运算,没有高级运算才进入下面运算
if(Level4(result) != true)
return false;
//若下一单元为*/%
while((op=*m_strToken) == '*' || op == '/' || op == '%')
{
//取得运算符后的单元
if(GetToken() == true)
{
//运算*/%后的表达式值,有可能又获得*/%
if(Level4(&hold) == true)
{
//数学运算,结果放在*result中
bool nRet = Arith(op,result,&hold);
if( nRet == false )
return false;
}
else
return false;
}
else
{
m_iErrFlag = 2; //m_iErrFlag = 1;
return false;
}
}
return true;
}
//乘方运算
bool CExpression::Level4(double *result)
{
register char op; //运算符
double hold=0; //保留中间运算结果
//直接进入高优先级运算,没有高级运算才进入下面运算
if(Level5(result) != true)
return false;
//若下一单元为^(乘方)
while((op=*m_strToken) == '^')
{
if(GetToken() == true)
{
//取得运算符后的单元
if(Level5(&hold) == true)
{
//运算^后的表达式值,有可能又获得^
bool nRet = Arith(op,result,&hold);
if( nRet == false )
return false;
}
else
return false;
}
else
{
m_iErrFlag = 2; //m_iErrFlag = 1;
return false;
}
}
return true;
}
//单目求反运算
bool CExpression::Level5(double *result)
{
register char op = 0;
if((m_cTokenType == DELIMITER) && *m_strToken == '+' || *m_strToken == '-' )
{
//若表达式第一单元为+号或-号,记录该运算符
op = *m_strToken;
//取得下一单元
if(GetToken() != true)
{
m_iErrFlag = 2; //m_iErrFlag = 1;
return false;
}
}
//进入高优先级运算
if(Level6(result) != true)
return false;
//进入高优先级运算
if(op)
Unary(op,result);
return true;
}