open Format open Bnf_spec.Bnf open Spec let before_first iterator f_begin f_end fall = let start = ref true in let do_el el = if !start then (start := false; fall el) else ( f_begin (); let res = fall el in f_end (); res) in iterator do_el let string_of_t t = let str = String.escaped t in let len = String.length str in let res = String.make (len + 2) '"' in String.blit str 0 res 1 len; res let string_of_nt nt = let str = String.escaped nt in let len = String.length str in let res = String.make (len + 4) '"' in res.[0] <- '<'; res.[len + 3] <- '>'; String.blit str 0 res 2 len; res let string_of_symbol = function | T t -> string_of_t t | NT nt -> string_of_nt nt let rec pp_prod ppf = function | [] -> () | [h] -> fprintf ppf "%s" (string_of_symbol h) | h::t -> fprintf ppf "%s@ " (string_of_symbol h); pp_prod ppf t let pp_prods ppf = before_first ProdSet.iter (fun _ -> fprintf ppf "@ @[| ") (pp_close_box ppf) (fun (_, sym_list) -> fprintf ppf "@[%a@]" pp_prod sym_list) let pp_live_prods ppf = before_first ProdMap.iter (fun _ -> fprintf ppf "@ @[| ") (pp_close_box ppf) (fun (_, sym_list) n -> fprintf ppf "@[%a (%d)@]" pp_prod sym_list n) let pp_nt ppf nt = fprintf ppf "@[<0>%s @[<1>:= %a .@]@]" (string_of_nt nt) pp_prods let pp_live_nt ppf nt (d, prods) = fprintf ppf "@[<0>%s (%d) @[<1>:= %a .@]@]" (string_of_nt nt) d pp_live_prods prods let nop _ = () let pp_nt_map ppf = before_first NTMap.iter force_newline nop (pp_nt ppf) let pp_live_nts ppf = before_first NTMap.iter force_newline nop (pp_live_nt ppf) let pp_ts ppf = before_first TSet.iter force_newline nop (fun t -> pp_print_string ppf (string_of_t t)) let pp_nts ppf = before_first NTSet.iter force_newline nop (fun nt -> pp_print_string ppf (string_of_nt nt)) let pp_prods ppf = before_first ProdSet.iter force_newline nop (fun (_, sl) -> pp_prod ppf sl)