module M = Map.Make(Char)
module S = Set.Make(Char)
                   
let gram = M.add 'S' ["aA";"b"] (M.add 'A' ["Bb";"aA"] (M.singleton 'B' ["Sa"]))

(* calculeaza punctul fix pentru functia f pe dictionare cu valori multimi *)
let fixmap f =
  let rec fix1 x =
    let y = f x in if M.equal S.equal x y then x else fix1 y
  in fix1

(* calculeaza o valoare actualizata din dictionarul cmap
 * care da multimea primelor caractere din derivarile fiecarui neterminal *)
let cstep gram cmap =
  M.mapi (fun c cset ->        (* transforma dict. cu o functie de cheie si valoare *)
          List.fold_left (   (* peste toate productiile pentru c, v. mai jos *)
              fun cs str ->
              let c = str.[0] in        (* primul caracter din productie *)
              (* adauga la multimea curenta multimea caracterelor cu care
               * poate incepe c, daca e neterminal, altfel { c } *)
              S.union cs (try M.find c cmap with Not_found -> S.singleton c)
            ) cset (M.find c gram) (* peste lista productiilor pentru c *)
         ) cmap
         
let fset = fixmap (cstep gram) (M.map (fun _ -> S.empty) gram)                        ;;

M.bindings (M.map S.elements fset)

This document was generated using caml2html