next up previous contents index
Next: Index Up: Programmes en Caml Previous: Chapitre 5

Chapitre 6

type arbre =
| Feuille of char 
| Noeud of char * arbre * arbre;;

let f = " (a + a * a ) ";;
let i = ref 0;;

let rec expression () =
  let a = terme () in
  if f.[!i] = `+` then begin
   incr i;
   Noeud (`+`, a, expression ()) end
  else a

and terme () =
  let a = facteur () in
  if f.[!i] = `*` then begin
   incr i;
   Noeud (`*`, a, terme ()) end
  else a

and facteur () =
  if f.[!i] = `(` then begin
   incr i;
   let a = expression () in
   if f.[!i] = `)` then begin
    incr i;
    a end
   else erreur (i) end
  else
  if f.[!i] = `à
  then begin
   incr i;
   Feuille `à end 
  else erreur (i);;

(* Prédicat définissant les non-terminaux *)
let auxiliaire y = ... ;;

(* règle.(s).(i) est la ième règle
   dont le membre gauche est s *)
let règle =
  [|  [| s00; s01; ... |];
      [| s10; s11; ... |];
      [| si0; si1; ... |];
  ... |];;

(* nbrègle.(s) est le nombre de règles
   dont le membre gauche est s *)
let nbrègle = [| s0; ...; sn |];;

(* Fonction auxiliaire sur les chaînes
   de caractères: remplacer s pos char
   renvoit une copie de la chaîne s
   avec char en position pos *)
let remplacer s pos char =
 let s1 = make_string (string_length s) ` ` in
 blit_string s 0 s1 0 (string_length s);
 s1.[pos] <- char;
 s1;;

let analyse_récursive f u =
 let b = ref false in
 let pos = ref 0 in
 while f.[!pos] = u.[!pos] do incr pos done;
 if f[!pos] = `$` && u.[!pos] = `#`
 then begin
  print_string "analyse réussie \n";
  true end
 else
   let y = u.[!pos] in
   if auxiliaire y
   then begin
    let i = ref 0 in
    let ynum = int_of_char y - int_of_char `À in
    while not !b && !i <= nbrègle.(ynum) do
     b := analyse_récursive
           (remplacer (u, !pos, règle.(ynum).(!i)), f);
     if !b
     then printf "règle %d du non-terminal %c \n" !i y
     else incr i
    done;
    !b end
   else false;;

(* {\em Analyse LL(1), voir page \pageref{prog:ll1}} *)
let rec arbre_synt_pref () =
  if f.[!pos] = `à
  then begin
    incr pos;
    Feuille `à end
  else
  if f.[!pos] = `(`
  && f.[!pos + 1] = `+`
  || f.[!pos + 1] = `*`
  then begin
    let x = f.[!pos + 1] in
    pos := !pos + 2;
    let a = arbre_synt_pref () in
    let b = arbre_synt_pref () in
    if f.[!pos] = `)`
    then Noeud (x, a, b)
    else erreur (!pos) end
  else erreur(!pos);;

(* {\em Évaluation, voir page \pageref{prog:evaluation}} *)
type expression =
| Constante of int
| Opération of char * expression * expression;;

let rec évaluer = function
| Constante i -> i
| Opération ('+', e1, e2) -> évaluer e1 + évaluer e2
| Opération ('*', e1, e2) -> évaluer e1 * évaluer e2;;



1/11/1998