📄 expression.cpp
字号:
// 错误
return 0;
}
}
_CallParmCntStack.pop();
// 把结果压入参数堆栈
_ParmStack.push(var);
// 取得表达式下一个位置的指针
return GetNextChar(str+1);
}
// 计算逗号表达式
// 如果出现错误,返回0
// 否则返回剩余表达式的指针
char* CExpression::_DoComma(char *szExpr)
{
char* str=szExpr;
int cnt=0;
while (1)
{
// 计算逗号表达式中的子表达式
str=this->_DoExpr(str);
// 如果出现错误
if (str==0)
return 0;
// 如果逗号表达式计算结束
if (str==(char*)-1)
break;
// 参数个数加1
cnt ++;
if (*str==',')
{
// 如果是下一个符号逗号,就说明逗号表达式还有其他的元素
str ++;
}else if((*str==')' && _CallStack.size()!=0) || (*str=='\0' && _CallStack.size()==0))
{
break;
}else
{
// 表达式错误,左右括号不匹配
this->SetError("syntax error : ')'");
return 0;
}
}
if (cnt==0 && _CallStack.size()==0)
{
// 空表达式错误
this->SetError("expression is NULL");
return 0;
}else
{
_CallParmCntStack.push(cnt);
return str;
}
}
// 计算一个表达式
// szExpr 是表达式的字符串
// 如果出现错误,返回0
// 否则返回剩余表达式的指针
char* CExpression::_DoExpr(char *szExpr)
{
char* str;
double n1, n2;
int opcnt=0;
char opr;
if (szExpr==0)
{
// 空表达式错误
this->SetError("expression is NULL");
return 0;
}
str = szExpr;
_OprStack.push(0);
opcnt = 1;
while(*str!=0 && *str!=',' && *str!=')' || _OprStack.top()!=0)
{
if (!this->inOperate(*str)) // 如果不是操作符
{
opcnt = 0;
str = GetSymbol(str, _Symbol);
if (str==0) return 0;
if (*str=='(')
{
// 这是一个由参数的函数
str = this->_DoCall(_Symbol, str+1);
if (str)
{
n1 = _ParmStack.top();
_NumStack.push(n1);
_ParmStack.pop();
}else
{
return 0;
}
}else
{
if (_Symbol[0]>='0' && _Symbol[0]<='9')
{
// 只是一个数字
if (this->_GetNumber(_Symbol, &n1))
{
_NumStack.push(n1);
}else
{
return 0;
}
}else
{
// 这是一个没有参数的函数
if (this->DoCall(_Symbol, 0, 0, &n1))
{
_NumStack.push(n1);
}else
{
return 0;
}
}
}
}else
{
if (opcnt)
{
if (*str=='+' || *str=='-')
{
opr = _OprStack.top();
if (opr!=')')
{
opr = (*str=='+')?'#':'$';
}else
{
opr = *str;
}
}else
{
// 表达式格式错误,比如出现 a**b
this->SetError("illegal indirection");
return 0;
}
}else
{
opr = *str;
}
opcnt ++;
switch(this->Precede(_OprStack.top(),opr)) // 取得优先及别
{
case EL: // <
_OprStack.push(opr);
str = GetNextChar(str+1);
break;
case EE: // =
_OprStack.pop();
str = GetNextChar(str+1);
break;
case EG: // >
opr = _OprStack.top();
if (this->_IsSingle(opr))
{
if (_NumStack.size()<1)
{
this->SetError("operate error");
return 0;
}
n1 = 0;
}else
{
if (_NumStack.size()<2)
{
this->SetError("operate error");
return 0;
}
n1 = _NumStack.top();
_NumStack.pop();
}
n2 = _NumStack.top();
_NumStack.pop();
_NumStack.push(this->Operate(n2, n1, opr));
_OprStack.pop();
opcnt=0;
break;
default: // 异常
this->SetError("operate error");
return 0;
break;
}
}
}
while(!_OprStack.empty()) _OprStack.pop();
if (_NumStack.size())
{
_ParmStack.push(_NumStack.top());
while(!_NumStack.empty()) _NumStack.pop();
return str;
}else
{
return (char*)-1;
}
return 0;
}
// 从字符串中取出一个数字
bool CExpression::_GetNumber(char* szExpr, double *var)
{
if (szExpr==0)
{
// 空表达式错误
this->SetError("expression is NULL");
return false;
}
for (char *str=(char*)szExpr; *str; str++)
{
if ((*str<'0'||*str>'9')&&(*str!='.'))
{
// 数字格式错误
this->SetError("bad suffix on number: '%s'", szExpr);
return false;
}
}
// 取出数字
*var = atof(szExpr);
return true;
}
// 虚函数,用户重定义这个函数来实现对自定义函数的解释
bool CExpression::DoCall(const char *szCallName, const int iParmCnt, const double *pParms, double *var)
{
return DefDoCall(this, szCallName, iParmCnt, pParms, var);
}
// 定义一些基本的函数给用户使用
// 如果用户需要使用这些函数就要在
// 虚函数 DoCall 中调用这个函数
bool CExpression::DefDoCall(CExpression *pObj, const char *szCallName, const int iParmCnt, const double *pParms, double *var)
{
int i;
if (iParmCnt) *var = pParms[iParmCnt-1];
else *var = 0;
if (strcmp("log", szCallName)==0)
{
if (iParmCnt!=1) goto err_pos_1;
*var = log(pParms[0]);
}else if (strcmp("abs", szCallName)==0)
{
if (iParmCnt!=1) goto err_pos_1;
*var = fabs(pParms[0]);
}else if (strcmp("sqrt", szCallName)==0)
{
if (iParmCnt!=1) goto err_pos_1;
*var = sqrt(pParms[0]);
}else if (strcmp("sin", szCallName)==0)
{
if (iParmCnt!=1) goto err_pos_1;
*var = sin(pParms[0]);
}else if (strcmp("cos", szCallName)==0)
{
if (iParmCnt!=1) goto err_pos_1;
*var = cos(pParms[0]);
}else if (strcmp("tan", szCallName)==0)
{
if (iParmCnt!=1) goto err_pos_1;
*var = tan(pParms[0]);
}else if (strcmp("rand", szCallName)==0)
{
if (iParmCnt!=2) goto err_pos_1;
*var = (rand()%((int)(pParms[1]-pParms[0]))+pParms[0]);
}else if (strcmp("min", szCallName)==0)
{
*var = pParms[0];
for (i=1; i<iParmCnt; i++)
{
if (pParms[i]<*var) *var = pParms[i];
}
}else if (strcmp("max", szCallName)==0)
{
*var = pParms[0];
for (i=1; i<iParmCnt; i++)
{
if (pParms[i]>*var) *var = pParms[i];
}
}else if (strcmp("sum", szCallName)==0)
{
*var = 0;
for (i=0; i<iParmCnt; i++)
{
*var += pParms[i];
}
}else if (strcmp("ave", szCallName)==0)
{
*var = 0;
for (i=0; i<iParmCnt; i++)
{
*var += pParms[i];
}
*var /= iParmCnt;
}else
{
goto err_pos_2;
}
return true;
err_pos_1:
if (pObj)
{
// 函数参数个数错误
pObj->SetError("'%s' : function does not take %d parameters", szCallName, iParmCnt);
}
return false;
err_pos_2:
if (pObj)
{
// 没有定义的标志符
pObj->SetError("'%s' : undeclared identifier", szCallName);
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -