表達式求值(中)

 

// 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 == '.')

    {

              //.50.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;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章