|
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;
|