Next: Index
Up: Programmes en Caml
Previous: Chapitre 5
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;;