X-Git-Url: http://git.nguyen.vg/gitweb/?a=blobdiff_plain;f=src%2Fgrammar.ml;fp=src%2Fgrammar.ml;h=7795150033587d13407401998e479ac3dd979fde;hb=7b50894295e91036042de481e02edb71842a6e7a;hp=6537cb25d542e6011c8ba406fc78281a84f82d87;hpb=7166a99542af5ad2f5b53fe9fa9e5164dff7cfe5;p=SXSI%2Fxpathcomp.git 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 +