//////////////////////////////////////////// Grammar stuff
-extern "C" value caml_grammar_load(value file, value load_bp)
+extern "C" value caml_grammar_load(value file, value load_bp)
{
CAMLparam2(file, load_bp);
CAMLlocal1(result);
CAMLreturn(result);
}
+extern "C" value caml_grammar_get_symbol_at(value grammar, value symbol, value preorder)
+{
+ CAMLparam3(grammar, symbol, preorder);
+ CAMLreturn(Val_long(GRAMMAR(grammar)->getSymbolAt(Long_val(symbol), Int_val(preorder))));
+
+}
+
+extern "C" value caml_grammar_first_child(value grammar, value rule, value pos)
+{
+ CAMLparam1(grammar);
+ CAMLreturn(Val_int(GRAMMAR(grammar)->firstChild(Long_val(rule), Int_val(pos))));
+}
+
+extern "C" value caml_grammar_next_sibling(value grammar, value rule, value pos)
+{
+ CAMLparam1(grammar);
+ CAMLreturn(Val_int(GRAMMAR(grammar)->nextSibling(Long_val(rule), Int_val(pos))));
+}
+
+extern "C" value caml_grammar_is_nil(value grammar, value rule)
+{
+ CAMLparam1(grammar);
+ CAMLreturn(Val_bool(GRAMMAR(grammar)->isNil(Long_val(rule))));
+}
+
+extern "C" value caml_grammar_get_tag(value grammar, value symbol)
+{
+ CAMLparam1(grammar);
+ CAMLlocal1(res);
+ const char * s = (GRAMMAR(grammar)->getTagName(Long_val(symbol) >> 2)).c_str();
+ res = caml_copy_string(s);
+ CAMLreturn(res);
+}
type t
+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
+
external load : Unix.file_descr -> bool -> t = "caml_grammar_load"
+
+
+let traversal g =
+ let start_symbol = (Node.of_int 0) in
+ let rec start_loop idx =
+ if idx >= Node.null then begin
+ let symbol = get_symbol_at g start_symbol idx in
+ if is_terminal symbol then
+ let ts = terminal symbol in
+ if is_nil g ts then () else
+ let str = get_tag g ts in
+ Printf.printf "<%s>%!" str;
+ start_loop (first_child g start_symbol idx);
+ start_loop (next_sibling g start_symbol idx);
+ Printf.printf "</%s>%!" str;
+ else
+ let tn = non_terminal symbol in
+ let nparam = num_params tn in
+ let child = ref (first_child g start_symbol idx) in
+ let a_param = Array.init nparam
+ (fun _ -> let c = !child in
+ child := next_sibling g start_symbol c;
+ c)
+ in
+ rule_loop tn a_param
+ end
+ and rule_loop (nterm : [ `NonTerminal | `Terminal ] Node.t) a_param =
+ let
+
+ in
+ start_loop (Node.of_int 0)
+;;
+
+
+
let load filename bp =
let fd = Unix.openfile filename [ Unix.O_RDONLY ] 0o600 in
let g =
Unix.close fd;
g
+