From 7b50894295e91036042de481e02edb71842a6e7a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kim=20Nguy=E1=BB=85n?= Date: Wed, 15 Feb 2012 19:09:37 +0100 Subject: [PATCH] Temporary commit. --- src/OCamlDriver.cpp | 35 +++++++++++++++++++- src/grammar.ml | 78 +++++++++++++++++++++++++++++++++++++++++++++ src/grammar.mli | 1 + 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/src/OCamlDriver.cpp b/src/OCamlDriver.cpp index cd7fed4..0f15f49 100644 --- a/src/OCamlDriver.cpp +++ b/src/OCamlDriver.cpp @@ -899,7 +899,7 @@ BV_QUERY(lessthan, LessThan) //////////////////////////////////////////// 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); @@ -916,3 +916,36 @@ extern "C" value caml_grammar_load(value file, value load_bp) 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); +} diff --git a/src/grammar.ml b/src/grammar.ml index 6537cb2..7795150 100644 --- a/src/grammar.ml +++ b/src/grammar.ml @@ -1,7 +1,84 @@ 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 "%!" 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 = @@ -11,3 +88,4 @@ let load filename bp = Unix.close fd; g + diff --git a/src/grammar.mli b/src/grammar.mli index 3e355d4..29fc43c 100644 --- a/src/grammar.mli +++ b/src/grammar.mli @@ -1,3 +1,4 @@ type t +type node = [ `Grammar ] Node.t val load : string -> bool -> t -- 2.17.1