Interpréteur Notation Polonaise Inverse
Bonjour a tous,
etant donné le niveau élevé, je n'ai encore rien contribué ici :lol:
Mais dans un soft que je développe (gestion de persos D&D 3.5 pour ceux que çà intéresse), j'avais besoin de pouvoir taper des formules de calcul assez complexes et pas vraiment l'envie de faire un analyseur syntaxique (surtotu que je sais pas comment faire :oops:). Du coup, j'ai fait un petit interpreteur ne NPI qui va rappeler de bon souvenirs aux anciens possesseurs de calculateurs HP (10, 12, 15, 41).
Pour l'explication de la NPI :http://fr.wikipedia.org/wiki/Notation_polonaise_inverse
Le code source est ici :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
function npi(formule : string) : string;
var pile : tstringlist;
s : string;
function npioperation : string;
var operande2 , operande1 : string;
begin
if pile.Count > 0 then operande1 := pile.Strings[pile.Count - 2] else operande1 := '0';
if pile.Count > 1 then operande2 := pile.Strings[pile.Count - 1] else operande2 := '0';
pile.Delete(pile.Count - 1);
pile.Delete(pile.Count - 1);
case s[1] of
'+' : result := inttostr(strtoint(operande1) + strtoint(operande2));
'-' : result := inttostr(strtoint(operande1) - strtoint(operande2));
'*' : result := inttostr(strtoint(operande1) * strtoint(operande2));
'/' : result := inttostr(trunc(strtoint(operande1) / strtoint(operande2)));
'^' : result := inttostr(trunc(intpower(strtoint(operande1) , strtoint(operande2))));
end;
pile.Add(result);
end;
begin
result := '';
pile := tstringlist.Create; pile.Add('0');pile.Add('0');
while formule <> '' do
begin
if pos(' ' , formule) < 1 then
begin
s := formule;
formule := '';
end else
begin
s := copy(formule , 1 , pos(' ' , formule) - 1);
delete(formule , 1 , pos(' ' , formule));
end;
case s[1] of
'0'..'9' : pile.Add(s);
'+','-','/','*','^' : npioperation;
else
begin
result := 'Erreur';
showmessage('Erreur : operateur ' + s + ' Inconnu');
pile.Free;
exit;
end;
end;
end;
result := pile.Strings[pile.Count - 1];
pile.Clear;
pile.Free;
end; |
Les remarques :
- D'abord çà gère pas les nombres décimaux, mais les moifs à faire sont pas énormes
- je ne gère que les 4 ops de base et l'élévation à la puissance entière, mais les évols doivent pas être dures a faire
- Y a pas de fonction de manipulation de la pile, mais çà aussi ca doit pas être compliqué
- le contrôle de syntaxe est pas très poussé
Pour utiliser :
Code:
1 2
|
resultat := npi('2 3 4 + 4 * +') |
vous renverra 30 ce qui est effectivement le résultat de
2 + (4 * (3 + 4))
Amusez vous bien et merci a tous ceux qui ont déjà contribué.