Newsgroup: it.comp.lang.delphi
Titolo: [D5] Valutatore di espressioni algebriche

Salve a tutto il ng,
mi chiamo Sara, ho necessità di realizzare un algoritmo di tipo parser a
discesa ricorsiva per la creazione di un valutatatore di espressioni (tipo
1+4*5/6) sapreste dirmi dove posso trovare degli esempi di codice o articoli
che ne parlano, oppure darmi qualche consiglio in merito?
Vi ringrazio Sara

> mi chiamo Sara
E allora xche sulla Mail troviamo il nome Mauro Roversi???  :)))
Vedi sulle faq.
Bye
AS

 wrote in message
news:aau66r$58m$
1...@newsreader.mailgate.org

unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs,
  StdCtrls;
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
const tkNULL   = #00;
      tkNUMBER = #01;
      tkPLUS   = '+';
      tkMINUS  = '-';
      tkMUL    = '*';
      tkDIV    = '/';
      tkLP     = '(';
      tkRP     = ')';
var
  CurrentToken: Char;
  NumberValue: Double;
  ExprStr: String;
procedure GenerateError(Msg: String);
begin
  raise Exception.Create(Msg);
end;
function Expression(GetFlag: Boolean): Double; forward;
procedure GetToken;
var
  NumStr: String;
begin
  if (ExprStr = '') then
    CurrentToken := tkNULL
  else
  if (ExprStr[1] in ['0'..'9']) then
  begin
    NumStr := '';
    while ((ExprStr <> '') and
           (ExprStr[1] in ['0'..'9'])) do
    begin
      NumStr := NumStr + ExprStr[1];
      Delete(ExprStr, 1, 1);
    end;
    NumberValue := StrToFloat(NumStr);
    CurrentToken := tkNUMBER;
  end
  else
  if (ExprStr[1] in ['+', '-', '*', '/', '(', ')']) then
  begin
    case ExprStr[1] of
       '+' : CurrentToken := tkPLUS;
       '-' : CurrentToken := tkMINUS;
       '*' : CurrentToken := tkMUL;
       '/' : CurrentToken := tkDIV;
       '(' : CurrentToken := tkLP;
       ')' : CurrentToken := tkRP;
    end;
    Delete(ExprStr, 1, 1);
  end
  else
    CurrentToken := tkNULL;
end;
function Prim(GetFlag: Boolean): Double;
var
  V: Double;
begin
  if (GetFlag) then GetToken;
  case CurrentToken of
    tkNUMBER : begin
                 V := NumberValue;
                 GetToken;
                 Result := V;
                 Exit;
               end;
    tkMINUS  : begin
                 Result := -Prim(True);
               end;
    tkLP     : begin
                 V := Expression(True);
                 if (CurrentToken <> tkRP) then
                   GenerateError('Errore: attesa )');
                 GetToken;
                 Result := V;
                 Exit;
               end;
  else
    GenerateError('Errore di sintassi!');
  end
end;
function Term(GetFlag: Boolean): Double;
var
  D, Left: Double;
begin
  Left := Prim(GetFlag);
  while (True) do
  begin
    case CurrentToken of
      tkMUL : Left := Left * Prim(True);
      tkDIV : begin
                D := Prim(True);
                if (D = 0) then
                  GenerateError('Divisione per zero!');
                Left := Left / D;
              end;
    else
      begin
        Result := Left;
        Exit
      end
    end
  end
end;
function Expression(GetFlag: Boolean): Double;
var
  Left: Double;
begin
  Left := Term(GetFlag);
  while (True) do
  begin
    case (CurrentToken) of
      tkPLUS  : Left := Left + Term(True);
      tkMINUS : Left := Left - Term(True);
    else
      begin
        Result := Left;
        Exit;
      end
    end
  end
end;
function NoSpaces(S: String): String;
var
  I: Integer;
begin
  Result := '';
  for I := 1 to Length(S) do
  begin
    if S[I] <> ' ' then
    begin
      Result := Result + S[I];
    end;
  end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  ExprStr := NoSpaces(Edit1.Text);
  Edit2.Text := FloatToStr(Expression(True));
end;
end.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG