Commit 2094b634 authored by Pietro Abate's avatar Pietro Abate
Browse files

[r2003-05-22 17:05:31 by cvscast] Tail-recursive load_xml

Original author: cvscast
Date: 2003-05-22 17:05:31+00:00
parent 45170515
......@@ -51,6 +51,11 @@ let elem tag att child =
class warner = object method warn w = print_endline ("PXP WARNING: " ^ w) end
type token =
| Element of Value.t
| Start of string * (string * string) list
| String of string
let load_xml_aux s =
let config = { default_config with
(* warner = new warner; *)
......@@ -62,61 +67,47 @@ let load_xml_aux s =
let mgr = create_entity_manager config (from_file s) in
let next_event =
create_pull_parser config (`Entry_document[]) mgr in
let curr = ref E_end_of_stream in
let get () =
match next_event () with
| Some (E_error exn) -> failwith (Pxp_types.string_of_exn exn)
| Some E_end_of_stream -> failwith "Unexpected end of XML stream"
| Some x -> curr := x
| None -> () in
| Some E_end_of_stream | None -> failwith "Unexpected end of XML stream"
| Some x -> x in
let txt = create 1024 in
let rec parse_elt name att =
let elt = elem name att (parse_seq ()) in
(match !curr with
| E_end_tag (_,_) -> get ()
| _ -> failwith "Expect end_tag");
elt
and parse_seq () =
match !curr with
let rec create_elt accu = function
| String s :: st -> create_elt (string s accu) st
| Element x :: st -> create_elt (Pair (x,accu)) st
| [ Start (name,att) ] -> elem name att accu
| Start (name,att) :: st -> parse_seq (Element (elem name att accu) :: st)
| [] -> assert false
and parse_seq stack =
match get() with
| E_start_tag (name,att,_) ->
get ();
if only_ws txt.buffer txt.pos then
let () = txt.pos <- 0 in
let e1 = parse_elt name att in
let rest = parse_seq () in
Pair (e1,rest)
parse_seq (Start (name,att) :: stack)
else
let s = String.sub txt.buffer 0 txt.pos in
let () = txt.pos <- 0 in
let e1 = parse_elt name att in
let rest = parse_seq () in
let q = Pair (e1,rest) in
string s q
parse_seq (Start (name,att) :: String s :: stack)
| E_char_data data ->
get();
add_string txt data;
parse_seq ()
parse_seq stack
| E_end_tag (_,_) ->
if only_ws txt.buffer txt.pos then (txt.pos <- 0; nil)
if only_ws txt.buffer txt.pos then
(txt.pos <- 0;
create_elt nil stack)
else
let s = String.sub txt.buffer 0 txt.pos in
txt.pos <- 0;
string s nil
create_elt (string s nil) stack
| _ -> failwith "Expect start_tag, char_data, or end_tag"
and parse_doc () =
match !curr with
| E_start_tag (name,att,_) -> get (); parse_elt name att
| _ -> get (); parse_doc ()
in
get ();
let rec parse_doc () =
match get () with
| E_start_tag (name,att,_) -> parse_seq [ Start (name,att) ]
| _ -> parse_doc () in
parse_doc ()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment