// Expression.cpp: implementation of the CExpression class.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
//
//////////////////////////////////////////////////////////////////////
#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;
}