+let traversal g =
+ let start_symbol = (Node.of_int 0) in
+ let dummy_leaf = Leaf (Node.nil) in
+ let rec start_loop idx =
+ TRACE("grammar", 2, __ "start_loop %a\n%!" Node.print idx);
+ if idx >= Node.null then begin
+ let symbol = get_symbol_at g start_symbol idx in
+ if is_terminal symbol then
+ let () = ();TRACE("grammar", 2, __ "Symbol %a is terminal\n%!" Node.print symbol); in
+ let ts = terminal symbol in
+ if is_nil g ts then (TRACE("grammar", 2, __ "Symbol %a is nil\n%!" Node.print symbol)) else
+(* let str = get_tag g ts in
+ Printf.printf "<%s>%!" str; *)
+ let fs = first_child g start_symbol idx in
+ start_loop fs;
+ start_loop (next_sibling g start_symbol fs);
+(* 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;
+ Leaf c)
+ in
+ rule_loop tn a_param
+ end
+
+ and rule_loop (t : n_symbol) a_param =
+ TRACE("grammar", 2, __ "rule_loop %a, (%i) \n%!" Node.print t (Array.length a_param));
+ let id1 = get_id1 g t in
+ let id2 = get_id2 g t in
+ let param_pos = get_param_pos g t in
+ let nparam1 = num_children id1 in
+ let nparam2 = if is_terminal id2 && is_nil g (terminal id2) then 0 else num_children id2 in
+ let a_param1 = Array.create nparam1 dummy_leaf in
+ let a_param2 = Array.create nparam2 dummy_leaf in
+ let i = param_pos - 2 in
+ TRACE("grammar", 2, __ "id1: %i, id2: %i, param_pos: %i, nparam1: %i, nparam2: %i, i: %i\n%!"
+ (Node.to_int id1) (Node.to_int id2) param_pos nparam1 nparam2 i);
+
+ TRACE("grammar", 2, __ "blit a(%i) %i b(%i) %i %i\n%!"
+ (Array.length a_param) 0 (Array.length a_param1) 0 (i+1));
+
+ Array.blit a_param 0 a_param1 0 (i+1); (* Pass parameters before id2 *)
+ a_param1.(i+1) <- Node(id2, a_param2); (* id2( ... ) *)
+
+ TRACE("grammar", 2, __ "blit a(%i) %i b(%i) %i %i\n%!"
+ (Array.length a_param) (i + nparam2 + 1) (Array.length a_param1) (i+2) (nparam1 - i - 2));
+ Array.blit a_param (i + nparam2 + 1) a_param1 (i+2) (nparam1 - i - 2); (* Pass parameters after id2 *)
+
+
+
+ TRACE("grammar", 2, __ "blit a(%i) %i b(%i) %i %i\n\n\n%!"
+ (Array.length a_param) (i + 1) (Array.length a_param2) 0 (nparam2));
+ Array.blit a_param (i + 1) a_param2 0 nparam2; (* parameters below id2 *)
+ if is_non_terminal id1 then
+ let id1 = non_terminal id1 in
+ rule_loop id1 a_param1
+ else
+ let id1 = terminal id1 in
+ terminal_loop id1 a_param1
+
+ and terminal_loop (t : t_symbol) a_param =
+ if is_nil g t then () else begin
+(* let str = get_tag g t in *)
+(* Printf.printf "<%s>%!" str; *)
+ partial_loop a_param.(0);
+ partial_loop a_param.(1)
+(* Printf.printf "</%s>%!" str *)
+ end
+ and partial_loop = function
+ | Leaf id -> start_loop id
+ | Node (id, a_param) ->
+ if is_terminal id then terminal_loop (terminal id) a_param
+ else rule_loop (non_terminal id) a_param
+ in
+
+ start_loop (Node.null)
+;;
+
+
+