델파이 eval 함수 비슷하게 구현 > Visual Basic, C & C++

본문 바로가기
사이트 내 전체검색


회원로그인

오늘 111
어제 157
최대 618
전체 326,269
마음을 나누는 인터넷 일기장 - 통플 다이어리
Visual Basic, C & C++

Delphi | 델파이 eval 함수 비슷하게 구현

페이지 정보

작성자 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 작성일13-11-13 15:17 조회8,422회 댓글0건

본문

{

 You asked for something simple. But to evaluate an expression it's not that simple 'cause

 it envolves parsing a string and deal with all those tokens within an expression.

 // 

 Now. It's done. It is that simple..

 //

 Label.Caption := IntToStr( Eval( '(10   -2) + 50   (3+5)' ));

 //

 As you see this code supports parenteses and negative numbers.

 //





}





//>>>>

// This a support unit...

unit Stack;



INTERFACE



Uses Windows, Classes;



Const

  // This is more than enough for an expression.

  MaxStackSize = 1023;



Type

  TStack  =  class( TObject )

  private

     items : Array[0..MaxStackSize] of Integer;

     StkPtr : Integer;

  public

     procedure Reset;

     procedure AddItem( Item : Integer );

     function GetItem : Integer;

     function StackSize : Integer;

     function TestItem : Integer;

  end;



implementation



procedure TStack.Reset;

 StkPtr := MaxStackSize;

end;



procedure TStack.AddItem( Item : Integer );

begin

 Items[ StkPtr ] := Item;

 Dec( StkPtr );

end;



function TStack.GetItem : Integer;

begin

 Inc( StkPtr );

 GetItem := Items[ StkPtr ];

end;



function TStack.TestItem : Integer;

begin

 TestItem := Items[ StkPtr + 1 ];

end;



function TStack.StackSize : Integer;

begin

 StackSize := MaxStackSize - StkPtr;

end;



end.

// eof support unit

//>>>





//>>>

//  This is the main program...

// There is a label and a button on this form..

//

unit EvalUnit1;

interface



uses

 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Stack,

 StdCtrls;





Const

  Number = 0;

  TokError = 1;

  Plus = 2;

  Minus = 3;

  Times = 4;

  Divide = 5;

  LParen = 6;

  RParen = 7;



type

 TForm1 = class(TForm)

   Label1: TLabel;

   Button1: TButton;

   procedure FormDestroy(Sender: TObject);

   procedure FormCreate(Sender: TObject);

   procedure Button1Click(Sender: TObject);

 private

    Expression  : String;

    i, Code     : Integer;

    TokenPos    : Integer;

    Token       : String;

    TokenType   : Integer;

    MinusFlag   : Boolean;

    Arg1,Arg2   : Integer;

    procedure GetToken;

    function Eval( ExpressionToEvaluate : String ) : Integer;

 public

    Numbers     : TStack;

    Operators   : TStack;

 end;



var

 Form1: TForm1;



implementation

{$R  .DFM}



{Get the token the expression string}

procedure TForm1.GetToken;

