📄 lexclass.cpp
字号:
//////////////////////////////////////////////////////////////////////
//
// By Liutao
// Xi'an JiaoTong University, 2000.11
//
// LexClass.cpp: implementation of the LexClass class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Lex.h"
#include "LexClass.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Lex::Lex()
{
i = 0;
pStr = "#()+-*/";
WithWrong = false;
_element tmpElement;
tmpElement.u.op = '#', tmpElement.flag = OP, tmpElement.p = GetP();
opStack.AddTail(tmpElement);
}
Lex::~Lex()
{
opStack.RemoveAll();
numStack.RemoveAll();
}
void Lex::GetFormula(CString str)
{
formula = str + '#';
formula.Replace(" ", "");
int start = formula.Find('-');
while (start!=-1)
{
if (start==0) formula = '0' + formula, start++;
else if (!isdigit(formula[start-1])) formula.Insert(start++, "0");
start = formula.Find('-', start+1);
}
}
void Lex::Push()
{
if (element.flag==OP)
{
if (element.u.op=='#')
if (opStack.GetTail().u.op!='#') WithWrong = true;
else opStack.RemoveTail();
else if (element.u.op==')')
if (opStack.GetTail().u.op!='(') WithWrong = true;
else opStack.RemoveTail();
else opStack.AddTail(element);
}
else numStack.AddTail(element);
}
BOOL Lex::pGreat()
{
if (element.flag==OP && element.u.op=='(') return true;
else if (element.flag==OP && element.u.op==')') return false;
else return element.p >= opStack.GetTail().p;
}
double Lex::GetResult()
{
double result = -1;
while (GetNextElement()!=NULL && !WithWrong)
{
if (pGreat()) Push();
else
{
do Cal(); while (element.p < opStack.GetTail().p && !WithWrong);
Push();
}
}
WithWrong = !(opStack.IsEmpty() && numStack.GetCount()==1);
if (!WithWrong) result = numStack.RemoveTail().u.num;
return result;
}
int Lex::GetNextElement()
{
CString tmpStr;
element.flag = NUM;
if (i>=formula.GetLength()) return NULL;
if (!isdigit(formula.GetAt(i)))
{
element.u.op = formula.GetAt(i++), element.flag = OP, element.p = GetP();
return 1;
}
for (; i<formula.GetLength(); i++)
if (isdigit(formula.GetAt(i)) || formula.GetAt(i)=='.')
tmpStr += formula.GetAt(i);
else break;
element.u.num = atof((LPCTSTR)tmpStr), element.p = RAW;
return 1;
}
int Lex::GetP()
{
return pStr.Find(element.u.op);
}
BOOL Lex::IsWrong()
{
return WithWrong;
}
#define _cal(x) tmp2.u.num ##x=tmp1.u.num, tmp2.p = NOTRAW, numStack.AddTail(tmp2); break;
void Lex::Cal()
{
if (WithWrong = numStack.GetCount()<=1 && IsOp()) return;
CString tmpStr;
_element tmp1 = numStack.RemoveTail(), tmp2 = numStack.RemoveTail();
if (tmp1.p==tmp2.p && tmp1.p==RAW)
{
result_str += opStack.GetTail().u.op;
tmpStr.Format("%f ", tmp2.u.num), result_str += tmpStr;
tmpStr.Format("%f ", tmp1.u.num), result_str += tmpStr;
}
else
{
result_str = opStack.GetTail().u.op + result_str;
if (tmp2.p==RAW) tmpStr.Format("%f ", tmp2.u.num), result_str += tmpStr;
}
switch (opStack.RemoveTail().u.op)
{
case '+' : _cal(+);
case '-' : _cal(-);
case '*' : _cal(*);
case '/' : _cal(/);
}
}
#undef _cal
CString Lex::GetString()
{
return result_str;
}
#define __comp(x) opStack.GetTail().u.op==#@x
BOOL Lex::IsOp()
{
return __comp(+) || __comp(-) || __comp(*) || __comp(/);
}
#undef __comp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -