+type node = [ `Grammar ] Node.t
+type symbol = [ `Terminal | `NonTerminal | `Parameter ] Node.t
+
+type p_symbol = [ `Parameter ] Node.t
+type n_symbol = [ `NonTerminal ] Node.t
+type t_symbol = [ `Terminal ] Node.t
+
+type partial = Node of n_symbol * partial array | Leaf of node
+
+
+
+
+external is_nil : t -> t_symbol -> bool = "caml_grammar_is_nil"
+external get_tag : t -> t_symbol -> string = "caml_grammar_get_tag"
+
+external get_symbol_at : t -> symbol -> node -> symbol = "caml_grammar_get_symbol_at"
+external first_child : t -> symbol -> node -> node = "caml_grammar_first_child"
+external next_sibling : t -> symbol -> node -> node = "caml_grammar_next_sibling"
+
+
+let is_non_terminal (n : symbol) =
+ let n = Node.to_int n in
+ n land 3 == 0
+
+let is_terminal (n : symbol) =
+ let n = Node.to_int n in
+ n land 3 == 1
+
+let is_parameter (n : symbol) =
+ let n = Node.to_int n in
+ n land 3 == 2
+
+
+external parameter : symbol -> p_symbol = "%identity"
+external terminal : symbol -> t_symbol = "%identity"
+external non_terminal : symbol -> n_symbol = "%identity"
+
+
+let num_params (n : n_symbol) =
+ let n = Node.to_int n in
+ (n lsr 2) land 0xf
+