begin

 {Clear the token string }

 Token := '';

 { if the expression has a digit, it's a number }

 if ( Ord( Expression[TokenPos]) >= Ord('0'))

     AND ( Ord( Expression[TokenPos] ) <= Ord('9')) then

  begin

       { Keep getting digits }

       repeat

          Token := Token + Expression[TokenPos];

          Inc(TokenPos);

       until ( Ord(Expression[TokenPos] ) < Ord('0'))

               or ( Ord(Expression[TokenPos] ) > Ord('9'))

               or ( TokenPos > Length( Expression ));

       { Mark the token Type as a Number }

       TokenType := Number;

     end

     { See if it's a plus sign }

     else if Expression[ TokenPos ] = '+' then

     begin

       TokenType := Plus;

       Inc( TokenPos );

     end

     { See if it's minus sign }

     else if Expression[ TokenPos ] = '-' then

     begin

       TokenType := Minus;

       Inc( TokenPos );

     end

     { See if it's a multiply sign }

     else if Expression[ TokenPos ] = ' ' then

     begin

       TokenType := Times;

       Inc( TokenPos );

     end

     { See if it's a divide sign }

     else if Expression[ TokenPos ] = '/' then

     begin

       TokenType := Times;

       Inc( TokenPos );

     end

     { See if it's a left parent sign }

     else if Expression[ TokenPos ] = '(' then

     begin

       TokenType := LParen;

       Inc( TokenPos );

     end

     { See if it's a right parent sign }

     else if Expression[ TokenPos ] = ')' then

     begin

       TokenType := RParen;

       Inc( TokenPos );

     end

     { None of that. So it's a junk }

     else

        TokenType := TokError;

end;



Function StripOff( ch : char; Str : String ) : String;

Var

 posi : byte;

begin

 posi := Pos( ch, str );

 while posi <> 0 do

 begin

   posi := Pos( ch, str );

   delete( str, posi, 1 );

 end;

 Result := str;

end;





function TForm1.Eval( ExpressionToEvaluate : String ) : Integer;

begin

  { Initialize the number and operator stacks }

  TokenPos := 1;



  { Make sure is something at the operators stack }

  Operators.AddItem( LParen );



  { Set the stack pointer }

  Numbers.Reset;

  Operators.Reset;



  { Strip all the spaces off } 

  Expression := StripOff(' ', ExpressionToEvaluate );





  while TokenPos <= Length( Expression ) do

  begin

     GetToken;

     While TokenType = LParen do

     begin

       Operators.AddItem( LParen );

       GetToken;

     end;

     { Check for negative number }

     if TokenType = Minus then

     begin

        MinusFlag := true;

        GetToken;

     end

     else

        MinusFlag := false;

     if TokenType = Number then

     begin

       Val( Token, i, code );

       if MinusFlag then

          i := -i;

       Numbers.AddItem( i );

       { See if at the end of the expression }

       if TokenPos <= Length( Expression ) then

       begin

         { Get the operators }

         repeat

            GetToken;

            if Operators.TestItem <>  LParen then

               { Do operations of higher precedence up to the left paren }

               while ( Operators.TestItem <> LParen ) and

                       ((( Operators.TestItem DIV 2 ) >= ( TokenType DIV 2 ))

                       or ( TokenType = RParen )) do

                       begin

                         Arg1 := Numbers.GetItem;

                         Arg2 := Numbers.GetItem;

                         case Operators.GetItem of

                              Plus   : Numbers.AddItem( Arg2 + Arg1 );

                              Minus  : Numbers.AddItem( Arg2 - Arg1 );

                              Times  : Numbers.AddItem( Arg2   Arg1 );

                              Divide : Numbers.AddItem( Arg2 DIV Arg1 );

                         end;

                       end;

                       if TokenType = RParen then

                          i := Operators.GetItem;

         until ( TokenType <> RParen )

                 or ( TokenPos >= Length( Expression ));

         Operators.AddItem( TokenType );

         end;

         end

         else

            TokenType := TokError;

         if Tokentype = TokError then

         begin

            TokenPos := Length( Expression ) + 1;

            Numbers.AddItem( 0 );

         end;

      end;

      while Operators.StackSize > 1 do

      begin

        Arg1 := Numbers.GetItem;

        Arg2 := Numbers.GetItem;

        repeat

           i := Operators.GetItem;

        until ( i <> LParen ) and ( i <> RParen );

        case i of

           Plus   : Numbers.AddItem( Arg2 + Arg1 );

           Minus  : Numbers.AddItem( Arg2 - Arg1 );

           Times  : Numbers.AddItem( Arg2   Arg1 );

           Divide : Numbers.AddItem( Arg2 DIV Arg1 );

       end;

    end;

    Result := Numbers.GetItem;

end;





// Link this to FormDestroy method..

procedure TForm1.FormDestroy(Sender: TObject);

begin

    Numbers.Free;

    Operators.Free;

end;



// Link this to FormCreate method..

procedure TForm1.FormCreate(Sender: TObject);

begin

    Numbers := TStack.Create;

    Operators := TStack.Create;

end;



// And this to Button1Click...

procedure TForm1.Button1Click(Sender: TObject);

begin

    Label1.Caption := IntToStr( Eval( '(10   -2) + 50   (3+5)' ));

end;





end.




 There it is... Hope it helps.







 Reginaldo Ap. Rigo

 São Paulo, SP Brazil

 virtual@alphanet.com.br





 )

추천 0

댓글목록

등록된 댓글이 없습니다.

Visual Basic, C & C++ 목록

Total 31건 1 페이지
Visual Basic, C & C++ 목록
번호 제목 글쓴이 날짜 조회 추천
31 Delphi [델파이] Frame의 속성 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 06-01 724 0
30 Delphi 델파이 날짜구현 함수 모음들 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 09-06 2496 0
29 Delphi 델파이 팁들 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 09-06 3374 0
28 Delphi [radstudio] 배포시 독립 실행 파일 만들기 인기글첨부파일 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 09-04 2634 0
27 Delphi Delphi 2007 Debug running 중 "bordbk105N.dll"오류 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 02-18 4338 0
26 Delphi 윈도+델파이 환경에서 리눅스용 실행파일을 만들 수 있다는 CrossKylix 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 04-02 8032 0
25 Delphi [펌] 델파이 객체지향프로그래밍을 위한 20가지 규칙 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 12-26 11431 0
24 Delphi Rad XE2 ~ XE4 에서 mysql 5.5 ~ 5.6 libmysql 인기글첨부파일 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 12-04 9309 0
23 Delphi 델파이에서 날짜 더하고 빼기 예제 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11-20 10051 0
22 Delphi EDIT 컴포넌트 숫자만 입력, 오른쪽 정렬 등등 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11-20 11917 0
21 Delphi Edit에 수치값만 입력 가능하게(소수, 음수입력 가능) 자리수 제한 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11-19 10520 0
20 Delphi [펌] TChart 기본정보 및 사용팁 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11-18 9517 0
19 Delphi [펌] 폼 크기에 맞게 자동으로 컴포넌트 크기 조절하기 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11-18 9637 0
18 Delphi [펌] 델파이 기본 컴포넌트2 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11-18 10724 0
17 Delphi [펌] 델파이 기본 컴포넌트1 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11-18 10847 0
16 Delphi 델파이에서 ie 창 띄우기 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11-13 10270 0
15 Delphi [양병규님 세미나 자료] 계산기 소스 인기글첨부파일 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11-13 11516 0
열람중 Delphi 델파이 eval 함수 비슷하게 구현 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11-13 8423 0
13 Delphi Firebird 포트 넘버 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11-13 8070 0
12 Delphi zeos설치하기 인기글 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10-28 7420 0
게시물 검색

Copyright © nuno21.net All rights reserved. 상단으로
모바일 버전으로 보기