📄 mathparser.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MathParser.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#include "math.h"
TMathParser::TMathParser(AnsiString s)
{
m_VarList = new TList;
FInput = s;
}
TMathParser::~TMathParser()
{
VARSTRU *pvar;
while( m_VarList->Count > 0)
{
pvar = (VARSTRU *)m_VarList->Items[0];
delete pvar;
m_VarList->Delete(0);
}
delete m_VarList;
}
WORD TMathParser::GotoState(WORD Production)/* Finds the new state based on the just-completed production and the top state. */
{
WORD State;
WORD ResultGotoState;
State = Stack[StackTop].State;
if (Production <= 3)
{
switch(State)
{
case 0 : ResultGotoState = 1; break;
case 9 : ResultGotoState = 19;break;
case 20: ResultGotoState = 28;break;
}
}
else if(Production <= 6)
{
switch(State)
{
case 0:
case 9:
case 20: ResultGotoState = 2;
break;
case 12: ResultGotoState = 21;
break;
case 13: ResultGotoState = 22;
break;
}
}
else if( (Production <= 8) || (Production == 100))
{ //begin
switch(State)
{
case 0:
case 9:
case 12:
case 13:
case 20: ResultGotoState = 3;
break;
case 14: ResultGotoState = 23;
break;
case 15: ResultGotoState = 24;
break;
case 16: ResultGotoState = 25;
break;
case 40: ResultGotoState = 80;
break;
}
}
else if (Production <= 10)
{// begin
switch(State)
{
case 0:
case 9:
case 12:
case 13:
case 14:
case 15:
case 16:
case 20:
case 40: ResultGotoState = 4; break;
}
}
else if( Production <= 12 )
{
switch(State)
{
case 0:
case 9:
case 12:
case 13:
case 14:
case 15:
case 16:
case 20:
case 40: ResultGotoState = 6;
break;
case 5: ResultGotoState = 17;
break;
}
}
else
{
switch(State)
{
case 0:
case 5:
case 9:
case 12:
case 13:
case 14:
case 15:
case 16:
case 20:
case 40: ResultGotoState = 8;
break;
}
}
return ResultGotoState;
}
BOOL TMathParser::IsFunc(AnsiString S)//{ Checks to see if the parser is about to read a function }
{
WORD P, SLen;
AnsiString FuncName;
BOOL bIsFunc;
P = Position;
FuncName = "";
while (P <= FInput.Length())
{
if(!((FInput[P] <= 'Z' && FInput[P] >= 'A')
||(FInput[P] <= 'z' && FInput[P] >= 'a')
||(FInput[P] <= '9' && FInput[P] >= '0')
||(FInput[P] == '_')))
{
break;
}
FuncName = FuncName + FInput[P];
P++;
}
FuncName = FuncName.UpperCase();
if (FuncName == S )
{
SLen = S.Length();
CurrToken.FuncName = FInput.SubString(Position, SLen);
CurrToken.FuncName = CurrToken.FuncName.UpperCase();
Position += SLen;
bIsFunc = TRUE;
}
else bIsFunc = FALSE;
return bIsFunc;
}
BOOL TMathParser::IsVar(Extended &Value)
{
AnsiString VarName;
VarName = "";
while ((Position <= FInput.Length()) &&
(( FInput[Position ] >= 'A' && FInput[Position ] <= 'Z')
||(FInput[Position ] >= 'a' && FInput[Position ] <= 'z')
||(FInput[Position ] >= '0' && FInput[Position ] <= '9')
||(FInput[Position ] == '_')
))// in ['A'..'Z', 'a'..'z', '0'..'9', '_']) do
{
VarName = VarName + FInput[Position ];
Position++;
}
if( GetVar(VarName, Value) == TRUE)
return TRUE;
return FALSE;
}
TokenTypes TMathParser::NextToken()//{ Gets the next Token from the Input stream }
{
AnsiString NumString;// : String[80];
WORD FormLen, Place, TLen, NumLen ;
int Check ;//: Integer;
char Ch;//, FirstChar;
BOOL Decimal ;
TokenTypes ResultNextToken;
while ((Position <= FInput.Length()) && (FInput[Position ] == ' '))
Position++;
TokenLen = Position;
if (Position > FInput.Length())
{
ResultNextToken = EOL;
TokenLen = 0;
return ResultNextToken;
}
FInput = FInput.UpperCase();
Ch = FInput[Position ];
if (Ch == '!')
{
ResultNextToken = ERR;
TokenLen = 0;
return ResultNextToken ;
}
if((Ch >= '0' && Ch <= '9') || Ch == '.')// if Ch in ['0'..'9', '.'] then
{
NumString = "";
TLen = Position;
Decimal = FALSE;
while ((TLen <= FInput.Length()) &&
((FInput[TLen ] >= '0' && FInput[TLen ] <= '9' ) ||
((FInput[TLen ] == '.') && (!Decimal))))
{
NumString = NumString + FInput[TLen ];
if (Ch == '.') Decimal = TRUE;
TLen++;//Inc(TLen);
}
if ((TLen == 2) && (Ch == '.'))// then
{
ResultNextToken = BAD;
TokenLen = 0;
return ResultNextToken ;
}
if ((TLen <= FInput.Length()) && ((FInput[TLen ]) == 'E'))// then
{
NumString = NumString + 'E';
TLen++;
if( FInput[TLen ] == '+' || FInput[TLen ] == '-')// in ['+', '-'] then
{
NumString[TLen ] = FInput[TLen ];//= NumString + FInput[TLen];
TLen++;
}
NumLen = 1;
while ( (TLen <= FInput.Length()) && (FInput[TLen ] >= '0' && FInput[TLen ] <= '9') &&
(NumLen <= MaxExpLen))
{
NumString = NumString + FInput[TLen ];
NumLen++;//Inc(NumLen);
TLen++;//Inc(TLen);
}
}
if (NumString[1] == '.') NumString = "0" + NumString;
CurrToken.Value = atof(NumString.c_str());
ResultNextToken = NUM;
Position += NumString.Length();
TokenLen = Position - TokenLen;
return ResultNextToken;
}
else if (( Ch>='a' && Ch <= 'z')
||(Ch>='A' && Ch <= 'Z'))
{
if (IsFunc("ABS") ||
IsFunc("ATAN") ||
IsFunc("COS") ||
IsFunc("EXP") ||
IsFunc("LN") ||
IsFunc("ROUND") ||
IsFunc("SIN") ||
IsFunc("SQRT") ||
IsFunc("SQR") ||
IsFunc("TRUNC") ||
IsFunc("NOT") ||
IsFunc("BOOL") ||
IsFunc("LOG10") ||
IsFunc("SGN"))
{
ResultNextToken = FUNC;
TokenLen = Position - TokenLen;
return ResultNextToken ;
}
if (IsVar(CurrToken.Value))
{
ResultNextToken = NUM;
TokenLen = Position - TokenLen;
return ResultNextToken;
}
else
{
ResultNextToken = BAD;
TokenLen = 0;
return ResultNextToken ;
}
}
else
{
switch(Ch)
{
case '+' : ResultNextToken = PLUS; break;
case '-' : ResultNextToken = MINUS; break;
case '*' : ResultNextToken = TIMES; break;
case '/' : ResultNextToken = DIVIDE;break;
case '%' : ResultNextToken = MODU; break;
case '^' : ResultNextToken = EXPO; break;
case '(' : ResultNextToken = OPAREN;break;
case ')' : ResultNextToken = CPAREN;break;
default : ResultNextToken = BAD;
TokenLen = 0;
return ResultNextToken ;
}
Position++;
TokenLen = Position - TokenLen;
return ResultNextToken ;
}
}
void TMathParser::Pop(TokenRec &Token)
{
Token = Stack[StackTop];
StackTop--;
}
void TMathParser::Push(TokenRec Token)
{
if (StackTop == ParserStackSize-1)
{
TokenError = ErrParserStack;
}
else
{
StackTop++;
Stack[StackTop] = Token;
}
}
void TMathParser::Parse()//{ Parses an input stream }
{
TokenRec FirstToken ;
BOOL Accepted;
Position = 1;
StackTop = -1;
TokenError = 0;
MathError = FALSE;
ParseError = FALSE;
Accepted = FALSE;
FirstToken.State= 0;
FirstToken.Value= 0;
Push(FirstToken);
TokenType = NextToken();
do{
switch(Stack[StackTop].State)
{
case 0:
case 9:
case 12:
case 13:
case 14:
case 15:
case 16:
case 20:
case 40 :
{//begin
if (TokenType == NUM)
Shift(10);
else if (TokenType == FUNC)
Shift(11);
else if (TokenType == MINUS)
Shift(5);
else if (TokenType == OPAREN)
Shift(9);
else if (TokenType == ERR)
{
MathError = TRUE;
Accepted = TRUE;
}
else
{
TokenError = ErrExpression;
Position -= TokenLen;
}
break;
}
case 1 :
{
if (TokenType == EOL)
Accepted = TRUE;
else if (TokenType == PLUS)
Shift(12);
else if (TokenType == MINUS)
Shift(13);
else
{
TokenError = ErrOperator;
Position -= TokenLen;
}
break;
}
case 2 :
{
if (TokenType == TIMES)
Shift(14);
else if (TokenType == DIVIDE)
Shift(15);
else
Reduce(3);
break;
}
case 3 :
{
if( TokenType == MODU)
Shift(40);
else
Reduce(6);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -