Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1857 connectés 

  FORUM HardWare.fr
  Programmation
  Algo

  Calculette qui prend et retourne une chaîne de caractères

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Calculette qui prend et retourne une chaîne de caractères

n°2029081
Profil sup​primé
Posté le 13-10-2010 à 20:48:29  answer
 

Je réalise une calculette qui prend une chaîne de caractères et je voulais avoir votre avis sur un algo.
Je prend une chaîne de caractères et je retourne une chaîne de caractères.
j'ai à ma disposition un thread qui réalise toute les opérations mathématiques primitives voulues.
Merci pour votre aide.

mood
Publicité
Posté le 13-10-2010 à 20:48:29  profilanswer
 

n°2029109
breizhbugs
Posté le 13-10-2010 à 22:10:21  profilanswer
 

Je vois rien qui ressemble a un algo...

n°2029129
Profil sup​primé
Posté le 14-10-2010 à 01:44:39  answer
 

Code :
  1. function Compute(Eq : in String) return String is
  2.      Rest : access String := new String '("" );
  3.      Buffer : access String := new String '("" );
  4.      Close, Open : Natural := 0;
  5.  
  6.   begin
  7.      if Eq'Length = 0 then
  8.         return "néant";
  9.      end if;
  10.      for I in reverse Eq'Range loop
  11.         if Eq(I) = '(' then
  12.            Open := I;
  13.            exit;
  14.         end if;
  15.      end loop;
  16.      if Open /= 0 then
  17.         for I in Eq'Range loop
  18.            if Eq(I) = ')' then
  19.               Close := I;
  20.               exit;
  21.            end if;
  22.         end loop;
  23.         if Close = 0 then
  24.            return "vous avez oublié de fermer la paranthèse";
  25.         end if;
  26.         if Close > Open + 1 then
  27.            buffer := new String ' (Compute(Eq(Open+1..Close-1)));
  28.         else
  29.            return "néant n'est pas allouable entre paranthèse";
  30.         end if;
  31.  
  32.  
  33.         rest := new String ' (Compute(Eq(Eq'First..Open-1) &
  34.                                         Buffer.all &
  35.                                         Eq(Close+1..Eq'Last)));
  36.      else
  37.           Rest := new String ' ("calculer eq" );
  38.      end if;
  39.      return Rest.all;
  40.   end Compute;

n°2029135
Profil sup​primé
Posté le 14-10-2010 à 02:26:55  answer
 

Code :
  1. function Compute(Eq : in String) return String is
  2.      Rest : access String := new String '("" );
  3.      Buffer : access String := new String '("" );
  4.      Close, Open : Natural := 0;
  5.  
  6.   begin
  7.      if Eq'Length = 0 then
  8.         return "néant";
  9.      end if;
  10.      for I in reverse Eq'Range loop
  11.         if Eq(I) = '(' then
  12.            Open := I;
  13.            exit;
  14.         end if;
  15.      end loop;
  16.      if Open /= 0 then
  17.         for I in Open+2..Eq'last loop
  18.            if Eq(I) = ')' then
  19.               Close := I;
  20.               exit;
  21.            end if;
  22.         end loop;
  23.         if Close = 0 then
  24.            return "vous avez oublié de fermer la paranthèse";
  25.         end if;
  26.         if Close > Open + 1 then
  27.            buffer := new String ' (Compute(Eq(Open+1..Close-1)));
  28.         else
  29.            return "néant n'est pas allouable entre paranthèse";
  30.         end if;
  31.         if Close < Eq'Last then
  32.            return Compute(Eq(Eq'First..Open-1) &
  33.                              Buffer.all &
  34.                             Eq(Close+1..Eq'Last));
  35.         else
  36.            return Compute(Eq(Eq'First..Open-1) & Buffer.all );
  37.         end if;
  38.      else
  39.         rest:= new String ' (Eq); -- calculer Eq ici
  40.      end if;
  41.      return Rest.all;
  42.   end Compute;


 

n°2029144
Profil sup​primé
Posté le 14-10-2010 à 06:23:45  answer
 

6 heures du mat, j'en suis là :

Code :
  1. function Compute(Eq : in String) return String is
  2.  
  3.      type Fixed_Point is delta 0.000_000_001 digits Max_digits range -9_999_999.0..9_999_999.0;
  4.      Locale : access String := new String '(Eq);
  5.      Rest : access String := new String '("" );
  6.      Buffer : access String := new String '("" );
  7.      Close, Open : Natural := 0;
  8.      Left  : Fixed_Point := 0.0;
  9.      Right : Fixed_Point := 0.0;
  10.      Top : Positive := locale'first;
  11.      Bot : Positive := locale'Last;
  12.   begin
  13.      if Locale'Length = 0 then
  14.         return "néant";
  15.      end if;
  16.      for I in reverse Locale'Range loop
  17.         if Locale(I) = '(' then
  18.            Open := I;
  19.            exit;
  20.         end if;
  21.      end loop;
  22.      if Open /= 0 then
  23.         for I in Open+2..Locale'last loop
  24.            if Locale(I) = ')' then
  25.               Close := I;
  26.               exit;
  27.            end if;
  28.         end loop;
  29.         if Close = 0 then
  30.            return "vous avez oublié de fermer la paranthèse";
  31.         end if;
  32.         if Close > Open + 1 then
  33.            buffer := new String ' (Compute(Locale(Open+1..Close-1)));
  34.         else
  35.            return "néant n'est pas allouable entre paranthèse";
  36.         end if;
  37.         if Close < Locale'Last then
  38.            return Compute(Locale(Locale'First..Open-1) &
  39.                             Compute(Buffer.all) &
  40.                             Locale(Close+1..Locale'Last));
  41.         else
  42.            return Compute(Locale(Locale'First..Open-1) & Compute(Buffer.all) );
  43.         end if;
  44.      else
  45.         New_Line;
  46.         Put_line("Top := " & Integer'Image(Top));
  47.         Put_line("Bot := " & Integer'Image(Bot));
  48.         for I in reverse Locale'Range loop
  49.            Put("I = " & Integer'Image(I));
  50.  
  51.            case Locale(I) is
  52.               when '+' =>
  53.                  if I > Top then
  54.                     Left := Fixed_point'Value(Compute(Locale(top..I-1)));
  55.                  else
  56.                     return Compute(Locale(I+1..Bot));
  57.                  end if;
  58.                  Right := Fixed_point'Value(Compute(Locale(I+1..bot)));
  59.                  return Fixed_point'Image(Left+Right);
  60.               when '-' =>
  61.                  if I > Top then
  62.                     left := Fixed_point'Value(Compute(Locale(top..I-1)));
  63.                  else
  64.                     return Fixed_point'Image(Fixed_point'Value(Locale(I..bot)));
  65.                  end if;
  66.                  Right := Fixed_point'Value(Compute(Locale(I+1..bot)));
  67.                  return Fixed_point'Image(Left-Right);
  68.               when '/' =>
  69.                  Left := Fixed_point'Value(Compute(Locale(top..I-1)));
  70.                  Right := Fixed_point'Value(Compute(Locale(I+1..bot)));
  71.                  return Fixed_point'Image(Left/Right);
  72.               when '*' =>
  73.                  Left := Fixed_point'Value(Compute(Locale(top..I-1)));
  74.                  Right := Fixed_point'Value(Compute(Locale(I+1..bot)));
  75.                  return Fixed_point'Image(Left*Right);
  76.               when others =>
  77.                  null;
  78.            end case;
  79.         end loop;
  80.         rest:= new String ' (Fixed_point'Image(Fixed_point'Value(Locale.all)));
  81.         return Rest.all;
  82.      end if;
  83.  
  84.   end Compute;

n°2029243
Profil sup​primé
Posté le 14-10-2010 à 11:59:33  answer
 

Midi, c'est l'heure de la gamelle.  :o  
 
 

Code :
  1. function Compute(Eq : in String) return String is
  2.  
  3.      type Fixed_Point is delta 0.000_000_001 digits Max_digits range -9_999_999.0..9_999_999.0;
  4.      Locale : access String := new String '(Eq);
  5.      Rest : access String := new String '("" );
  6.      Buffer : access String := new String '("" );
  7.      Close, Open : Natural := 0;
  8.      Left  : Fixed_Point := 0.0;
  9.      Right : Fixed_Point := 0.0;
  10.      Top   : Positive := Locale'First;
  11.      Bot   : Positive := Locale'Last;
  12.      Pos_Operator : Natural := 0;
  13.   begin
  14.      if Locale'Length = 0 then
  15.         return "néant";
  16.      end if;
  17.      for I in reverse Locale'Range loop
  18.         if Locale(I) = '(' then
  19.            Open := I;
  20.            exit;
  21.         end if;
  22.      end loop;
  23.      if Open /= 0 then
  24.         for I in Open+1..Locale'last loop
  25.            if Locale(I) = ')' then
  26.               Close := I;
  27.               exit;
  28.            end if;
  29.         end loop;
  30.         if Close = 0 then
  31.            return "vous avez oublié de fermer la paranthèse";
  32.         end if;
  33.         if Close > Open + 1 then
  34.            buffer := new String ' (Locale(Open+1..Close-1));
  35.         else
  36.            return "néant n'est pas allouable entre paranthèse";
  37.         end if;
  38.         if Close < Locale'Last then
  39.            return Compute(Locale(Locale'First..Open-1) &
  40.                             Compute(Buffer.all) &
  41.                             Locale(Close+1..Locale'Last));
  42.         else
  43.            return Compute(Locale(Locale'First..Open-1) & Compute(Buffer.all) );
  44.         end if;
  45.      else
  46.         if Fixed.Index(Locale.all, "*" ) /= 0 then
  47.            Pos_Operator :=  Fixed.Index(Locale.all, "*" );
  48.         elsif Fixed.Index(Locale.all, "/" ) /= 0 then
  49.            Pos_Operator :=  Fixed.Index(Locale.all, "/" );
  50.         elsif Fixed.Index(Locale.all, ":" ) /= 0 then
  51.            Pos_Operator :=  Fixed.Index(Locale.all, ":" );
  52.         end if;
  53.         if Pos_Operator /= 0 then
  54.            if Fixed.Index(Locale(Top..Pos_Operator), "+" ) /= 0 then
  55.               return Fixed_Point'Image
  56.                 (Fixed_Point'Value
  57.                    (Compute
  58.                       (Locale(Top..Fixed.Index(Locale(Top..Pos_Operator), "+" ) - 1))) +
  59.                    Fixed_Point'Value
  60.                    (Compute
  61.                       (Locale(Fixed.Index(Locale(Top..Pos_Operator), "+" ) + 1..Bot))));
  62.            elsif Fixed.Index(Locale(Top..Pos_Operator), "-" ) /= 0 then
  63.               return Fixed_Point'Image
  64.                 (Fixed_Point'Value
  65.                    (Compute
  66.                       (Locale
  67.                          (Top..Fixed.Index
  68.                             (Locale
  69.                                (Top..Pos_Operator), "-" ) - 1))) -
  70.                    Fixed_Point'Value
  71.                    (Compute
  72.                       (Locale
  73.                          (Fixed.Index
  74.                             (Locale(Top..Pos_Operator), "-" ) + 1..Bot))));
  75.  
  76.            elsif Fixed.Index(Locale(Pos_Operator+1..bot), "+" ) /= 0 then
  77.               return Fixed_Point'Image
  78.                 (Fixed_Point'Value
  79.                    (Compute
  80.                       (Locale(Top..Fixed.Index(Locale(Pos_Operator+1..bot), "+" ) - 1))) +
  81.                    Fixed_Point'Value
  82.                    (Compute
  83.                       (Locale(Fixed.Index(Locale(Pos_Operator..bot), "+" ) + 1..Bot))));
  84.            elsif Fixed.Index(Locale(Pos_Operator..bot), "-" ) /= 0 then
  85.               return Fixed_Point'Image
  86.                 (Fixed_Point'Value
  87.                    (Compute
  88.                       (Locale
  89.                          (Top..Fixed.Index
  90.                             (Locale
  91.                                (Pos_Operator..bot), "-" ) - 1))) -
  92.                    Fixed_Point'Value
  93.                    (Compute
  94.                       (Locale
  95.                          (Fixed.Index
  96.                             (Locale(Pos_Operator..bot), "-" ) + 1..Bot))));
  97.  
  98.  
  99.            else
  100.               case Locale(Pos_Operator) is
  101.                  when '*' =>
  102.                     return Fixed_Point'Image
  103.                       (Fixed_Point'Value
  104.                          (Compute
  105.                             (Locale
  106.                                (Top..Pos_Operator-1))) *
  107.                          Fixed_Point'Value
  108.                          (Compute
  109.                             (Locale
  110.                                (Pos_Operator+1..bot))));
  111.                  when '/' | ':' =>
  112.                     return Fixed_Point'Image
  113.                       (Fixed_Point'Value
  114.                          (Compute
  115.                             (Locale
  116.                                (Top..Pos_Operator-1))) /
  117.                          Fixed_Point'Value
  118.                          (Compute
  119.                             (Locale
  120.                                (Pos_Operator+1..bot))));
  121.                  when others =>
  122.                     raise Program_Error;
  123.  
  124.               end case;
  125.  
  126.            end if;
  127.         else
  128.            if Fixed.Index(Locale(Top..bot), "+" ) /= 0 then
  129.               return Fixed_Point'Image
  130.                 (Fixed_Point'Value
  131.                    (Compute
  132.                       (Locale(Top..Fixed.Index(Locale(Top..bot), "+" ) - 1))) +
  133.                 Fixed_Point'Value
  134.                 (Compute
  135.                    (Locale(Fixed.Index(Locale(Top..bot), "+" ) + 1..Bot))));
  136.            elsif Fixed.Index(Locale(Top..bot), "-" ) /= 0 then
  137.               return Fixed_Point'Image
  138.                 (Fixed_Point'Value
  139.                    (Compute
  140.                       (Locale
  141.                          (Top..Fixed.Index
  142.                          (Locale
  143.                             (Top..bot), "-" ) - 1))) -
  144.                    Fixed_Point'Value
  145.                    (Compute
  146.                    (Locale
  147.                       (Fixed.Index
  148.                          (Locale(Top..bot), "-" ) + 1..Bot))));
  149.            else
  150.               return Fixed_Point'Image
  151.                 (Fixed_Point'Value(Locale.all));
  152.            end if;
  153.         end if;
  154.      end if;
  155.   end Compute;


Message édité par Profil supprimé le 14-10-2010 à 12:00:10
n°2029578
Profil sup​primé
Posté le 15-10-2010 à 13:48:46  answer
 

Petite correction pour le traitement des nombres négatif et ajout des fonctions trigonométrique et autres.
Mais j'aurais aimé voir un peut les algo qui tourne ailleurs.

Code :
  1. function Compute(Eq : in String) return String is
  2.  
  3.      type T_Function is (Null_Item,
  4.                          Sqrt, Log, Exp,
  5.                          Sin, Cos, Tan, Cot,
  6.                          Arcsin, Arccos, Arctan, Arccot);
  7.  
  8.      function Value(Command : String) return T_Function is
  9.      begin
  10.         if Ada.Strings.Fixed.Index(Command , " ",  Ada.Strings.Fixed.Index_Non_Blank(command)) /= 0 then
  11.            return T_Function'Value(Command(Ada.Strings.Fixed.Index_Non_Blank(Command)..Ada.Strings.Fixed.Index(Command, " ", Ada.Strings.Fixed.Index_Non_Blank(Command)) - 1));
  12.         else
  13.            return T_Function'Value(Command(Fixed.Index_Non_Blank(Command)..Command'last));
  14.         end if;
  15.      exception
  16.         when Constraint_Error =>
  17.            Return Null_Item;
  18.      end Value;
  19.  
  20.  
  21.  
  22.  
  23.  
  24.      type Fixed_Point is delta 0.000_000_001 digits Max_digits range -9_999_999.0..9_999_999.0;
  25.      Locale : constant access String := new String '(Eq);
  26.      Buffer : access String := new String '("" );
  27.      Close, Open : Natural := 0;
  28.  
  29.      Top   : constant Positive := Locale'First;
  30.      Bot   : constant Positive := Locale'Last;
  31.      Pos_Operator : Natural := 0;
  32.  
  33.      Command : T_Function := Null_Item;
  34.   begin
  35.  
  36.      if Locale'Length = 0 then
  37.         return "néant";
  38.      end if;
  39.      for I in reverse Locale'Range loop
  40.         if Locale(I) = '(' then
  41.            Open := I;
  42.            exit;
  43.         end if;
  44.      end loop;
  45.  
  46.      if Open /= 0 then
  47.         for I in Open+1..Locale'last loop
  48.            if Locale(I) = ')' then
  49.               Close := I;
  50.               exit;
  51.            end if;
  52.         end loop;
  53.         if Close = 0 then
  54.            return "vous avez oublié de fermer la paranthèse";
  55.         end if;
  56.         if Close > Open + 1 then
  57.            buffer := new String ' (Locale(Open+1..Close-1));
  58.         else
  59.            return "néant n'est pas allouable entre paranthèse";
  60.         end if;
  61.         if Close < Locale'Last then
  62.            return Compute(Locale(Locale'First..Open-1) &
  63.                             Compute(Buffer.all) &
  64.                             Locale(Close+1..Locale'Last));
  65.         else
  66.            return Compute(Locale(Locale'First..Open-1) & Compute(Buffer.all) );
  67.         end if;
  68.      else
  69.         Command := Value(Locale.all);
  70.         Put_line("Locale ::= " & Locale.all);
  71.         Put_Line("Command ::= " & T_Function'Image(Command));
  72.         if Command /= Null_Item then
  73.            case Command is
  74.               when Sqrt =>
  75.                  return Fixed_Point'Image
  76.                    (Fixed_Point(Sqrt(float'Value(Compute(Locale(Fixed.Index(Locale.all, "sqrt" )+5..Locale'Last))))));
  77.               when Log =>
  78.                  return Fixed_Point'Image
  79.                    (Fixed_Point(log(float'Value(Compute(Locale(Fixed.Index(Locale.all, "log" )+4..Locale'Last))))));
  80.               when Exp =>
  81.                  return Fixed_Point'Image
  82.                    (Fixed_Point(exp(float'Value(Compute(Locale(Fixed.Index(Locale.all, "exp" )+4..Locale'Last))))));
  83.               when Sin =>
  84.                  return Fixed_Point'Image
  85.                    (Fixed_Point(sin(float'Value(Compute(Locale(Fixed.Index(Locale.all, "sin" )+4..Locale'Last))))));
  86.               when Cos =>
  87.                  return Fixed_Point'Image
  88.                    (Fixed_Point(Cos(float'Value(Compute(Locale(Fixed.Index(Locale.all, "cos" )+4..Locale'Last))))));
  89.               when Tan =>
  90.                  return Fixed_Point'Image
  91.                    (Fixed_Point(Tan(float'Value(Compute(Locale(Fixed.Index(Locale.all, "tan" )+4..Locale'Last))))));
  92.               when Cot =>
  93.                  return Fixed_Point'Image
  94.                    (Fixed_Point(Cot(float'Value(Compute(Locale(Fixed.Index(Locale.all, "cot" )+4..Locale'Last))))));
  95.               when Arcsin =>
  96.                  return Fixed_Point'Image
  97.                    (Fixed_Point(Arcsin(float'Value(Compute(Locale(Fixed.Index(Locale.all, "arcsin" )+7..Locale'Last))))));
  98.               when Arccos =>
  99.                  return Fixed_Point'Image
  100.                    (Fixed_Point(Arccos(float'Value(Compute(Locale(Fixed.Index(Locale.all, "arccos" )+7..Locale'Last))))));
  101.               when Arctan =>
  102.                  return Fixed_Point'Image
  103.                    (Fixed_Point(Arctan(float'Value(Compute(Locale(Fixed.Index(Locale.all, "arctan" )+7..Locale'Last))))));
  104.               when Arccot =>
  105.                  return Fixed_Point'Image
  106.                    (Fixed_Point(Arccot(float'Value(Compute(Locale(Fixed.Index(Locale.all, "arccot" )+7..Locale'Last))))));
  107.               when Null_Item =>
  108.                  null;
  109.            end case;
  110.         end if;
  111.         if Fixed.Index(Locale.all, "*" ) /= 0 then
  112.            Pos_Operator :=  Fixed.Index(Locale.all, "*" );
  113.         elsif Fixed.Index(Locale.all, "/" ) /= 0 then
  114.            Pos_Operator :=  Fixed.Index(Locale.all, "/" );
  115.         elsif Fixed.Index(Locale.all, ":" ) /= 0 then
  116.            Pos_Operator :=  Fixed.Index(Locale.all, ":" );
  117.         end if;
  118.         if Pos_Operator /= 0 then
  119.            if Fixed.Index(Locale(Top..Pos_Operator), "+" ) /= 0 then
  120.               return Fixed_Point'Image
  121.                 (Fixed_Point'Value
  122.                    (Compute
  123.                       (Locale(Top..Fixed.Index(Locale(Top..Pos_Operator), "+" ) - 1))) +
  124.                    Fixed_Point'Value
  125.                    (Compute
  126.                       (Locale(Fixed.Index(Locale(Top..Pos_Operator), "+" ) + 1..Bot))));
  127.            elsif Fixed.Index(Locale(Top..Pos_Operator), "-" ) /= 0 then
  128.               if Fixed.Index
  129.                 (Locale
  130.                    (Top..Pos_Operator), "-" ) > Top then
  131.                  return Fixed_Point'Image
  132.                    (Fixed_Point'Value
  133.                       (Compute
  134.                          (Locale
  135.                             (Top..Fixed.Index
  136.                                (Locale
  137.                                   (Top..Pos_Operator), "-" ) - 1))) -
  138.                       Fixed_Point'Value
  139.                       (Compute
  140.                          (Locale
  141.                             (Fixed.Index
  142.                                (Locale(Top..Pos_Operator), "-" ) + 1..Bot))));
  143.               else
  144.                  return Fixed_Point'Image
  145.                    (-Fixed_Point'Value
  146.                       (Compute
  147.                          (Locale
  148.                             (Fixed.Index
  149.                                (Locale(Top..Pos_Operator), "-" )+1..Bot))));
  150.               end if;
  151.  
  152.            elsif Fixed.Index(Locale(Pos_Operator+1..bot), "+" ) /= 0 then
  153.               return Fixed_Point'Image
  154.                 (Fixed_Point'Value
  155.                    (Compute
  156.                       (Locale(Top..Fixed.Index(Locale(Pos_Operator+1..bot), "+" ) - 1))) +
  157.                    Fixed_Point'Value
  158.                    (Compute
  159.                       (Locale(Fixed.Index(Locale(Pos_Operator..bot), "+" ) + 1..Bot))));
  160.            elsif Fixed.Index(Locale(Pos_Operator..bot), "-" ) /= 0 then
  161.               if Fixed.Index(Locale(Pos_Operator..bot), "-" ) <= Pos_Operator+2 then
  162.                  return Fixed_Point'Image
  163.                    (-Fixed_Point'Value
  164.                       (Compute
  165.                          (Locale
  166.                             (Fixed.Index
  167.                                (Locale(Pos_Operator..bot), "-" ) + 1..Bot))));
  168.               else
  169.  
  170.                  return Fixed_Point'Image
  171.                    (Fixed_Point'Value
  172.                       (Compute
  173.                          (Locale
  174.                             (Top..Fixed.Index
  175.                                  (Locale
  176.                                     (Pos_Operator..bot), "-" ) - 1))) -
  177.                       Fixed_Point'Value
  178.                       (Compute
  179.                          (Locale
  180.                             (Fixed.Index
  181.                                (Locale(Pos_Operator..bot), "-" ) + 1..Bot))));
  182.               end if;
  183.  
  184.            else
  185.               case Locale(Pos_Operator) is
  186.                  when '*' =>
  187.                     return Fixed_Point'Image
  188.                       (Fixed_Point'Value
  189.                          (Compute
  190.                             (Locale
  191.                                (Top..Pos_Operator-1))) *
  192.                          Fixed_Point'Value
  193.                          (Compute
  194.                             (Locale
  195.                                (Pos_Operator+1..bot))));
  196.                  when '/' | ':' =>
  197.                     return Fixed_Point'Image
  198.                       (Fixed_Point'Value
  199.                          (Compute
  200.                             (Locale
  201.                                (Top..Pos_Operator-1))) /
  202.                          Fixed_Point'Value
  203.                          (Compute
  204.                             (Locale
  205.                                (Pos_Operator+1..bot))));
  206.                  when others =>
  207.                     raise Program_Error;
  208.  
  209.               end case;
  210.  
  211.            end if;
  212.         else
  213.            if Fixed.Index(Locale(Top..bot), "+" ) /= 0 then
  214.               return Fixed_Point'Image
  215.                 (Fixed_Point'Value
  216.                    (Compute
  217.                       (Locale(Top..Fixed.Index(Locale(Top..bot), "+" ) - 1))) +
  218.                 Fixed_Point'Value
  219.                 (Compute
  220.                    (Locale(Fixed.Index(Locale(Top..bot), "+" ) + 1..Bot))));
  221.            elsif Fixed.Index(Locale(Top..bot), "-" ) /= 0 then
  222.               if Fixed.Index
  223.                 (Locale
  224.                    (Top..bot), "-" ) > Top then
  225.                  return Fixed_Point'Image
  226.                    (Fixed_Point'Value
  227.                    (Compute
  228.                       (Locale
  229.                          (Top..Fixed.Index
  230.                             (Locale
  231.                                (Top..bot), "-" ) - 1))) -
  232.                    Fixed_Point'Value
  233.                       (Compute
  234.                          (Locale
  235.                       (Fixed.Index
  236.                          (Locale(Top..bot), "-" ) + 1..Bot))));
  237.               else
  238.                  return Fixed_Point'Image
  239.                    (-Fixed_Point'Value
  240.                       (Compute
  241.                          (Locale
  242.                       (Fixed.Index
  243.                          (Locale(Top..bot), "-" ) + 1..Bot))));
  244.               end if;
  245.            else
  246.               return Fixed_Point'Image
  247.                 (Fixed_Point'Value(Locale.all));
  248.            end if;
  249.         end if;
  250.      end if;
  251.   end Compute;


edit : j'en avais oublié un petit morceau.


Message édité par Profil supprimé le 15-10-2010 à 14:07:00
n°2029580
Profil sup​primé
Posté le 15-10-2010 à 14:24:26  answer
 

Bon non en fait, ça ne fonctionne plus. Désolé.  :(

n°2029597
tpierron
Posté le 15-10-2010 à 15:10:41  profilanswer
 

Ah ouais, assez bourrin ton algo. Si j'ai bien compris, tu essaie d'identifier l'expression au parenthèsage le plus interne, fais une évaluation, remplace le résultat dans la chaine et continue comme ça, jusqu'à ce qu'il n'y a plus rien à évaluer.
 
Bon, tu devrais voir du coté des parser LALR(1). C'est typiquement taillé pour ce genre de chose. C'est ce que génère des outils comme lex&yacc, mais pour un truc aussi trivial que ça, pas la peine de sortir une artillerie aussi lourde. Le truc avec les parseurs LALR(1) c'est de diviser ton code en deux: une qui fait l'analyse lexicale, une autre l'analyse grammaticale.
 
L'analyse lexicale est triviale, l'analyse grammaticale nécessite un automate fini à pile. Mais pour des expressions mathématiques en notation infixe, c'est assez trivial à faire à la main. Pour ça, tu as besoins de 3 variables:

  • un entier pour garder la priorité courante en fonction du parenthésage.
  • une pile d'opérateur avec leur priorité.
  • une pile de nombre (entier pour simplifier).

L'algo se résume à :

  • Si tu vois un nombre tu l'empiles sur la pile des nombres.
  • Si tu vois un opérateur, tu ne l'empiles que si sa priorité est supérieure à l'opérateur au sommet de la pile. Dans le cas contraire, dépiler en faisant l'opération associée et empile le résultat.
  • une parenthèse ne fait que modifier la priorité courante.

S'il n'y a plus rien à lire, le résultat est normallement au sommet de la pile des entiers. S'il y a encore des opérateurs sur la pile, dépile en faisant l'opération associée.
 
Et voilà, avantages :
- Trivial d'ajouter de nouveaux opérateurs et/ou prendre en compte d'autres types de données.
- La chaine est lue de gauche à droite, en ne lisant qu'un caractère à la fois.
- L'arité des opérateurs se résume au nombre d'éléments à dépiler.
- L'associativité se résume à la condition du dépilement pour garder une pile d'opérateur en priorité croissante (associativité à gauche) ou strictement croissante (associativité à droite).
 
Comme j'ai que ça à foutre en ce moment, j'ai dépoussiéré une implémentation en C que j'avais faite il y a un bout de temps. Cette version ne contient qu'un type de donnée avec une douzaine d'opérateurs. La version originale
en avait 35 avec 3 types de données (entier, réél et chaine), en C pas en ADA, mais le code n'est pas trop pourri pour être transposé dans un autre langage:

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. #define RIGHT               1
  7. #define LEFT                2
  8. #define    DIM(table)         (sizeof(table) / sizeof(table[0]))
  9.  
  10. typedef char                    TEXT;
  11. typedef TEXT *                  STRPTR;
  12. typedef struct Operator_t *     Operator;
  13. typedef struct Stack_t *        Stack;
  14.  
  15. struct Operator_t
  16. {
  17.    STRPTR token;
  18.    int    arity;
  19.    int    associativity;
  20.    int    priority;
  21. };
  22.  
  23. static struct Operator_t OperatorList[] =
  24. {
  25.    { "-",   1, RIGHT, 15 }, { "~",   1, RIGHT, 15 },
  26.    { "*",   2, LEFT,  13 }, { "/",   2, LEFT,  13 },
  27.    { "%",   2, LEFT,  13 }, { "+",   2, LEFT,  12 },
  28.    { "-",   2, LEFT,  12 }, { "<<",  2, LEFT,  11 },
  29.    { ">>",  2, LEFT,  11 }, { "&",   2, LEFT,   8 },
  30.    { "^",   2, LEFT,   7 }, { "|",   2, LEFT,   6 }
  31. };
  32.  
  33. struct Stack_t
  34. {
  35.    Stack next;
  36.    short type;
  37.    union
  38.    {
  39.        Operator ope;
  40.        long     integer;
  41.    } value;
  42. };
  43.  
  44. enum
  45. {
  46.    TOKEN_UNKNOWN,
  47.    TOKEN_NUMBER,
  48.    TOKEN_INCPRI,
  49.    TOKEN_DECPRI,
  50.    TOKEN_OPERATOR,
  51.    TOKEN_SKIP
  52. };
  53.  
  54. enum /* Possible values for 'type' field */
  55. {
  56.    TYPE_INT,
  57.    TYPE_OPE
  58. };
  59.  
  60. enum /* Return codes of ParseExpression */
  61. {
  62.    PERR_SyntaxError = 1,
  63.    PERR_DivisionByZero,
  64.    PERR_LValueNotModifiable,
  65.    PERR_TooManyClosingParens,
  66.    PERR_MissingOperand,
  67.    PERR_InvalidOperation
  68. };
  69.  
  70. static Stack NewOperator(Operator ope)
  71. {
  72.    Stack oper = calloc(sizeof *oper, 1);
  73.  
  74.    oper->value.ope = ope;
  75.    oper->type      = TYPE_OPE;
  76.  
  77.    return oper;
  78. }
  79.  
  80. static Stack NewNumber(int val)
  81. {
  82.    Stack num = calloc(sizeof *num, 1);
  83.  
  84.    num->value.integer = val;
  85.    num->type = TYPE_INT;
  86.  
  87.    return num;
  88. }
  89.  
  90. // Try to parse a number
  91. static int GetNumber(Stack * object, STRPTR * exp)
  92. {
  93.    STRPTR cur = *exp;
  94.    STRPTR str = cur;
  95.    long   nb;
  96.  
  97.    // Signed numbers are interpreted as a unsigned preceeded by an unary -
  98.    if (! isdigit(*str)) return 0;
  99.  
  100.    // Try to parse an integer (octal, dec or hexa, like in C)
  101.    nb = strtoul(cur, &str, 0);
  102.  
  103.    if (str > cur)
  104.    {
  105.        *object = NewNumber(nb);
  106.        *exp    = str;
  107.        return 1;
  108.    }
  109.    return 0;
  110. }
  111.  
  112. // Our main lexical analyser, this should've been the lex part
  113. static int GetToken(Stack * object, STRPTR * exp)
  114. {
  115.    STRPTR str;
  116.    int    type = TOKEN_SKIP;
  117.  
  118.    // Skip starting space
  119.    for (str = *exp; isspace(*str); str ++);
  120.  
  121.    // Precedence arrangement
  122.    if (*str == '(')
  123.    {
  124.        str ++;
  125.        type = TOKEN_INCPRI;
  126.    }
  127.    else if (*str == ')')
  128.    {
  129.        str ++;
  130.        type = TOKEN_DECPRI;
  131.    }
  132.    else if (GetNumber(object, &str))
  133.    {
  134.        type = TOKEN_NUMBER;
  135.    }
  136.    else if (*str) // Maybe an operator
  137.    {
  138.        Operator best, cur;
  139.  
  140.        // Use same rule as C : longest match is winner
  141.        for (best = NULL, cur = OperatorList; cur < OperatorList + DIM(OperatorList); cur ++)
  142.        {
  143.            int length = strlen(cur->token);
  144.  
  145.            if (strncmp(str, cur->token, length) == 0 && (best == NULL || strlen(best->token) < length))
  146.                best = cur;
  147.        }
  148.        if (best)
  149.        {
  150.            str += strlen(best->token);
  151.            *object = NewOperator(best);
  152.            type = TOKEN_OPERATOR;
  153.        }
  154.        else type = TOKEN_UNKNOWN;
  155.    }
  156.  
  157.    *exp = str;
  158.  
  159.    return type;
  160. }
  161.  
  162. static void PushStack(Stack * top, Stack object)
  163. {
  164.    object->next = *top;
  165.    (*top) = object;
  166. }
  167.  
  168. static Stack PopStack(Stack * top)
  169. {
  170.    Stack ret = *top;
  171.  
  172.    if (ret) *top = ret->next;
  173.  
  174.    return ret;
  175. }
  176.  
  177. // This is the function that takes operand and perform operation according to top most operator
  178. // This is the syntax analyser, usually produced by tools like yacc
  179. static int MakeOp(Stack * values, Stack * oper)
  180. {
  181.    Stack    arg1, arg2;
  182.    Operator ope = (*oper)->value.ope;
  183.    int      nb, error = 0;
  184.  
  185.    #define    THROW(err)    { error = err; goto error_case; }
  186.  
  187.    arg1 = arg2 = NULL;
  188.    switch (ope->arity) {
  189.    case 2:  arg2 = PopStack(values); if (arg2 == NULL) THROW(PERR_MissingOperand);
  190.    default: arg1 = PopStack(values); if (arg1 == NULL) THROW(PERR_MissingOperand);
  191.    }
  192.    free(PopStack(oper));
  193.  
  194.    nb = ope - OperatorList;
  195.  
  196.    switch (nb) {
  197.    case 0: arg1->value.integer  = - arg1->value.integer; PushStack(values, arg1); free(arg2); break;
  198.    case 1: arg1->value.integer  = ~ arg1->value.integer; PushStack(values, arg1); free(arg2); break;
  199.    case 2: arg1->value.integer *=   arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  200.    case 3: // Division /
  201.        if (arg2->value.integer == 0) THROW(PERR_DivisionByZero);
  202.        arg1->value.integer /= arg2->value.integer;
  203.        PushStack(values, arg1);
  204.        free(arg2);
  205.        break;
  206.  
  207.    case 4: // Modulus %
  208.        if (arg2->value.integer == 0) THROW(PERR_DivisionByZero);
  209.        arg1->value.integer %= arg2->value.integer;
  210.        PushStack(values, arg1);
  211.        free(arg2);
  212.        break;
  213.  
  214.    case  5: arg1->value.integer  += arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  215.    case  6: arg1->value.integer  -= arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  216.    case  7: arg1->value.integer <<= arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  217.    case  8: arg1->value.integer >>= arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  218.    case  9: arg1->value.integer  &= arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  219.    case 10: arg1->value.integer  ^= arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  220.    case 11: arg1->value.integer  |= arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  221.    }
  222.    return error;
  223.  
  224.    error_case:
  225.    if (arg1) free(arg1);
  226.    if (arg2) free(arg2);
  227.    return error;
  228. }
  229.  
  230. int ParseExpression(STRPTR exp, int * result)
  231. {
  232.    Operator ope;
  233.    STRPTR   next;
  234.    int      curpri, pri, error, tok;
  235.    Stack    values, oper, object;
  236.  
  237.    for (curpri = error = tok = 0, values = oper = NULL, next = exp; error == 0 && *exp; exp = next)
  238.    {
  239.        switch (GetToken(&object, &next)) {
  240.        case TOKEN_NUMBER: // Number => stack it
  241.            if (tok == TOKEN_NUMBER) error = PERR_SyntaxError;
  242.            tok = TOKEN_NUMBER;
  243.            PushStack(&values, object);
  244.            break;
  245.        case TOKEN_INCPRI:
  246.            curpri += 30;
  247.            break;
  248.        case TOKEN_DECPRI:
  249.            if (tok == TOKEN_OPERATOR) error = PERR_SyntaxError;
  250.            curpri -= 30;
  251.            if (curpri < 0) error = PERR_TooManyClosingParens;
  252.            break;
  253.        case TOKEN_OPERATOR: // Operator
  254.            ope = object->value.ope;
  255.            pri = curpri + ope->priority - (ope->associativity == LEFT);
  256.  
  257.            if (ope == OperatorList && tok == TOKEN_NUMBER)
  258.                ope = object->value.ope = OperatorList + 6, pri = 11 + curpri; // Binary '-' instead
  259.  
  260.            while (error == 0 && oper && pri < oper->type)
  261.                error = MakeOp(&values, &oper);
  262.  
  263.            if (error) { free(object); break; }
  264.  
  265.            tok = TOKEN_OPERATOR;
  266.            object->type = curpri + ope->priority;
  267.            PushStack(&oper, object);
  268.            break;
  269.        case TOKEN_UNKNOWN:
  270.            error = PERR_SyntaxError;
  271.        }
  272.    }
  273.    while (error == 0 && oper)
  274.        error = MakeOp(&values, &oper);
  275.  
  276.    if (error == 0 && values)
  277.        *result = values->value.integer;
  278.  
  279.    while (oper)   free(PopStack(&oper));
  280.    while (values) free(PopStack(&values));
  281.    return error;
  282. }
  283.  
  284. int main(int nb, char * argv[])
  285. {
  286.    TEXT buffer[256];
  287.  
  288.    while (1)
  289.    {
  290.        int res, err;
  291.        fprintf(stderr, "calc> " );
  292.        fgets(buffer, sizeof buffer, stdin);
  293.        err = ParseExpression(buffer, &res);
  294.        switch (err) {
  295.        case 0:                         fprintf(stderr, "result = %d\n", res); break;
  296.        case PERR_SyntaxError:          fprintf(stderr, "Syntax error.\n" ); break;
  297.        case PERR_DivisionByZero:       fprintf(stderr, "Division by zero.\n" ); break;
  298.        case PERR_TooManyClosingParens: fprintf(stderr, "Too many closing parenthesis.\n" ); break;
  299.        case PERR_MissingOperand:       fprintf(stderr, "Missing operand.\n" ); break;
  300.        case PERR_InvalidOperation:     fprintf(stderr, "Invalid operation.\n" ); break;
  301.        }
  302.    }
  303.    return 0;
  304. }

n°2029661
Profil sup​primé
Posté le 15-10-2010 à 17:10:49  answer
 

Merci bien tpierron.
 
Je vais passer quelques heures à bricoler mon code, et je me mettrais à cette solution.

mood
Publicité
Posté le 15-10-2010 à 17:10:49  profilanswer
 

n°2029702
Profil sup​primé
Posté le 15-10-2010 à 20:32:46  answer
 

j'ai fait un import de ton code que j'ai modifié pour traiter des flottant et j'ai légèrement modifier le main pour qu'il réponde à mes besoins en terme d'interface.
Je connais pas grand chose au C. j'ai une warning à la compilation, mais ça fonctionne.

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5.    
  6. #define RIGHT               1
  7. #define LEFT                 2
  8. #define    DIM(table)         (sizeof(table) / sizeof(table[0]))
  9.    
  10. typedef char                    TEXT;
  11. typedef TEXT *                  STRPTR;
  12. typedef struct Operator_t *     Operator;
  13. typedef struct Stack_t *        Stack;
  14.    
  15. struct Operator_t
  16. {
  17.  STRPTR token;
  18.  int    arity;
  19.  int    associativity;
  20.  int    priority;
  21. };
  22.    
  23. static struct Operator_t OperatorList[] =
  24.  {
  25.    { "-",   1, RIGHT, 15 }, { "~",   1, RIGHT, 15 },
  26.    { "*",   2, LEFT,  13 }, { "/",   2, LEFT,  13 },
  27.    { "%",   2, LEFT,  13 }, { "+",   2, LEFT,  12 },
  28.    { "-",   2, LEFT,  12 }, { "<<",  2, LEFT,  11 },
  29.    { ">>",  2, LEFT,  11 }, { "&",   2, LEFT,   8 },
  30.    { "^",   2, LEFT,   7 }, { "|",   2, LEFT,   6 }
  31.  };
  32.    
  33. struct Stack_t
  34. {
  35.  Stack next;
  36.  short type;
  37.  union
  38.  {
  39.    Operator ope;
  40.    float    integer;
  41.  } value;
  42. };
  43.    
  44. enum
  45.  {
  46.    TOKEN_UNKNOWN,
  47.    TOKEN_NUMBER,
  48.    TOKEN_INCPRI,
  49.    TOKEN_DECPRI,
  50.    TOKEN_OPERATOR,
  51.    TOKEN_SKIP
  52.  };
  53.    
  54. enum /* Possible values for 'type' field */
  55.  {
  56.    TYPE_FLOAT,
  57.    TYPE_OPE
  58.  };
  59.    
  60. enum /* Return codes of ParseExpression */
  61.  {
  62.    PERR_SyntaxError = 1,
  63.    PERR_DivisionByZero,
  64.    PERR_LValueNotModifiable,
  65.    PERR_TooManyClosingParens,
  66.    PERR_MissingOperand,
  67.    PERR_InvalidOperation
  68.  };
  69.    
  70. static Stack NewOperator(Operator ope)
  71. {
  72.  Stack oper = calloc(sizeof *oper, 1);
  73.    
  74.  oper->value.ope = ope;
  75.  oper->type      = TYPE_OPE;
  76.    
  77.  return oper;
  78. }
  79.    
  80. static Stack NewNumber(float val)
  81. {
  82.  Stack num = calloc(sizeof *num, 1);
  83.    
  84.  num->value.integer = val;
  85.  num->type = TYPE_FLOAT;
  86.    
  87.  return num;
  88. }
  89.    
  90. // Try to parse a number
  91. static int GetNumber(Stack * object, STRPTR * exp)
  92. {
  93.  STRPTR cur = *exp;
  94.  STRPTR str = cur;
  95.  long   nb;
  96.    
  97.  // Signed numbers are interpreted as a unsigned preceeded by an unary -
  98.  if (! isdigit(*str)) return 0;
  99.    
  100.  // Try to parse an integer (octal, dec or hexa, like in C)
  101.  nb = strtoul(cur, &str, 0);
  102.    
  103.  if (str > cur)
  104.    {
  105.      *object = NewNumber(nb);
  106.      *exp    = str;
  107.      return 1;
  108.    }
  109.  return 0;
  110. }
  111.    
  112. // Our main lexical analyser, this should've been the lex part
  113. static int GetToken(Stack * object, STRPTR * exp)
  114. {
  115.  STRPTR str;
  116.  int    type = TOKEN_SKIP;
  117.    
  118.  // Skip starting space
  119.  for (str = *exp; isspace(*str); str ++);
  120.    
  121.  // Precedence arrangement
  122.  if (*str == '(')
  123.    {
  124.      str ++;
  125.      type = TOKEN_INCPRI;
  126.    }
  127.  else if (*str == ')')
  128.    {
  129.      str ++;
  130.      type = TOKEN_DECPRI;
  131.    }
  132.  else if (GetNumber(object, &str))
  133.    {
  134.      type = TOKEN_NUMBER;
  135.    }
  136.  else if (*str) // Maybe an operator
  137.    {
  138.      Operator best, cur;
  139.    
  140.      // Use same rule as C : longest match is winner
  141.      for (best = NULL, cur = OperatorList; cur < OperatorList + DIM(OperatorList); cur ++)
  142.     {
  143.       int length = strlen(cur->token);
  144.    
  145.       if (strncmp(str, cur->token, length) == 0 && (best == NULL || strlen(best->token) < length))
  146.         best = cur;
  147.     }
  148.      if (best)
  149.     {
  150.       str += strlen(best->token);
  151.       *object = NewOperator(best);
  152.       type = TOKEN_OPERATOR;
  153.     }
  154.      else type = TOKEN_UNKNOWN;
  155.    }
  156.    
  157.  *exp = str;
  158.    
  159.  return type;
  160. }
  161.    
  162. static void PushStack(Stack * top, Stack object)
  163. {
  164.  object->next = *top;
  165.  (*top) = object;
  166. }
  167.    
  168. static Stack PopStack(Stack * top)
  169. {
  170.  Stack ret = *top;
  171.    
  172.  if (ret) *top = ret->next;
  173.    
  174.  return ret;
  175. }
  176.    
  177. // This is the function that takes operand and perform operation according to top most operator
  178. // This is the syntax analyser, usually produced by tools like yacc
  179. static int MakeOp(Stack * values, Stack * oper)
  180. {
  181.  Stack    arg1, arg2;
  182.  Operator ope = (*oper)->value.ope;
  183.  int      nb, error = 0;
  184.    
  185. #define    THROW(err)    { error = err; goto error_case; }
  186.    
  187.  arg1 = arg2 = NULL;
  188.  switch (ope->arity) {
  189.  case 2:  arg2 = PopStack(values); if (arg2 == NULL) THROW(PERR_MissingOperand);
  190.  default: arg1 = PopStack(values); if (arg1 == NULL) THROW(PERR_MissingOperand);
  191.  }
  192.  free(PopStack(oper));
  193.    
  194.  nb = ope - OperatorList;
  195.    
  196.  switch (nb) {
  197.  case 0: arg1->value.integer  = - arg1->value.integer; PushStack(values, arg1); free(arg2); break;
  198.    /* case 1: arg1->value.integer  = ~ arg1->value.integer; PushStack(values, arg1); free(arg2); break; */
  199.  case 2: arg1->value.integer *=   arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  200.  case 3: // Division /
  201.    if (arg2->value.integer == 0) THROW(PERR_DivisionByZero);
  202.    arg1->value.integer /= arg2->value.integer;
  203.    PushStack(values, arg1);
  204.    free(arg2);
  205.    break;
  206.    
  207.  /*case 4: // Modulus %
  208.    if (arg2->value.integer == 0) THROW(PERR_DivisionByZero);
  209.    arg1->value.integer %= arg2->value.integer;
  210.    PushStack(values, arg1);
  211.    free(arg2);
  212.    break;
  213.  */  
  214.  case  5: arg1->value.integer  += arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  215.  case  6: arg1->value.integer  -= arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  216.    /*  case  7: arg1->value.integer <<= arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  217.  case  8: arg1->value.integer >>= arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  218.  case  9: arg1->value.integer  &= arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  219.  case 10: arg1->value.integer  ^= arg2->value.integer; PushStack(values, arg1); free(arg2); break;
  220.  case 11: arg1->value.integer  |= arg2->value.integer; PushStack(values, arg1); free(arg2); break; */
  221.  }
  222.  return error;
  223.    
  224. error_case:
  225.  if (arg1) free(arg1);
  226.  if (arg2) free(arg2);
  227.  return error;
  228. }
  229.    
  230. int ParseExpression(STRPTR exp, float * result)
  231. {
  232.  Operator ope;
  233.  STRPTR   next;
  234.  int      curpri, pri, error, tok;
  235.  Stack    values, oper, object;
  236.    
  237.  for (curpri = error = tok = 0, values = oper = NULL, next = exp; error == 0 && *exp; exp = next)
  238.    {
  239.      switch (GetToken(&object, &next)) {
  240.      case TOKEN_NUMBER: // Number => stack it
  241.     if (tok == TOKEN_NUMBER) error = PERR_SyntaxError;
  242.     tok = TOKEN_NUMBER;
  243.     PushStack(&values, object);
  244.     break;
  245.      case TOKEN_INCPRI:
  246.     curpri += 30;
  247.     break;
  248.      case TOKEN_DECPRI:
  249.     if (tok == TOKEN_OPERATOR) error = PERR_SyntaxError;
  250.     curpri -= 30;
  251.     if (curpri < 0) error = PERR_TooManyClosingParens;
  252.     break;
  253.      case TOKEN_OPERATOR: // Operator
  254.     ope = object->value.ope;
  255.     pri = curpri + ope->priority - (ope->associativity == LEFT);
  256.    
  257.     if (ope == OperatorList && tok == TOKEN_NUMBER)
  258.       ope = object->value.ope = OperatorList + 6, pri = 11 + curpri; // Binary '-' instead
  259.    
  260.     while (error == 0 && oper && pri < oper->type)
  261.       error = MakeOp(&values, &oper);
  262.    
  263.     if (error) { free(object); break; }
  264.    
  265.     tok = TOKEN_OPERATOR;
  266.     object->type = curpri + ope->priority;
  267.     PushStack(&oper, object);
  268.     break;
  269.      case TOKEN_UNKNOWN:
  270.     error = PERR_SyntaxError;
  271.      }
  272.    }
  273.  while (error == 0 && oper)
  274.    error = MakeOp(&values, &oper);
  275.    
  276.  if (error == 0 && values)
  277.    *result = values->value.integer;
  278.    
  279.  while (oper)   free(PopStack(&oper));
  280.  while (values) free(PopStack(&values));
  281.  return error;
  282. }
  283.  
  284. int computer(int nb, char * argv[], char * result )
  285. {
  286.  TEXT locale[256];
  287.  TEXT buffer[256];
  288.  float res;
  289.  int err;
  290.  /* fprintf(stderr, "calc> " ); */
  291.  /* fgets(buffer, sizeof buffer, stdin); */
  292.  err = ParseExpression(argv, &res);
  293.  switch (err) {
  294.  case 0:                         fprintf(stderr, "result = %f\n", res); break;
  295.  case PERR_SyntaxError:          fprintf(stderr, "Syntax error.\n" ); break;
  296.  case PERR_DivisionByZero:       fprintf(stderr, "Division by zero.\n" ); break;
  297.  case PERR_TooManyClosingParens: fprintf(stderr, "Too many closing parenthesis.\n" ); break;
  298.  case PERR_MissingOperand:       fprintf(stderr, "Missing operand.\n" ); break;
  299.  case PERR_InvalidOperation:     fprintf(stderr, "Invalid operation.\n" ); break;
  300.  }
  301.  sprintf(locale, "%f", res);
  302.  result = locale;
  303.  return err;
  304. }

n°2029704
Profil sup​primé
Posté le 15-10-2010 à 20:38:50  answer
 

A zut non. Ca marche pas encore... Mais ça va marcher.  :D

n°2029787
Profil sup​primé
Posté le 16-10-2010 à 11:05:06  answer
 

Pour le moment j'ai fait un import en retournant un pointeur sur un char finalement mais je me mettrai à l'implémentation avec Ada un peu plus tard.
 
Marci encore tpierron.

n°2037902
Profil sup​primé
Posté le 23-11-2010 à 19:19:41  answer
 


 
Bonjour,
 
Finalement, comment appelle-t-on  ce type de machine ?
 
J'ai trouvé une implémentation Ada du même genre.
 
Je compte maintenant en implémenté une pour traiter les fichier MIDI... Vous pensez que ça peut ce faire ?
 
Pardon rien à voir avec les calculette.... Si .... [:deouss]

Message cité 1 fois
Message édité par Profil supprimé le 23-11-2010 à 19:21:09
n°2037909
breizhbugs
Posté le 23-11-2010 à 19:33:05  profilanswer
 


Hello,
C'est une machine à pile si mes souvenirs sont bons ( http://www.google.fr/#q=compilateu [...] 22138eb393 ).


---------------
Seul Google le sait...
n°2037921
Profil sup​primé
Posté le 23-11-2010 à 20:08:51  answer
 

Merci bien breizhbugs,  :jap: .


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Algo

  Calculette qui prend et retourne une chaîne de caractères

 

Sujets relatifs
[résolu] Nettoyage de chaine par Regexconnect qui échoue de façon aléatoire
Découper une chaîne avec un tableau de longueur en param[php]imagettftext et caractères accentués.
[VBA] Test de chaine de caractère sur une collectionConstante chaîne non terminée
[RESOLU] Remplacement d'une chaine de caractères dans un fichier html[Résolu] Fonction supp petit mot et supp caractères spéciaux
Décoder une chaine de caractère 
Plus de sujets relatifs à : Calculette qui prend et retourne une chaîne de caractères


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR