3 type node = [ `Grammar ] Node.t
4 type symbol = [ `Terminal | `NonTerminal | `Parameter ] Node.t
6 type p_symbol = [ `Parameter ] Node.t
7 type n_symbol = [ `NonTerminal ] Node.t
8 type t_symbol = [ `Terminal ] Node.t
10 type partial = Node of n_symbol * partial array | Leaf of node
15 external is_nil : t -> t_symbol -> bool = "caml_grammar_is_nil"
16 external get_tag : t -> t_symbol -> string = "caml_grammar_get_tag"
18 external get_symbol_at : t -> symbol -> node -> symbol = "caml_grammar_get_symbol_at"
19 external first_child : t -> symbol -> node -> node = "caml_grammar_first_child"
20 external next_sibling : t -> symbol -> node -> node = "caml_grammar_next_sibling"
23 let is_non_terminal (n : symbol) =
24 let n = Node.to_int n in
27 let is_terminal (n : symbol) =
28 let n = Node.to_int n in
31 let is_parameter (n : symbol) =
32 let n = Node.to_int n in
36 external parameter : symbol -> p_symbol = "%identity"
37 external terminal : symbol -> t_symbol = "%identity"
38 external non_terminal : symbol -> n_symbol = "%identity"
41 let num_params (n : n_symbol) =
42 let n = Node.to_int n in
45 external load : Unix.file_descr -> bool -> t = "caml_grammar_load"
50 let start_symbol = (Node.of_int 0) in
51 let rec start_loop idx =
52 if idx >= Node.null then begin
53 let symbol = get_symbol_at g start_symbol idx in
54 if is_terminal symbol then
55 let ts = terminal symbol in
56 if is_nil g ts then () else
57 let str = get_tag g ts in
58 Printf.printf "<%s>%!" str;
59 start_loop (first_child g start_symbol idx);
60 start_loop (next_sibling g start_symbol idx);
61 Printf.printf "</%s>%!" str;
63 let tn = non_terminal symbol in
64 let nparam = num_params tn in
65 let child = ref (first_child g start_symbol idx) in
66 let a_param = Array.init nparam
67 (fun _ -> let c = !child in
68 child := next_sibling g start_symbol c;
73 and rule_loop (nterm : [ `NonTerminal | `Terminal ] Node.t) a_param =
77 start_loop (Node.of_int 0)
82 let load filename bp =
83 let fd = Unix.openfile filename [ Unix.O_RDONLY ] 0o600 in
86 | e -> (Unix.close fd; raise e)