⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mathparser.cpp

📁 自定义的报表
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------------
#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 + -