(* citeste formula booleana pana la sfarsitul intrarii; tipareste
 * operatori: + (sau), * (si), ~ (nu). propozitii: litere
 * din linia de comanda compilati: ocamlc printexp.ml -o printexp.exe
 * si rulati printexp.exe sau ./printexp.exe *)

open Scanf

type boolform = V of char
              | Neg of boolform
              | Or of boolform * boolform 
              | And of boolform * boolform 

let rec expr() =        (* citeste si returneaza expresie: disjunctie de termeni *)
  let factor () =         (* factor ::= p | ~ expr | ( expr ) *)
    try scanf " (" ();        (* incepe cu paranteza ? *)
        let e = expr() in        (* citeste o expresie *)
        try scanf " )" (); e        (* daca se termina cu ) returneaza expresia *)
        with Scan_failure _ | End_of_file -> failwith "missing )"
    with Scan_failure _ ->        (* nu a fost paranteza *)
      scanf "%c" (function        (* citeste un caracter *)
                   | '~' -> Neg (expr())        (* citeste si neaga expresie *)
                   | 'A'..'Z' | 'a'..'z' as c -> V c  (* litera = propozitie *)
                   | _ -> failwith "expected ( ~ or letter")
  in let term() =        (* conjunctie de factori *)
       let rec term1 t =        (* t = termenul citit pana acum *)
         try scanf " *" (); term1 (And(t, factor()))        (* citeste factor, creeaza And, continua *)
         with Scan_failure _ | End_of_file -> t                (* gata factorii, returneaza termenul *)
       in term1 (factor())        (* citeste un factor, formeaza restul termenului *)
     in let rec expr1 e =        (* e = expresia citita pana acum *)
          try scanf " +" (); expr1 (Or(e, term()))        (* citeste termen, creeaza Or, continua *)
          with Scan_failure _ | End_of_file -> e        (* gata termenii, returneaza expresia *)
        in expr1 (term())        (* citeste un termen, formeaza restul expresiei *)

let rec print_expr =        (* versiune primitiva, cu multe paranteze *)
  let print_binop e1 op e2 = print_char '('; print_expr e1; print_char op;
                             print_expr e2; print_char ')'
  in function
  | V c -> print_char c
  | Neg e -> print_string "(~"; print_expr e; print_char ')'
  | And (e1, e2) -> print_binop e1 '*' e2
  | Or (e1, e2) -> print_binop e1 '+' e2
              
let e = expr()

let _ = print_expr e; print_newline()

This document was generated using caml2html