⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmcalcexpressionanalyzer.cpp

📁 TOOL (Tiny Object Oriented Language) is an easily-embedded, object-oriented, C++-like-language inter
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      pxNewNode->m_pxLeft      = pxLHS;
      pxNewNode->m_pxRight     = NULL;
      pxNewNode->m_ucOperation = 162;

      SkipSpaces();
      return( pxNewNode );
    }
    if ( oToken =="ASINH" )
    {
      pxLHS = FactorExpression();
      pxNewNode = new NODE;

      pxNewNode->m_pxLeft      = pxLHS;
      pxNewNode->m_pxRight     = NULL;
      pxNewNode->m_ucOperation = 163;

      SkipSpaces();
      return( pxNewNode );
    }
    if ( oToken =="ACOSH" )
    {
      pxLHS = FactorExpression();
      pxNewNode = new NODE;

      pxNewNode->m_pxLeft      = pxLHS;
      pxNewNode->m_pxRight     = NULL;
      pxNewNode->m_ucOperation = 164;

      SkipSpaces();
      return( pxNewNode );
    }
    if ( oToken =="ATANH" )
    {
      pxLHS = FactorExpression();
      pxNewNode = new NODE;

      pxNewNode->m_pxLeft      = pxLHS;
      pxNewNode->m_pxRight     = NULL;
      pxNewNode->m_ucOperation = 165;

      SkipSpaces();
      return( pxNewNode );
    }

    if ( oToken =="LOG10" )
    {
      pxLHS = FactorExpression();
      pxNewNode = new NODE;

      pxNewNode->m_pxLeft      = pxLHS;
      pxNewNode->m_pxRight     = NULL;
      pxNewNode->m_ucOperation = 166;

      SkipSpaces();
      return( pxNewNode );
    }

    if ( oToken =="LOG2" )
    {
      pxLHS = FactorExpression();
      pxNewNode = new NODE;

      pxNewNode->m_pxLeft      = pxLHS;
      pxNewNode->m_pxRight     = NULL;
      pxNewNode->m_ucOperation = 167;

      SkipSpaces();
      return( pxNewNode );
    }

    if ( oToken =="ABS" )
    {
      pxLHS = FactorExpression();
      pxNewNode = new NODE;

      pxNewNode->m_pxLeft      = pxLHS;
      pxNewNode->m_pxRight     = NULL;
      pxNewNode->m_ucOperation = 168;

      SkipSpaces();
      return( pxNewNode );
    }

    if ( oToken =="ROUNDDOWN" )
    {
      pxLHS = FactorExpression();
      pxNewNode = new NODE;

      pxNewNode->m_pxLeft      = pxLHS;
      pxNewNode->m_pxRight     = NULL;
      pxNewNode->m_ucOperation = 169;

      SkipSpaces();
      return( pxNewNode );
    }

    if ( oToken =="ROUNDUP" )
    {
      pxLHS = FactorExpression();
      pxNewNode = new NODE;

      pxNewNode->m_pxLeft      = pxLHS;
      pxNewNode->m_pxRight     = NULL;
      pxNewNode->m_ucOperation = 170;

      SkipSpaces();
      return( pxNewNode );
    }

    std::string onid        = oVarName;
    IterCMapVariable oIter = m_poVariables->find( onid );

    if ( m_poVariables->end() != oIter )
    {
      poValue = (*oIter).second;
      pxNewNode = new NODE;

      pxNewNode->m_pxLeft       = NULL;
      pxNewNode->m_pxRight      = NULL;
      pxNewNode->m_ucOperation  = '`';

      pxNewNode->m_oValueString = new std::string( oVarName ); 
      pxReturn = pxNewNode;
    }
    else 
      pxReturn = NULL;
  }

  SkipSpaces();
  return( pxReturn );
}


int VMCalcExpressionAnalyzer::ChangeExpression( const char* pchNewExpression )
{
  int   iSize   = strlen( pchNewExpression );
  char* pchCopy = new char[ iSize + 1 ];

  strcpy( pchCopy, pchNewExpression );

  for ( int iLoop = 0; iLoop < iSize; iLoop++ )
  {
    if ( pchCopy[ iLoop ] == ' ' || pchCopy[ iLoop ] == '\t' )
    {
      memmove( pchCopy + iLoop, pchCopy + iLoop + 1, iSize - iLoop );
      iLoop--;
    }
  }  

  m_oEquation = pchCopy;

  delete [] pchCopy;

  m_oEquation += '\0';
  m_oEquation += '\0';
  SkipSpaces();
  return( UpdateValue() );
}


