Blame camlp4/Camlp4/Struct/Grammar/Print.ml

Packit 1f8b6b
(****************************************************************************)
Packit 1f8b6b
(*                                                                          *)
Packit 1f8b6b
(*                                   OCaml                                  *)
Packit 1f8b6b
(*                                                                          *)
Packit 1f8b6b
(*                            INRIA Rocquencourt                            *)
Packit 1f8b6b
(*                                                                          *)
Packit 1f8b6b
(*  Copyright  2006   Institut National de Recherche  en  Informatique et   *)
Packit 1f8b6b
(*  en Automatique.  All rights reserved.  This file is distributed under   *)
Packit 1f8b6b
(*  the terms of the GNU Library General Public License, with the special   *)
Packit 1f8b6b
(*  exception on linking described in LICENSE at the top of the Camlp4      *)
Packit 1f8b6b
(*  source tree.                                                            *)
Packit 1f8b6b
(*                                                                          *)
Packit 1f8b6b
(****************************************************************************)
Packit 1f8b6b
Packit 1f8b6b
(* Authors:
Packit 1f8b6b
 * - Daniel de Rauglaudre: initial version
Packit 1f8b6b
 * - Nicolas Pouillard: refactoring
Packit 1f8b6b
 *)
Packit 1f8b6b
Packit 1f8b6b
module Make (Structure : Structure.S) = struct
Packit 1f8b6b
  open Structure;
Packit 1f8b6b
  open Format;
Packit 1f8b6b
  open Sig.Grammar;
Packit 1f8b6b
Packit 1f8b6b
  value rec flatten_tree =
Packit 1f8b6b
    fun
Packit 1f8b6b
    [ DeadEnd -> []
Packit 1f8b6b
    | LocAct _ _ -> [[]]
Packit 1f8b6b
    | Node {node = n; brother = b; son = s} ->
Packit 1f8b6b
        [ [n :: l] | l <- flatten_tree s ] @ flatten_tree b ];
Packit 1f8b6b
Packit 1f8b6b
  value rec print_symbol ppf =
Packit 1f8b6b
    fun
Packit 1f8b6b
    [ Smeta n sl _ -> print_meta ppf n sl
Packit 1f8b6b
    | Slist0 s -> fprintf ppf "LIST0 %a" print_symbol1 s
Packit 1f8b6b
    | Slist0sep s t ->
Packit 1f8b6b
        fprintf ppf "LIST0 %a SEP %a" print_symbol1 s print_symbol1 t
Packit 1f8b6b
    | Slist1 s -> fprintf ppf "LIST1 %a" print_symbol1 s
Packit 1f8b6b
    | Slist1sep s t ->
Packit 1f8b6b
        fprintf ppf "LIST1 %a SEP %a" print_symbol1 s print_symbol1 t
Packit 1f8b6b
    | Sopt s -> fprintf ppf "OPT %a" print_symbol1 s
Packit 1f8b6b
    | Stry s -> fprintf ppf "TRY %a" print_symbol1 s
Packit 1f8b6b
    | Snterml e l -> fprintf ppf "%s@ LEVEL@ %S" e.ename l
Packit 1f8b6b
    | Snterm _ | Snext | Sself | Stree _ | Stoken _ | Skeyword _ as s ->
Packit 1f8b6b
        print_symbol1 ppf s ]
Packit 1f8b6b
  and print_meta ppf n sl =
Packit 1f8b6b
    loop 0 sl where rec loop i =
Packit 1f8b6b
      fun
Packit 1f8b6b
      [ [] -> ()
Packit 1f8b6b
      | [s :: sl] ->
Packit 1f8b6b
          let j =
Packit 1f8b6b
            try String.index_from n i ' ' with [ Not_found -> String.length n ]
Packit 1f8b6b
          in
Packit 1f8b6b
          do {
Packit 1f8b6b
            fprintf ppf "%s %a" (String.sub n i (j - i)) print_symbol1 s;
Packit 1f8b6b
            if sl = [] then ()
Packit 1f8b6b
            else do { fprintf ppf " "; loop (min (j + 1) (String.length n)) sl }
Packit 1f8b6b
          } ]
Packit 1f8b6b
  and print_symbol1 ppf =
Packit 1f8b6b
    fun
Packit 1f8b6b
    [ Snterm e -> pp_print_string ppf e.ename
Packit 1f8b6b
    | Sself -> pp_print_string ppf "SELF"
Packit 1f8b6b
    | Snext -> pp_print_string ppf "NEXT"
Packit 1f8b6b
    | Stoken (_, descr) -> pp_print_string ppf descr
Packit 1f8b6b
    | Skeyword s -> fprintf ppf "%S" s
Packit 1f8b6b
    | Stree t -> print_level ppf pp_print_space (flatten_tree t)
Packit 1f8b6b
    | Smeta _ _ _ | Snterml _ _ | Slist0 _ | Slist0sep _ _ | Slist1 _ |
Packit 1f8b6b
      Slist1sep _ _ | Sopt _ | Stry _ as s ->
Packit 1f8b6b
        fprintf ppf "(%a)" print_symbol s ]
Packit 1f8b6b
  and print_rule ppf symbols =
Packit 1f8b6b
    do {
Packit 1f8b6b
      fprintf ppf "@[<hov 0>";
Packit 1f8b6b
      let _ =
Packit 1f8b6b
        List.fold_left
Packit 1f8b6b
          (fun sep symbol ->
Packit 1f8b6b
            do {
Packit 1f8b6b
              fprintf ppf "%t%a" sep print_symbol symbol;
Packit 1f8b6b
              fun ppf -> fprintf ppf ";@ "
Packit 1f8b6b
            })
Packit 1f8b6b
          (fun _ -> ()) symbols
Packit 1f8b6b
      in
Packit 1f8b6b
      fprintf ppf "@]"
Packit 1f8b6b
    }
Packit 1f8b6b
  and print_level ppf pp_print_space rules =
Packit 1f8b6b
    do {
Packit 1f8b6b
      fprintf ppf "@[<hov 0>[ ";
Packit 1f8b6b
      let _ =
Packit 1f8b6b
        List.fold_left
Packit 1f8b6b
          (fun sep rule ->
Packit 1f8b6b
            do {
Packit 1f8b6b
              fprintf ppf "%t%a" sep print_rule rule;
Packit 1f8b6b
              fun ppf -> fprintf ppf "%a| " pp_print_space ()
Packit 1f8b6b
            })
Packit 1f8b6b
          (fun _ -> ()) rules
Packit 1f8b6b
      in
Packit 1f8b6b
      fprintf ppf " ]@]"
Packit 1f8b6b
    }
Packit 1f8b6b
  ;
Packit 1f8b6b
Packit 1f8b6b
  value levels ppf elev =
Packit 1f8b6b
    let _ =
Packit 1f8b6b
      List.fold_left
Packit 1f8b6b
        (fun sep lev ->
Packit 1f8b6b
          let rules =
Packit 1f8b6b
            [ [Sself :: t] | t <- flatten_tree lev.lsuffix ] @
Packit 1f8b6b
              flatten_tree lev.lprefix
Packit 1f8b6b
          in
Packit 1f8b6b
          do {
Packit 1f8b6b
            fprintf ppf "%t@[<hov 2>" sep;
Packit 1f8b6b
            match lev.lname with
Packit 1f8b6b
            [ Some n -> fprintf ppf "%S@;<1 2>" n
Packit 1f8b6b
            | None -> () ];
Packit 1f8b6b
            match lev.assoc with
Packit 1f8b6b
            [ LeftA -> fprintf ppf "LEFTA"
Packit 1f8b6b
            | RightA -> fprintf ppf "RIGHTA"
Packit 1f8b6b
            | NonA -> fprintf ppf "NONA" ];
Packit 1f8b6b
            fprintf ppf "@]@;<1 2>";
Packit 1f8b6b
            print_level ppf pp_force_newline rules;
Packit 1f8b6b
            fun ppf -> fprintf ppf "@,| "
Packit 1f8b6b
          })
Packit 1f8b6b
        (fun _ -> ()) elev
Packit 1f8b6b
    in
Packit 1f8b6b
    ();
Packit 1f8b6b
Packit 1f8b6b
  value entry ppf e =
Packit 1f8b6b
    do {
Packit 1f8b6b
      fprintf ppf "@[<v 0>%s: [ " e.ename;
Packit 1f8b6b
      match e.edesc with
Packit 1f8b6b
      [ Dlevels elev -> levels ppf elev
Packit 1f8b6b
      | Dparser _ -> fprintf ppf "<parser>" ];
Packit 1f8b6b
      fprintf ppf " ]@]"
Packit 1f8b6b
    };
Packit 1f8b6b
Packit 1f8b6b
end;
Packit 1f8b6b
Packit 1f8b6b
module MakeDump (Structure : Structure.S) = struct
Packit 1f8b6b
  open Structure;
Packit 1f8b6b
  open Format;
Packit 1f8b6b
  open Sig.Grammar;
Packit 1f8b6b
Packit 1f8b6b
  type brothers = [ Bro of symbol and list brothers ];
Packit 1f8b6b
Packit 1f8b6b
  value rec print_tree ppf tree =
Packit 1f8b6b
    let rec get_brothers acc =
Packit 1f8b6b
      fun
Packit 1f8b6b
      [ DeadEnd -> List.rev acc
Packit 1f8b6b
      | LocAct _ _ -> List.rev acc
Packit 1f8b6b
      | Node {node = n; brother = b; son = s} -> get_brothers [Bro n (get_brothers [] s) :: acc] b ]
Packit 1f8b6b
    and print_brothers ppf brothers =
Packit 1f8b6b
      if brothers = [] then fprintf ppf "@ []"
Packit 1f8b6b
      else
Packit 1f8b6b
        List.iter (fun [ Bro n xs -> do {
Packit 1f8b6b
          fprintf ppf "@ @[<hv2>- %a" print_symbol n;
Packit 1f8b6b
          match xs with
Packit 1f8b6b
          [ [] -> ()
Packit 1f8b6b
          | [_] -> try print_children ppf (get_children [] xs)
Packit 1f8b6b
                   with [ Exit -> fprintf ppf ":%a" print_brothers xs ]
Packit 1f8b6b
          | _ -> fprintf ppf ":%a" print_brothers xs ];
Packit 1f8b6b
          fprintf ppf "@]";
Packit 1f8b6b
        }]) brothers
Packit 1f8b6b
    and print_children ppf = List.iter (fprintf ppf ";@ %a" print_symbol)
Packit 1f8b6b
    and get_children acc =
Packit 1f8b6b
      fun
Packit 1f8b6b
      [ [] -> List.rev acc
Packit 1f8b6b
      | [Bro n x] -> get_children [n::acc] x
Packit 1f8b6b
      | _ -> raise Exit ]
Packit 1f8b6b
    in print_brothers ppf (get_brothers [] tree)
Packit 1f8b6b
  and print_symbol ppf =
Packit 1f8b6b
    fun
Packit 1f8b6b
    [ Smeta n sl _ -> print_meta ppf n sl
Packit 1f8b6b
    | Slist0 s -> fprintf ppf "LIST0 %a" print_symbol1 s
Packit 1f8b6b
    | Slist0sep s t ->
Packit 1f8b6b
        fprintf ppf "LIST0 %a SEP %a" print_symbol1 s print_symbol1 t
Packit 1f8b6b
    | Slist1 s -> fprintf ppf "LIST1 %a" print_symbol1 s
Packit 1f8b6b
    | Slist1sep s t ->
Packit 1f8b6b
        fprintf ppf "LIST1 %a SEP %a" print_symbol1 s print_symbol1 t
Packit 1f8b6b
    | Sopt s -> fprintf ppf "OPT %a" print_symbol1 s
Packit 1f8b6b
    | Stry s -> fprintf ppf "TRY %a" print_symbol1 s
Packit 1f8b6b
    | Snterml e l -> fprintf ppf "%s@ LEVEL@ %S" e.ename l
Packit 1f8b6b
    | Snterm _ | Snext | Sself | Stree _ | Stoken _ | Skeyword _ as s ->
Packit 1f8b6b
        print_symbol1 ppf s ]
Packit 1f8b6b
  and print_meta ppf n sl =
Packit 1f8b6b
    loop 0 sl where rec loop i =
Packit 1f8b6b
      fun
Packit 1f8b6b
      [ [] -> ()
Packit 1f8b6b
      | [s :: sl] ->
Packit 1f8b6b
          let j =
Packit 1f8b6b
            try String.index_from n i ' ' with [ Not_found -> String.length n ]
Packit 1f8b6b
          in
Packit 1f8b6b
          do {
Packit 1f8b6b
            fprintf ppf "%s %a" (String.sub n i (j - i)) print_symbol1 s;
Packit 1f8b6b
            if sl = [] then ()
Packit 1f8b6b
            else do { fprintf ppf " "; loop (min (j + 1) (String.length n)) sl }
Packit 1f8b6b
          } ]
Packit 1f8b6b
  and print_symbol1 ppf =
Packit 1f8b6b
    fun
Packit 1f8b6b
    [ Snterm e -> pp_print_string ppf e.ename
Packit 1f8b6b
    | Sself -> pp_print_string ppf "SELF"
Packit 1f8b6b
    | Snext -> pp_print_string ppf "NEXT"
Packit 1f8b6b
    | Stoken (_, descr) -> pp_print_string ppf descr
Packit 1f8b6b
    | Skeyword s -> fprintf ppf "%S" s
Packit 1f8b6b
    | Stree t -> print_tree ppf t
Packit 1f8b6b
    | Smeta _ _ _ | Snterml _ _ | Slist0 _ | Slist0sep _ _ | Slist1 _ |
Packit 1f8b6b
      Slist1sep _ _ | Sopt _ | Stry _ as s ->
Packit 1f8b6b
        fprintf ppf "(%a)" print_symbol s ]
Packit 1f8b6b
  and print_rule ppf symbols =
Packit 1f8b6b
    do {
Packit 1f8b6b
      fprintf ppf "@[<hov 0>";
Packit 1f8b6b
      let _ =
Packit 1f8b6b
        List.fold_left
Packit 1f8b6b
          (fun sep symbol ->
Packit 1f8b6b
            do {
Packit 1f8b6b
              fprintf ppf "%t%a" sep print_symbol symbol;
Packit 1f8b6b
              fun ppf -> fprintf ppf ";@ "
Packit 1f8b6b
            })
Packit 1f8b6b
          (fun _ -> ()) symbols
Packit 1f8b6b
      in
Packit 1f8b6b
      fprintf ppf "@]"
Packit 1f8b6b
    }
Packit 1f8b6b
  and print_level ppf pp_print_space rules =
Packit 1f8b6b
    do {
Packit 1f8b6b
      fprintf ppf "@[<hov 0>[ ";
Packit 1f8b6b
      let _ =
Packit 1f8b6b
        List.fold_left
Packit 1f8b6b
          (fun sep rule ->
Packit 1f8b6b
            do {
Packit 1f8b6b
              fprintf ppf "%t%a" sep print_rule rule;
Packit 1f8b6b
              fun ppf -> fprintf ppf "%a| " pp_print_space ()
Packit 1f8b6b
            })
Packit 1f8b6b
          (fun _ -> ()) rules
Packit 1f8b6b
      in
Packit 1f8b6b
      fprintf ppf " ]@]"
Packit 1f8b6b
    }
Packit 1f8b6b
  ;
Packit 1f8b6b
Packit 1f8b6b
  value levels ppf elev =
Packit 1f8b6b
    let _ =
Packit 1f8b6b
      List.fold_left
Packit 1f8b6b
        (fun sep lev ->
Packit 1f8b6b
          do {
Packit 1f8b6b
            fprintf ppf "%t@[<v2>" sep;
Packit 1f8b6b
            match lev.lname with
Packit 1f8b6b
            [ Some n -> fprintf ppf "%S@;<1 2>" n
Packit 1f8b6b
            | None -> () ];
Packit 1f8b6b
            match lev.assoc with
Packit 1f8b6b
            [ LeftA -> fprintf ppf "LEFTA"
Packit 1f8b6b
            | RightA -> fprintf ppf "RIGHTA"
Packit 1f8b6b
            | NonA -> fprintf ppf "NONA" ];
Packit 1f8b6b
            fprintf ppf "@]@;<1 2>";
Packit 1f8b6b
            fprintf ppf "@[<v2>suffix:@ ";
Packit 1f8b6b
            print_tree ppf lev.lsuffix;
Packit 1f8b6b
            fprintf ppf "@]@ @[<v2>prefix:@ ";
Packit 1f8b6b
            print_tree ppf lev.lprefix;
Packit 1f8b6b
            fprintf ppf "@]";
Packit 1f8b6b
            fun ppf -> fprintf ppf "@,| "
Packit 1f8b6b
          })
Packit 1f8b6b
        (fun _ -> ()) elev
Packit 1f8b6b
    in
Packit 1f8b6b
    ();
Packit 1f8b6b
Packit 1f8b6b
  value entry ppf e =
Packit 1f8b6b
    do {
Packit 1f8b6b
      fprintf ppf "@[<v 0>%s: [ " e.ename;
Packit 1f8b6b
      match e.edesc with
Packit 1f8b6b
      [ Dlevels elev -> levels ppf elev
Packit 1f8b6b
      | Dparser _ -> fprintf ppf "<parser>" ];
Packit 1f8b6b
      fprintf ppf " ]@]"
Packit 1f8b6b
    };
Packit 1f8b6b
Packit 1f8b6b
end;