Newsgroup: it.comp.lang.delphi
Titolo: Parser in Delphi

Devo realizzare un parser di funzioni matematiche in Delphi (senza
usare componente, programma console, ecc.). Qualcuno di voi potrebbe
darmi un suggerimento? Finora ho realizzato un piccolo parser talmente
minimale che riconosce espressioni del tipo a+b [+ le altre 3
operazioni fondamentali] dove a e b sono singole cifre e non numeri.
----
Lawrence "Rhymes" Oluyede
rhy...@myself.com


scusa Espressioni nn Funzioni.

 non numeri. 
vualà:
http://www.latrobe.edu.au/philosophy/phimvt/s00bok.html
un intero libro sull'argomento
-- 
Nato nel vizio, morto nel supplizio
Nato nel peccato, ad entrare sia invitato

un intero libro sull'argomento
grazie..


operazioni fondamentali] dove a e b sono singole cifre e non numeri.
Esempio di parser a discesa ricorsiva:
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.
-- 
The Follet

Grazie per il codice ma non è che potresti commentarlo ? ^_^
----
Lawrence "Rhymes" Oluyede
rhy...@myself.com
"Quando un uomo siede un'ora in compagnia di una bella ragazza,
sembra sia passato un minuto. Ma fatelo sedere su una stufa
per un minuto e gli sembrerà più lungo di qualsiasi ora.
Questa è la relatività".
Albert Einstein