📄 expclass.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 + -