// Expression.cpp 第一部分
// Expression.cpp: implementation of the CExpression class.
//
//
#include <sstream>
#include <string>
#include <stack>
using namespace std;
#include "Expression.h"
//
// Construction/Destruction
//
__stdcall ExpAtom::ExpAtom() {
memset(this,0,sizeof(ExpAtom));
}
__stdcall CExpression::CExpression()
{
m_szExpr=NULL;
m_szOpr="+-*/{}[]()";
m_szInvalid=" /r/n/t";
m_IsDeleted=false;
m_IsTranslated=false;
m_IsSuffix=false;
m_IsCalc=false;
m_szTranslated="";
m_szSuffix="";
}
__stdcall CExpression::~CExpression() { Free(); }
void __stdcall CExpression::Free()
{
if(m_szExpr) delete []m_szExpr;
m_szExpr=NULL;
m_IsDeleted=false;
m_IsTranslated=false;
m_IsSuffix=false;
m_IsCalc=false;
m_szTranslated="";
m_szSuffix="";
}
const char* __stdcall CExpression::GetExpression()
{
if(!m_IsTranslated) TranslateToAtom();
return m_szTranslated.c_str();
}
const char* __stdcall CExpression::GetSuffixExpr()
{
if(!m_IsSuffix) AtomToSuffix();
return m_szSuffix.c_str();
}
void __stdcall CExpression::SetExpression(const char *Expr)
{
Free();
m_szExpr=strdup(Expr);
}
void __stdcall CExpression::TranslateToAtom()
{
if(!m_szExpr) return;
if(m_IsTranslated) return;
const char *exp=m_szExpr;
bool isSaveNum=false; // 是否已经保存了数字
int i=0;
if(!m_IsDeleted) DeleteInvalidChars(); // 删除一些无效的字符
m_arrAtom.clear(); // 先清空Atom数组
while(*exp)
{
ExpAtom ea;
if(IsOperator(*exp))
{
if(*exp=='-') // 解决负数的情况
{
if(i!=0)
{
// 当是'-'号,且不在第一个时,如果前一个是操作符且不是')',后一个是数字
// 则这是个负数.
if(IsOperator(*(exp-1)) && *(exp-1)!=')' && !IsOperator(*(exp+1)))
{
ea.flag=atomVal;
ea.atom.value=atof(exp);
m_arrAtom.push_back(ea);
isSaveNum=true;
goto LBL1;
}
}
else
{
// 当是'-'号,且在第一个时,如果后一个是数字
// 则这是个负数.
if(!IsOperator(*(exp+1)))
{
ea.flag=atomVal;
ea.atom.value=atof(exp);
m_arrAtom.push_back(ea);
isSaveNum=true;
goto LBL1;
}
}
}
isSaveNum=false;
ea.flag=atomOpr;
*ea.atom.opr=*exp;
m_arrAtom.push_back(ea);
LBL1:;
}
else
{
if(!isSaveNum)
{
ea.flag=atomVal;
ea.atom.value=atof(exp);
m_arrAtom.push_back(ea);
isSaveNum=true;
}
}
i++;
exp++;
}
AtomsToString(m_arrAtom,m_szTranslated);
m_IsTranslated=true;
}
void __stdcall CExpression::AtomToSuffix()
{
if(m_IsSuffix) return;
if(!m_IsTranslated) TranslateToAtom();
m_arrSuffix.clear(); // 置空
stack<ExpAtom> skop; // 操作符栈
ExpAtom ea;
ea.flag=atomOpr;
*ea.atom.opr='#';
skop.push(ea); // 向栈压入表达式开始符 #
m_arrAtom.push_back(ea); // 向表达式加结束符 #
vector<ExpAtom>::iterator it=m_arrAtom.begin();
for(;it<m_arrAtom.end();it++)
{
if(it->flag==atomVal)
{
m_arrSuffix.push_back(*it);
}
else
{
char op1=*skop.top().atom.opr; // 栈顶操作符
char op2=*it->atom.opr; // 当前操作符
switch(op2)
{
case ')':
case '#':
{
while(CompareOpr(*skop.top().atom.opr,*it->atom.opr))
{
m_arrSuffix.push_back(skop.top());
skop.pop();
}
skop.pop();
}
break;
default:
{
int cmp=CompareOpr(op1,op2);
if(cmp==1)
{
while(CompareOpr(*skop.top().atom.opr,*it->atom.opr)==1)
{
m_arrSuffix.push_back(skop.top());
skop.pop();
}
skop.push(*it);
}
else if(cmp==-1) // op1<op2
{
skop.push(*it);
}
}
}
}
}
m_arrAtom.pop_back();
AtomsToString(m_arrSuffix,m_szSuffix);
m_IsSuffix=true;
}
void __stdcall CExpression::DeleteInvalidChars()
{
if(m_IsDeleted) return;
string exp(m_szExpr);
string::iterator ithead=exp.begin();
string::iterator ittail=exp.end()-1;
while(ithead<=ittail)
{
if(IsInvalidChar(*ithead))
{
exp.erase(ithead);
}
if(IsInvalidChar(*ittail))
{
exp.erase(ittail);
}
ithead++;
ittail--;
}
if(m_szExpr) delete []m_szExpr;
m_szExpr=strdup(exp.c_str());
m_IsDeleted=true;
}
bool __stdcall CExpression::IsOperator(char c)
{
const char *head=m_szOpr;
const char *tail=m_szOpr+strlen(m_szOpr)-1;
while(head<=tail)
{
if(c==*head) return true;
if(c==*tail) return true;
head++;
tail--;
}
return false;
}
bool __stdcall CExpression::IsInvalidChar(char c)
{
const char *head=m_szInvalid;
const char *tail=m_szInvalid+strlen(m_szInvalid)-1;
while(head<=tail)
{
if(c==*head) return true;
if(c==*tail) return true;
head++;
tail--;
}
return false;
}