Advertisement
csmine

Option info - TP4 Evaluation d'expressions arithmétiques

Apr 9th, 2019
615
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 4.13 KB | None | 0 0
  1. (* Evaluation d'une expression abstraite *)
  2.  
  3. type ('a,'b) arbre =
  4.     | Feuille of 'b
  5.     | Noeud of 'a*(('a,'b) arbre)*(('a,'b) arbre);;
  6.  
  7. type expression_abstraite = (char,int) arbre;;
  8.  
  9. (*** INSERER ICI LES TROIS EXEMPLES ***)
  10. let exemple1 =
  11. Noeud(
  12.     '+',
  13.     Noeud(
  14.             '+',
  15.             Feuille 1,
  16.             Feuille 2),
  17.     Noeud(
  18.             '+',
  19.             Feuille 3,
  20.             Feuille 4));;
  21.  
  22. let exemple2 =
  23. Noeud(
  24.         '+',
  25.         Noeud(
  26.                 '+',
  27.                 Noeud(
  28.                         '+',
  29.                         Feuille 1,
  30.                         Feuille 2),
  31.                 Feuille 3),
  32.         Feuille 4);;
  33.  
  34. let exemple3 =
  35. Noeud(
  36.         '+',
  37.         Feuille 20,
  38.         Noeud(
  39.                 '+',
  40.                 Noeud(
  41.                         '+',
  42.                         Noeud(
  43.                                 '*',
  44.                                 Feuille 8,
  45.                                 Feuille 12),
  46.                         Noeud(
  47.                                 '*',
  48.                                 Feuille 18,
  49.                                 Feuille 5)),
  50.                 Noeud(
  51.                         '*',
  52.                         Noeud(
  53.                                 '+',
  54.                                 Feuille 8,
  55.                                 Feuille 12),
  56.                         Noeud(
  57.                                 '+',
  58.                                 Feuille 18,
  59.                                 Feuille 5))));;
  60.  
  61.  
  62.  
  63.  
  64. let rec evaluer (a : expression_abstraite) = match a with
  65. |Feuille f -> f
  66. |Noeud (n,fg,fd) when n='+' -> (evaluer fg) + (evaluer fd)
  67. |Noeud (n,fg,fd) when n='*' -> (evaluer fg) * (evaluer fd)
  68. |Noeud (n,fg,fd) when n='-' -> (evaluer fg) - (evaluer fd);;
  69.  
  70.  
  71. evaluer exemple1;;
  72. evaluer exemple2;;
  73. evaluer exemple3;;
  74.  
  75.  
  76. (* Conversion d'une expression concrete *)
  77.  
  78. let chiffres = ['0';'1';'2';'3';'4';'5';'6';'7';'8';'9']
  79. and operations = ['+';'*';'-'];;
  80.  
  81. int_of_string "01aa567a9";;
  82.  
  83. let nombre s =
  84. try
  85. let a=int_of_string s in
  86. true
  87. with
  88. | _ -> false;;
  89.  
  90.  
  91. let est_correct s =
  92.     let rec aux s i j =
  93.     (* teste si l'expression s.[i]...s.[j] est correcte *)
  94.         try
  95.         (* le rattrapage des exceptions est tres pratique ici : il permet d'eviter de verifier a chaque instant qu'on n'a pas depasse la longueur de la chaine ; si on depasse, c'est que c'est incorrect *)
  96.             if nombre (String.sub s i (j-i+1)) then true
  97.             (* les nombres sont corrects *)
  98.             else if s.[i]<>'(' || s.[j]<>')' then false
  99.             (* les autres commencent et finissent par une parenthese *)
  100.             else begin
  101.                 let p = ref 1 in (* p compte les parentheses *)
  102.                 let k = ref i in (* k indique la position *)
  103.                 (* Compte s'il y a le bon nombres de parenthèses*)
  104.                 while !p>0 do
  105.                     incr k;
  106.                     if s.[!k]='(' then incr p;
  107.                     if s.[!k]=')' then decr p;
  108.                     done;
  109.                 (* Appel récursif sur la partie gauche, et la partie droite *)
  110.                
  111.                 aux s (i+1) (!k-1) && (List.mem s.[!k+1] operations) && s.[!k+2]='(' && aux s (!k+3) (j-1) end
  112.         with _ -> false in
  113.         aux s 0 (String.length s - 1);;
  114.  
  115. est_correct "(((22)+(33))+((3)*(99)))*(100000000000)";;
  116.  
  117. let analyser s : expression_abstraite =
  118.     let rec aux s i j =
  119.     (* teste si l'expression s.[i]...s.[j] est correcte *)
  120.         try
  121.         (* le rattrapage des exceptions est tres pratique ici : il permet d'eviter de verifier a chaque instant qu'on n'a pas depasse la longueur de la chaine ; si on depasse, c'est que c'est incorrect *)
  122.             if nombre (String.sub s i (j-i+1)) then Feuille (int_of_string (String.sub s i (j-i+1)))
  123.             (* les nombres sont corrects *)
  124.             else if s.[i]<>'(' || s.[j]<>')' then failwith ""
  125.             (* les autres commencent et finissent par une parenthese *)
  126.             else begin
  127.                 let p = ref 1 in (* p compte les parentheses *)
  128.                 let k = ref i in (* k indique la position *)
  129.                 (* Compte s'il y a le bon nombres de parenthèses*)
  130.                 while !p>0 do
  131.                     incr k;
  132.                     if s.[!k]='(' then incr p;
  133.                     if s.[!k]=')' then decr p;
  134.                     done;
  135.                 (* Appel récursif sur la partie gauche, et la partie droite *)
  136.                 (* aux s (i+1) (!k-1) && (List.mem s.[!k+1] operations) && aux s (!k+3) (j-1) end *)
  137.                 Noeud(s.[!k+1],aux s (i+1) (!k-1),aux s (!k+3) (j-1));
  138.                 end
  139.         with _ -> failwith "Pas content !" in
  140.         aux s 0 (String.length s - 1);;
  141.  
  142. est_correct "0";;
  143.  
  144. analyser "(((22)-(33))+((3)*(99)))+(0)";;
  145.  
  146.  
  147. (* Boucle Read-Eval-Print *)
  148.  
  149.  
  150.  
  151.  
  152. exception Fini;;
  153.  
  154. let boucle_REP () =
  155. while true do
  156.     let s = read_line() in
  157.     if s="quitter" then raise Fini
  158.     else
  159.     if not (est_correct s)
  160.         then print_string "Mauvaise expression\n"
  161.         else begin
  162.                 print_string ">";
  163.                 print_string s;
  164.                 print_string "\n";
  165.                 print_int (evaluer (analyser s));
  166.                 print_string "\n";
  167.                 end
  168.     done;;
  169.  
  170. boucle_REP ();;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement