// ȸéÀÇ Edit1ÀÇ Text¿¡ sqrt(43.23*12+3.1/1.64) ¸¦ ÀÔ·ÂÇϰí
// ¹öưÀ» Ŭ¸¯ÇÏ½Ã¸é ±× °á°ú¸¦ °è»êÇØ¼ º¸¿©ÁÝ´Ï´Ù
// ¸¸¾à À߸øµÈ ¼ö½ÄÀÌ¸é ¿¡·¯³ ¹®ÀÚ·Î ÄÉ·µÀ» À̵¿½Ãŵ´Ï´Ù
//
// ¼Ò½º Ãâó: http://www.geocities.com/SiliconValley/Hills/9167/index.htm
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, forms, Dialogs,
StdCtrls;
type
Tform1 = class(Tform)
Edit1: TEdit;
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
form1: Tform1;
implementation
{$R *.DFM}
procedure Eval(formula: String; {Expression to be evaluated}
var Value: double; {Return value}
var ErrPos: Integer); {error position}
const
Digit: Set of Char = ['0'..'9'];
var
Posn: Integer; {Current position in formula}
CurrChar: Char; {character at Posn in formula}
procedure ParseNext;
begin
repeat
Posn := Posn+1;
if Posn <= Length(formula) then
CurrChar := formula[Posn]
else
CurrChar := ^M;
until CurrChar<>' ';
end {ParseNext};
function add_subt: Real;
var
E: Real;
Opr: Char;
function mult_DIV: Real;
var
S : Real;
Opr : Char;
function Power: Real;
var
T : Real;
function Signedop: Real;
function Unsignedop: Real;
type
StdFunc = (fabs, fsqrt, fsqr, fsin, fcos,
farctan, fln, flog, fexp, ffact);
StdFuncList = array[StdFunc] of String[6];
const
StdFuncName: StdFuncList =
('ABS','SQRT','SQR','SIN','COS',
'ARCTAN','LN','LOG','EXP','FACT');
var
E, L, Start : Integer;
Funnet : Boolean;
F : Real;
Sf : StdFunc;
function Fact(I: Integer): Real;
begin
if I > 0 then
begin
Fact := I*Fact(I-1);
end
else
Fact := 1;
end {Fact};
begin {function Unsignedop}
if CurrChar in Digit then
begin
Start := Posn;
repeat
ParseNext
until not (CurrChar in Digit);
if CurrChar = '.' then
repeat
ParseNext
until not (CurrChar in Digit);
if CurrChar = 'E' then
begin
ParseNext;
repeat
ParseNext
until not (CurrChar in Digit);
end;
Val(Copy(formula,Start,Posn-Start),F,ErrPos);
end
else if CurrChar = '(' then
begin
ParseNext;
F := add_subt;
if CurrChar=')' then
ParseNext
else
ErrPos := Posn;
end
else
begin
Funnet := False;
for sf := fabs tO ffact do
if not Funnet then
begin
l := Length(StdFuncName[sf]);
if Copy(formula,Posn,l)=StdFuncName[sf] then
begin
Posn := Posn+l-1;
ParseNext;
f := Unsignedop;
case sf of
fabs: f := abs(f);
fsqrt: f := SqrT(f);
fsqr: f := Sqr(f);
fsin: f := Sin(f);
fcos: f := Cos(f);
farctan: f := ArcTan(f);
fln : f := LN(f);
flog: f := LN(f)/LN(10);
fexp: f := EXP(f);
ffact: f := fact(Trunc(f));
end;
Funnet := True;
end;
end;
if not Funnet then
begin
ErrPos := Posn;
f := 0;
end;
end;
Unsignedop := F;
end {Unsignedop};
begin {Signedop}
if CurrChar='-' then
begin
ParseNext;
Signedop := -Unsignedop;
end
else
Signedop := Unsignedop;
end {Signedop};
begin {Power}
T := Signedop;
while CurrChar='^' do
begin
ParseNext;
if t <> 0 then
t := EXP(LN(abs(t))*Signedop)
else
t := 0;
end;
Power := t;
end {Power};
begin {mult_DIV}
s := Power;
while CurrChar in ['*','/'] do
begin
Opr := CurrChar;
ParseNext;
case Opr of
'*': s := s * Power;
'/': s := s / Power;
end;
end;
mult_DIV := s;
end {mult_DIV};
begin {add_subt}
E := mult_DIV;
while CurrChar in ['+','-'] do
begin
Opr := CurrChar;
ParseNext;
case Opr of
'+': e := e + mult_DIV;
'-': e := e - mult_DIV;
end;
end;
add_subt := E;
end {add_subt};
begin {PROC Eval}
if formula[1] = '.' then
formula := '0' + formula;
if formula[1]='+' then
Delete(formula,1,1);
for Posn:=1 to Length(formula) do
formula[Posn] := Upcase(formula[Posn]);
Posn := 0;
ParseNext;
Value := add_subt;
if CurrChar=^M then
ErrPos := 0
else
ErrPos := Posn;
end {PROC Eval};
procedure Tform1.Button1Click(Sender: TObject);
var
Value: double;
ErrPos: Integer;
begin
Eval(Edit1.Text, Value, ErrPos);
Label1.Caption := FloatToStr(Value); // °á°ú°ª
if ErrPos > 0 then // ¿¡·¯°¡ ÀÖ´Ù¸é ÇØ´ç ¹®ÀڷΠij·µÀ» À§Ä¡ ½ÃŲ´Ù
begin
Edit1.SetFocus;
{µÎ¹øÂ° ¹®ÀÚ À§Ä¡·Î Ä¿¼¸¦ º¸³½´ë}
Edit1.SelStart := ErrPos - 1;
{¹®ÀÚ¸¦ ¼±ÅÃÇÏÁö ¾ÊÀº »óÅ·Π¸¸µç´Ù}
Edit1.SelLength := 0;
end;
end;
end. |
|