📄 mathparser.cpp
字号:
break;
}
case 4 :
{
if (TokenType == EXPO)
Shift(16);
else
Reduce(8);
break;
}
case 5 :
{
if (TokenType == NUM)
Shift(10);
else if (TokenType == FUNC )
Shift(11);
else if (TokenType == OPAREN)
Shift(9);
else
{
TokenError = ErrExpression;
Position -= TokenLen;
}
break;
}
case 6 : Reduce(10); break;
case 7 : Reduce(13); break;
case 8 : Reduce(12); break;
case 10 :Reduce(15); break;
case 11 :
{
if (TokenType == OPAREN)
Shift(20);
else
{
TokenError = ErrOpenParen;
Position -= TokenLen;
}
break;
}
case 17 : Reduce(9); break;
case 18 : throw Exception("错误!18");
case 19 :
{
if (TokenType == PLUS)
Shift(12);
else if (TokenType == MINUS)
Shift(13);
else if (TokenType == CPAREN)
Shift(27);
else
{
TokenError = ErrOpCloseParen;
Position -= TokenLen;
}
break;
}
case 21 :
{
if (TokenType == TIMES)
Shift(14);
else if (TokenType == DIVIDE)
Shift(15);
else
Reduce(1);
break;
}
case 22 :
{
if (TokenType == TIMES)
Shift(14);
else if (TokenType == DIVIDE)
Shift(15);
else
Reduce(2);
break;
}
case 23 : Reduce(4); break;
case 24 : Reduce(5); break;
case 25 : Reduce(7); break;
case 26 : Reduce(11); break;
case 27 : Reduce(14); break;
case 28 :
{
if (TokenType == PLUS)
Shift(12);
else if (TokenType == MINUS)
Shift(13);
else if (TokenType == CPAREN)
Shift(29);
else
{
TokenError = ErrOpCloseParen;
Position -= TokenLen;
}
break;
}
case 29 : Reduce(16); break;
case 80 : Reduce(100); break;
}
}while( !Accepted && (TokenError == 0));
if (TokenError != 0 )
{
if (TokenError == ErrBadRange ) Position -= TokenLen;
}
if (MathError || (TokenError != 0))
{
ParseError = TRUE;
ParseValue = 0;
return;
}
ParseError = FALSE;
ParseValue = Stack[StackTop].Value;
}
void TMathParser::Reduce(WORD Reduction)
{
TokenRec Token1, Token2;
switch(Reduction)
{
case 1 : //'+'运算
{
Pop(Token1);
Pop(Token2);
Pop(Token2);
CurrToken.Value = Token1.Value + Token2.Value;
break;
}
case 2 : //'-'运算
{
Pop(Token1);
Pop(Token2);
Pop(Token2);
CurrToken.Value = Token2.Value - Token1.Value;
break;
}
case 4 : //'*'运算
{
Pop(Token1);
Pop(Token2);
Pop(Token2);
CurrToken.Value = Token1.Value * Token2.Value;
break;
}
case 5 : //'/'运算
{
Pop(Token1);
Pop(Token2);
Pop(Token2);
if (fabs(Token1.Value) < 1.0E-12)
MathError = TRUE;
else
CurrToken.Value = Token2.Value / Token1.Value;
//CurrToken.Value = Token2.Value / Token1.Value;
break;
}
case 100 : //'%'运算
{
Pop(Token1);
Pop(Token2);
Pop(Token2);
if (fabs(Token1.Value) < 1.0E-12)
MathError = TRUE;
else
CurrToken.Value = Round(Token2.Value) % Round(Token1.Value);
//CurrToken.Value = Round(Token2.Value) % Round(Token1.Value);
break;
}
case 7 : //'^'运算
{
Pop(Token1);
Pop(Token2);
Pop(Token2);
if (Token2.Value < 0.0)
MathError = TRUE;
else if ((Token1.Value * log(Token2.Value) < -ExpLimit) ||
(Token1.Value * log(Token2.Value) > ExpLimit))
MathError = TRUE;
else
CurrToken.Value = exp(Token1.Value * log(Token2.Value));
break;
}
case 9 :
{
Pop(Token1);
Pop(Token2);
CurrToken.Value = -Token1.Value;
break;
}
case 11 : throw Exception("非法表达式!");
case 13 : throw Exception("非法表达式!");
case 14 :
{
Pop(Token1);
Pop(CurrToken);
Pop(Token1);
break;
}
case 16 : //计算各函数
{
Pop(Token1);
Pop(CurrToken);
Pop(Token1);
Pop(Token1);
if( Token1.FuncName == "ABS")
CurrToken.Value = fabs(CurrToken.Value);
else if (Token1.FuncName == "ATAN")
CurrToken.Value = atan(CurrToken.Value);
else if (Token1.FuncName == "COS")
{
if ((CurrToken.Value < -9E18) || (CurrToken.Value > 9E18))
MathError = TRUE;
else
CurrToken.Value = cos(CurrToken.Value);
}
else if (Token1.FuncName == "EXP")
{
if ((CurrToken.Value < -ExpLimit) || (CurrToken.Value > ExpLimit))// then
MathError = TRUE;
else
CurrToken.Value = exp(CurrToken.Value);
}
else if (Token1.FuncName == "LN")// then
{
if (CurrToken.Value <= 0.0)
MathError = TRUE;
else
CurrToken.Value = log(CurrToken.Value);
}
else if (Token1.FuncName == "ROUND")
{
if ((CurrToken.Value < -1E9) || (CurrToken.Value > 1E9))
MathError = TRUE;
else
CurrToken.Value = Round(CurrToken.Value);
}
else if (Token1.FuncName == "SIN")
{
if( (CurrToken.Value < -9E18) || (CurrToken.Value > 9E18))
MathError = TRUE;
else
CurrToken.Value = sin(CurrToken.Value);
}
else if (Token1.FuncName == "SQRT")
{
if( CurrToken.Value < 0.0 )//then
MathError = TRUE;
else
CurrToken.Value = sqrt(CurrToken.Value);
}
else if (Token1.FuncName == "SQR")
{
if ((CurrToken.Value < -SQRLIMIT) || (CurrToken.Value > SQRLIMIT))// then
MathError = TRUE;
else
CurrToken.Value = CurrToken.Value * CurrToken.Value;
}
else if (Token1.FuncName == "TRUNC")
{
if ((CurrToken.Value < -1E9) || (CurrToken.Value > 1E9))
MathError = TRUE;
else
CurrToken.Value = (int)(CurrToken.Value);//Trunc
}
else if(Token1.FuncName == "NOT")
{
if (CurrToken.Value < 0.001 && CurrToken.Value > -0.001)
CurrToken.Value = 1.0;
else
CurrToken.Value = 0.0;
}
else if(Token1.FuncName == "BOOL")
{
if (CurrToken.Value < 0.001 && CurrToken.Value > -0.001)
CurrToken.Value = 0.0;
else
CurrToken.Value = 1.0;
}
else if(Token1.FuncName == "SGN")
{
if (CurrToken.Value > 0.0)
CurrToken.Value = 1.0;
else
CurrToken.Value = 0.0;
}
else if(Token1.FuncName == "LOG10")
{
if (CurrToken.Value <= 0.0)
MathError = TRUE;
else
CurrToken.Value = log10(CurrToken.Value);
}
break;
}
case 3:
case 6:
case 8:
case 10:
case 12:
case 15 : Pop(CurrToken); break;
}
CurrToken.State = GotoState(Reduction);
Push(CurrToken);
}
void TMathParser::Shift(WORD State)//{ Shifts a Token onto the stack }
{
CurrToken.State = State;
Push(CurrToken);
TokenType = NextToken();
}
int TMathParser::Round(double value)
{
int result1, result2;
if(value > 0.0)
{
result1 = (int)value;
result2 = result1 + 1;
if( (value - (double)result1) > ((double)result2 - value))
return result2;
else return result1;
}
else
{
result1 = (int)value;
result2 = result1 - 1;
if( (value - (double)result2) > ((double)result1 - value))
return result1;
else return result2;
}
}
void TMathParser::AddVar(Extended Value, AnsiString VarName)
{
VARSTRU *pvar = new VARSTRU;
pvar->Value = Value;
if( VarName.Length() > MaxVarName) VarName.SetLength(MaxVarName);
VarName = VarName.Trim();
VarName = VarName.UpperCase();
memset(pvar->VarName,0,MaxVarName);
memcpy(pvar->VarName, VarName.c_str(), VarName.Length());
m_VarList->Add(pvar);
}
BOOL TMathParser::GetVar(AnsiString VarName, Extended &Value)
{
BOOL bFound;
POSITION pos;
if(m_VarList->Count == 0) return FALSE;
bFound = FALSE;
VarName = VarName.UpperCase();
VARSTRU *pvar;
AnsiString str;
for( pos = 0; pos < m_VarList->Count; pos ++)
{
pvar = (VARSTRU *)m_VarList->Items[ pos ];
str = AnsiString(pvar->VarName);
str = str.UpperCase();
if(str == VarName)
{
Value = pvar->Value;
bFound = TRUE;
break;
}
}
return bFound;
}
BOOL __fastcall TMathParser::CharIn(char ch, char StartCh, char EndCh)
{
//TODO: Add your source code here
BOOL Result = False;
if( ch >= StartCh && ch <= EndCh)
{
Result = True;
}
return Result;
}
BOOL __fastcall TMathParser::CharIn(char ch, AnsiString Str)
{
//TODO: Add your source code here
return Str.Pos(ch) > 0;
}
BOOL __fastcall TMathParser::EditVar(AnsiString VarName, Extended Value)
{
//TODO: Add your source code here
BOOL bFound;
POSITION pos;
if(m_VarList->Count == 0) return FALSE;
bFound = FALSE;
VarName = VarName.UpperCase();
VARSTRU *pvar;
AnsiString str;
for( pos = 0; pos < m_VarList->Count; pos ++)
{
pvar = (VARSTRU *)m_VarList->Items[ pos ];
str = AnsiString(pvar->VarName);
str = str.UpperCase();
if(str == VarName)
{
pvar->Value = Value;
bFound = TRUE;
break;
}
}
return bFound;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -