(* *)
(***********************************************************************)
-(*
- Time-stamp: <Last modified on 2013-04-04 18:47:30 CEST by Kim Nguyen>
-*)
-
type node = {
tag : QName.t;
preorder : int;
type t = {
root : node;
size : int;
+ by_preorder : node array;
(* TODO add other intersting stuff *)
}
"NODE " ^ string_of_int n.preorder)
let debug_node fmt node =
- Format.fprintf fmt "{ tag=%s; preorder=%i; data=%S; first_child=%a; next_sibling=%a; parent=%a }"
+ Format.fprintf fmt
+ "{ tag=%s; preorder=%i; data=%S;\
+first_child=%a; next_sibling=%a; parent=%a }"
(QName.to_string node.tag)
node.preorder
node.data
let debug_ctx fmt ctx =
- Format.fprintf fmt "Current context: { preorder = %i\n; stack = \n%a\n }\n-------------\n"
+ Format.fprintf fmt "Current context: { preorder = %i\n; stack = \n%a\n }\
+\n-------------\n"
ctx.current_preorder
(Pretty.print_list ~sep:";\n" debug_node) ctx.stack
let node = top ctx in
node.next_sibling <- nil;
consume_closing ctx node;
- match ctx.stack with
- [ root ] ->
- root.next_sibling <- nil;
- { root = root;
- size = ctx.current_preorder
- }
- | _ -> raise (Expat.Expat_error Expat.UNCLOSED_TOKEN)
+ Expat.final psr;
+ let root = List.hd ctx.stack in
+ root.next_sibling <- nil;
+ let a = Array.create ctx.current_preorder nil in
+ let rec loop n =
+ if n != nil then
+ begin
+ a.(n.preorder) <- n;
+ loop n.first_child;
+ loop n.next_sibling;
+ end
+ in
+ loop root;
+ { root = root;
+ size = ctx.current_preorder;
+ by_preorder = a
+ }
)
+ let error e parser_ =
+ let msg = Printf.sprintf "%i.%i %s"
+ (Expat.get_current_line_number parser_)
+ (Expat.get_current_column_number parser_)
+ (Expat.xml_error_to_string e)
+ in
+ raise (Tree.Parse_error msg)
let parse_string s =
let parser_, finalize = create_parser () in
- Expat.parse parser_ s;
- finalize ()
+ try
+ Expat.parse parser_ s;
+ finalize ()
+ with
+ Expat.Expat_error e -> error e parser_
let parse_file fd =
let buffer = String.create 4096 in
if read != 0 then
let () = Expat.parse_sub parser_ buffer 0 read in
loop ()
- in loop (); finalize ()
+ in try
+ loop (); finalize ()
+ with
+ Expat.Expat_error e -> error e parser_
end
let data _ n = n.data
let kind _ n = n.kind
let preorder _ n = n.preorder
-
+let by_preorder t i =
+ if i >= 0 && i < t.size then Array.unsafe_get t.by_preorder i
+ else let e = Invalid_argument "by_preorder" in raise e
let print_node fmt n = Parser.debug_node fmt n