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

📄 evfunction.pas

📁 表达式计算DEMO 利用词法分析器原理 以及后缀表达式计算 暂不支持函数以及乘号省略
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit EvFunction;

interface

uses
  SysUtils, Classes, Contnrs;

type
    TTokenType = (
      tkNumber,
      tkAdd,
      tkSub,
      tkMul,
      tkDiv,
      tkLBracket,
      tkRBracket);

    PToken = ^TToken;
    TToken = record
      Token: TTokenType;
      DValue: Double;
    end;

procedure Push(Stack: TStack;
               sData: String);
function Pop(Stack: TStack): String;
function Peek(Stack: TStack): String;
function IsEmpty(Stack: TStack): Boolean;
function CompareSymbol(SymA, SymB: String): Boolean;
function NewToken(Token: PToken): PToken;
function ParseExpression(InExpr: String;
                         InList: TList): Integer;
function InsideToSuffix(InList: TList): String;
function Evaluate(SuExpr: String): Double;

implementation

procedure Push(Stack: TStack;
               sData: String);
begin
     Stack.Push(StrNew(PChar(sData)));
end;

function Pop(Stack: TStack): String;
begin
     Result := StrPas(PChar(Stack.Pop));
end;

function Peek(Stack: TStack): String;
begin
     Result := StrPas(PChar(Stack.Peek));
end;

function IsEmpty(Stack: TStack): Boolean;
begin
     Result := Stack.Count = 0;
end;

function CompareSymbol(SymA, SymB: String): Boolean;
begin
     Result := True;
     Case SymA[1] of
       '*',
       '/': if SymB[1] in ['*', '/'] then
               Result := False;
     end;
end;

function NewToken(Token: PToken): PToken;
var
   Size: Integer;
begin
     Size := SizeOf(Token^);
     GetMem(Result, Size);
     Move(Token^, Result^, Size);
end;

function ParseExpression(InExpr: String;
                         InList: TList): Integer;
var
   Token: TToken;
   sTemp: String;
   IsExists: Boolean;
   I, iLen, iBracket: Integer;
   NextToken: set of TTokenType;
begin
     I := 1;
     Result := 0;
     iBracket := 0;
     iLen := Length(InExpr);
     NextToken := [tkNumber, tkLBracket];
     While I <= iLen do
           begin
                Case InExpr[I] of
                  '0'..'9': begin
                                 sTemp := '';
                                 IsExists := False;
                                 if not (tkNumber in
                                        NextToken) then
                                    begin
                                         Result := I;
                                         InList.Clear;
                                         Break;
                                    end;
                                 While I <= iLen do
                                       begin
                                            Case InExpr[I] of
                                              '0'..'9': sTemp := sTemp +
                                                                 InExpr[I];
                                              '.': if IsExists then
                                                      begin
                                                           Result := I;
                                                           I := iLen;
                                                           InList.Clear;
                                                           Break;
                                                      end
                                                      else
                                                      begin
                                                           sTemp := sTemp +
                                                                    InExpr[I];
                                                           IsExists := True;
                                                      end;
                                              else begin
                                                        Dec(I);
                                                        Break;
                                                   end;
                                            end;
                                            Inc(I);
                                       end;
                                 if sTemp[Length(sTemp)] = '.' then
                                    begin
                                         Result := I;
                                         InList.Clear;
                                         Break;
                                    end;
                                 Token.Token := tkNumber;
                                 Token.DValue := StrToFloat(sTemp);
                                 InList.Add(NewToken(@Token));
                                 NextToken := [tkAdd,
                                               tkSub,
                                               tkMul,
                                               tkDiv,
                                               tkRBracket];
                            end;
                  '+': begin
                            if not (tkAdd in
                                   NextToken) then
                               begin
                                    Result := I;
                                    InList.Clear;
                                    Break;
                               end;
                            Token.Token := tkAdd;
                            InList.Add(NewToken(@Token));
                            NextToken := [tkNumber,
                                          tkLBracket];
                       end;
                  '-': begin
                            if not (tkSub in
                                   NextToken) then
                               begin
                                    Result := I;
                                    InList.Clear;
                                    Break;
                               end;
                            Token.Token := tkSub;
                            InList.Add(NewToken(@Token));
                            NextToken := [tkNumber,
                                          tkLBracket];
                       end;
                  '*': begin
                            if not (tkMul in
                                   NextToken) then
                               begin
                                    Result := I;
                                    InList.Clear;
                                    Break;
                               end;
                            Token.Token := tkMul;
                            InList.Add(NewToken(@Token));
                            NextToken := [tkNumber,
                                          tkLBracket];
                       end;
                  '/': begin
                            if not (tkDiv in
                                   NextToken) then
                               begin
                                    Result := I;
                                    InList.Clear;
                                    Break;
                               end;
                            Token.Token := tkDiv;
                            InList.Add(NewToken(@Token));
                            NextToken := [tkNumber,
                                          tkLBracket];
                       end;
                  '(': begin
                            if not (tkLBracket in
                                   NextToken) then
                               begin
                                    Result := I;
                                    InList.Clear;
                                    Break;
                               end;
                            Inc(iBracket);
                            Token.Token := tkLBracket;
                            InList.Add(NewToken(@Token));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -