📄 evfunction.pas
字号:
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 + -