分享
 
 
 

表达式求值(中)

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

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

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有