int VMCalcExpressionAnalyzer::Value( double& rdOutput )
{
  giResultCode = 0;

  if ( NULL == m_xExpressionTree ) 
    return( -1 );

  rdOutput = EvaluateExpression( m_xExpressionTree );
  return( giResultCode );
}


double VMCalcExpressionAnalyzer::EvaluateExpression( PNODE a )
{
  VMCalcValueBase* poValue;
  double     v;

  if ( NULL == a->m_ucOperation ) 
  {
    giResultCode = 10;
    return( 0 );
  }

  switch( a->m_ucOperation ) 
  {
    case '+': 
    {
      return( EvaluateExpression( a->m_pxLeft ) 
              + EvaluateExpression( a->m_pxRight ) );
    }

    case '-':
    {
     return( EvaluateExpression( a->m_pxLeft ) 
             - EvaluateExpression( a->m_pxRight ) );
    }

    case '*': 
    {
      return( EvaluateExpression( a->m_pxLeft ) 
              * EvaluateExpression( a->m_pxRight ) );
    }

    case '/': 
    {
      v = EvaluateExpression( a->m_pxRight );
      if ( 0 == v )
      {
        giResultCode = DIVISION_BY_0;
        return( -EvaluateExpression( a->m_pxLeft ) / 0.001 );
      }
      else
      {
        return( EvaluateExpression( a->m_pxLeft ) / v );
      }
    }

    case 150: 
    {
      return( sin( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 151: 
    {
      return( cos( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 152: 
    {
      return( exp( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 153: 
    {
      v = EvaluateExpression( a->m_pxLeft ) ;
      if ( v < 0 ) 
      {
        giResultCode = INVALID_DOMAIN;
        return( 0 );
      }
      else 
      {
        return( sqrt( v ) );
      }
    }

    case 154: 
    {
      v = EvaluateExpression( a->m_pxLeft );
      if ( v <= 0 )
      { 
        giResultCode = INVALID_DOMAIN;
        return 0;
      }
      else 
      {
        return( log( v ) );
      }
    }

    case 155: 
    {
      return( tan( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 156: 
    {
      return( 1 / tan( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 157: 
    {
      return( asin( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 158: 
    {
      return( acos( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 159: 
    {
      return( atan( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 160: 
    {
      return( sinh( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 161: 
    {
      return( cosh( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 162: 
    {
      return( tanh( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 163: 
    { 
      double dblValue = EvaluateExpression( a->m_pxLeft );
      return( log( dblValue + sqrt( dblValue * dblValue + 1 ) ) );
    }

    case 164: 
    {
      double dblValue = EvaluateExpression( a->m_pxLeft );
      return( log( dblValue + sqrt( dblValue * dblValue - 1 ) ) );
    }

    case 165: 
    {
      double dblValue = EvaluateExpression( a->m_pxLeft );
      return( 0.5 * log( ( 1 + dblValue ) / ( 1 - dblValue ) ) );
    }

    case 166:
      return( log10( EvaluateExpression( a->m_pxLeft ) ) );
    
    case 167:
    {
      double dblValue = EvaluateExpression( a->m_pxLeft );
      return( log( dblValue ) / log( 2.0 ) );
    }

    case 168:
    {
      return( fabs( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 169:
    {
      return( floor( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case 170:
    {
      return( floor( EvaluateExpression( a->m_pxLeft ) + 0.5 ) );
    }

    case '|': 
    {
      return( fabs( EvaluateExpression( a->m_pxLeft ) ) );
    }

    case '^': 
    {
      return( pow( EvaluateExpression( a->m_pxLeft ), EvaluateExpression( a->m_pxRight ) ) );
    }

    case '@': 
    {
      return( a->m_dValue );
    }

    // logical operations evaluation
    //
    case '<': 
    {
      return( EvaluateExpression( a->m_pxLeft ) < EvaluateExpression( a->m_pxRight ) );
    }

    case '>': 
    {
      return( EvaluateExpression( a->m_pxLeft ) > EvaluateExpression( a->m_pxRight ) );
    }

    case '!': 
    {
      return( !EvaluateExpression( a->m_pxRight ) );
    }
 
    default: 
    {
      if ( NULL == m_poVariables ) 
      {
        giResultCode = UNDEFINED_VARIABLE;
        return( 0 ); 
      }

      std::string oVarName   = *a->m_oValueString;
      IterCMapVariable oIter = m_poVariables->find( oVarName );

      if ( m_poVariables->end() == oIter )
      {
        giResultCode = UNDEFINED_VARIABLE;
        return( 0 );
      }
      else 
      {
        poValue = (*oIter).second;
        return( poValue->GetValue() );
      }
    }
  }
}


VMCalcExpressionAnalyzer::PNODE VMCalcExpressionAnalyzer::GetExpressionRoot( void )
{
  return( m_xExpressionTree );
}


VMCalcExpressionAnalyzer::VMCalcExpressionAnalyzer( VMCalcExpressionAnalyzer& roOther )
{
  *this = roOther;
}


VMCalcExpressionAnalyzer::PNODE VMCalcExpressionAnalyzer::CloneTree( void )
{
  return( CloneTree( m_xExpressionTree ) );  
}


void VMCalcExpressionAnalyzer::AtachVariables( CMapVariable * poVarsMap )
{
  m_poVariables = poVarsMap;
}


VMCalcExpressionAnalyzer::PNODE VMCalcExpressionAnalyzer::CloneTree( PNODE arb )
{
  if ( NULL == arb )
    return( NULL );

  PNODE clonArb      = new NODE;
  *clonArb           = *arb;
  clonArb->m_pxLeft  = CloneTree( arb->m_pxLeft  );
  clonArb->m_pxRight = CloneTree( arb->m_pxRight );
  return( clonArb );
}


VMCalcExpressionAnalyzer& VMCalcExpressionAnalyzer::operator= ( VMCalcExpressionAnalyzer& roOther )
{
  m_oEquation       = roOther.m_oEquation;
  m_poVariables     = roOther.m_poVariables;
  m_iPosition       = 0;
  m_xExpressionTree = roOther.CloneTree();
  return( *this );
}


void VMCalcExpressionAnalyzer::SkipSpaces( void )
{
  while ( m_oEquation[ m_iPosition ] == ' ' 
       && m_oEquation[ m_iPosition ] != '\0' )
    m_iPosition++;
}


VMCalcExpressionAnalyzer::PNODE VMCalcExpressionAnalyzer::PerformLogicalOperation( void )
{
  SkipSpaces();

  PNODE pxNewNode;
  PNODE pxLHS = PerformSignedOperation();
  PNODE pxRHS;

  if ( NULL == pxLHS ) 
    return( NULL );

  SkipSpaces();

  // || another same priority operations
  //
  while ( ( m_oEquation[ m_iPosition ] == '<' ) 
       || ( m_oEquation[ m_iPosition ] == '>' ) ) 
  {
    pxNewNode = new NODE;

    pxNewNode->m_pxLeft      = pxLHS;
    pxNewNode->m_ucOperation = m_oEquation[ m_iPosition ];

    m_iPosition++;

    pxRHS = PerformSignedOperation();
    pxNewNode->m_pxRight = pxRHS;

    if ( NULL == pxRHS ) 
    {
      PruneTree( pxNewNode );
      return( NULL );
    }
    pxLHS = pxNewNode;
  }
  return( pxLHS );
}


VMCalcExpressionAnalyzer::PNODE VMCalcExpressionAnalyzer::PerformSignedOperation( void )
{
  SkipSpaces();

  PNODE pxNewNode = NULL;
  PNODE pxRHS;

  // || another same priority operations
  //
  if ( ( m_oEquation[ m_iPosition ] == '!' ) ) 
  {
    pxNewNode = new NODE;

    pxNewNode->m_pxLeft      = NULL;
    pxNewNode->m_ucOperation = m_oEquation[ m_iPosition ];

    m_iPosition++;

    pxRHS = PerformSignedOperation();
    pxNewNode->m_pxRight = pxRHS;

    if ( NULL == pxRHS ) 
    {
      PruneTree( pxNewNode );
      return( NULL );
    }
  }
  else 
    pxNewNode = FactorExpression();

  return( pxNewNode );
}


/*****************************************************************************/
/* Check-in history */
/*
 *$Log:  $
*/
/*****************************************************************************/


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -