open Scanf

type regexp = Void | Eps | Sym of char
              | Alt of regexp * regexp (* alternativa, reuniune *)
              | Seq of regexp * regexp (* secventiere, concatenare *)
              | Rep of regexp        (* inchidere Kleene, repetitie *)

let matchc c =        (* daca apare acel caracter, il citeste *)
  try scanf "%0c" (fun c1 -> (c1 = c) && (scanf "%_c"(); true))
  with End_of_file -> false

(* citeste expresie regulata fara spatii, cu | pentru alternativa *)
let read_regexp() =
  let rec read_rex() = 
    let read_seq() =        (* concatenare, poate include * Kleene *)
      let read_atom() =        (* caracter, sau expresie in paranteze *)
        if matchc '(' then 
          let r = read_rex() in
          if matchc ')' then r else failwith "missing )"
        else scanf "%1[^ \t\n\r)*|]"
          (fun s -> if s = "" then raise Exit else Sym s.[0])
      in let read_term() = (* atom, cu zero sau mai multe stele Kleene *)
           let rec read_stars e1 =
             if matchc '*' then read_stars (Rep e1) else e1
           in read_stars(read_atom()) 
         in let rec read_rep e1 = (* sir de concatenari *)
              try read_rep (Seq (e1, read_term())) with Exit -> e1
            in read_rep(read_term())
    in let rec read_alt e1 = (* una sau mai multe alternative, cu | *)
         if matchc '|' then read_alt (Alt (e1, read_seq())) else e1
       in read_alt(read_seq()) 
  in let r = try read_rex(); with Exit -> failwith "empty regexp"
     in try scanf "%c" (fun c -> if c == '\n' then r else
         failwith ("illegal character " ^ (Char.escaped c)))
       with End_of_file -> r        (* verifica terminarea cu \n sau EOF *)
         
let _ = read_regexp()

This document was generated using caml2html