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

📄 expclass.pas

📁 一个简单的表达式解析器 Delphi版
💻 PAS
字号:
unit expclass;

interface
uses
  SysUtils;

type
  TExpression = class
  private
    CurPos: integer;    MaxPos: integer;    iExp: string;    token: string;    function IsDigit(ch: char):boolean;    function IsLetter(ch: char):boolean;    function CheckExp:boolean;      // 首先对表达式进行检查    function gettoken:integer;    function term:extended;    function factor:extended;
  public    oResok: boolean;        constructor Create(AExpression: PChar);    function Calc:extended;  end;const  ID     = 1;   // var  NUM    = 2;   // numbers  PLUS   = 3;   // '+'  MINUS  = 4;   // '-'  TIMERS = 5;   // '*'  OVER   = 6;   // '/'  LPAREN = 7;   // '('  RPAREN = 8;   // ')'  POWER  = 9;   // '^'  ERROR  = 255; // Errors  OPS    = '+-*/()^';  // Opratorsimplementationfunction TExpression.IsLetter(ch: Char):boolean;
begin
  result := (ch in ['a'..'z']) or (ch in ['A'..'Z']);
end;

function TExpression.IsDigit(ch: Char):boolean;
begin
  result := (ch in ['0'..'9']) or (ch = '.');
end;

// Get Token and Token Type from curPos
function TExpression.gettoken:integer;
var
  Skip: boolean;
begin
  result := ERROR;
  Skip := False;          // 指示是否忽略指针移动
  token := '';
  while (CurPos <= MaxPos) and (iExp[CurPos] = ' ') do inc(CurPos);

  // 加入对负号的处理:如果前次token为 '(',或第一个符号就是'-',则减号是负号
  if Pos(iExp[CurPos],OPS)>0 then begin
    case iExp[CurPos] of
      '+': result := PLUS;
      '-':
        begin
          if (CurPos > 1) and (iExp[CurPos-1] <> '(') then
            result := MINUS
          else begin
            token := '-';
            inc(CurPos);
            while (CurPos <= MaxPos) and IsDigit(iExp[CurPos]) do begin
              token := token + iExp[CurPos];
              inc(CurPos);
            end;

            Skip := True;
            result := NUM;
          end;
        end;
      '*': result := TIMERS;
      '/': result := OVER;
      '(': result := LPAREN;
      ')': result := RPAREN;
      '^': result := POWER;
    end;
    if not Skip then inc(CurPos);
  end else begin
    if IsLetter(iExp[CurPos]) then begin
      while (CurPos <= MaxPos) and (IsLetter(iExp[CurPos]) or IsDigit(iExp[CurPos])) do begin
        token := token + iExp[CurPos];
        inc(CurPos);
      end;
      result := ID;
    end else if IsDigit(iExp[CurPos]) then begin
      while (CurPos <= MaxPos) and IsDigit(iExp[CurPos]) do begin
        token := token + iExp[CurPos];
        inc(CurPos);
      end;
      result := NUM;
    end;
  end;

  if result = ERROR then oResok := false;
end;

function TExpression.term:extended;
var
  temp: extended;
begin  result := factor();  while (CurPos <= MaxPos) and ((iExp[CurPos] = '*') or (iExp[CurPos] = '/')) do begin    case gettoken() of      TIMERS:        result := result * factor();      OVER:        begin          temp := factor;          if temp <> 0 then            result := result / temp          else begin            oResok := false;            result := 0;          end;        end;    end;  end;end;

function TExpression.factor():extended;
begin  result := 0.0;  case gettoken() of    NUM:      result := StrtoFloatDef(token,0);    LPAREN:      begin        result := calc;        if gettoken() <> RPAREN then begin          oResok := false;          result := 0;        end;      end;    ID:      begin      end;  end;end;

function TExpression.CheckExp: boolean;
begin
  result := true;
end;

constructor TExpression.Create(AExpression: PChar);
begin
  iExp := string(AExpression);
  CurPos := 1;
  MaxPos := Length(iExp);
  oResok := CheckExp;
end;

function TExpression.Calc:extended;
begin
  if oResok then begin
    result := term();
    while (CurPos <= MaxPos) and ((iExp[CurPos] = '+') or (iExp[CurPos] = '-')) do begin
      case gettoken() of
        PLUS:
          result := result + term();
        MINUS:
          result := result - term();
      end;
    end;
  end else
    result := 0;
end;

end.

⌨️ 快捷键说明

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