diff options
author | Pierre Weis <Pierre.Weis@inria.fr> | 2009-07-03 08:36:54 +0000 |
---|---|---|
committer | Pierre Weis <Pierre.Weis@inria.fr> | 2009-07-03 08:36:54 +0000 |
commit | c9839c874ae36f2eea405e90bf5aa77c17ad3d7b (patch) | |
tree | c38426e3998738cdef79c74a393d6b7dadcc8317 | |
parent | f8107f9061cd9e1b13c0523e95168e288a6414d7 (diff) |
List scanning revisited.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@9306 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r-- | test/Moretest/tscanf.ml | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/test/Moretest/tscanf.ml b/test/Moretest/tscanf.ml index f01d0297c..3a0d01a85 100644 --- a/test/Moretest/tscanf.ml +++ b/test/Moretest/tscanf.ml @@ -784,7 +784,7 @@ let rec scan_elems ib scan_elem accu = *) (* We use [kscanf] with a [%r] format ! *) -let rec scan_elems ib scan_elem accu = +let rec scan_elems scan_elem accu ib = kscanf ib (fun ib exc -> accu) "%r" (function ib -> @@ -795,14 +795,21 @@ let rec scan_elems ib scan_elem accu = " %1[;] " (function | "" -> accu - | _ -> scan_elems ib scan_elem accu))) + | _ -> scan_elems scan_elem accu ib))) (function l -> l) ;; +let scan_list scan_elem ib = + bscanf ib "[ " (); + let accu = scan_elems scan_elem [] ib in + bscanf ib " ]" (); + List.rev accu +;; + (* We may also try a version with only one format: We also changed the type of [scan_elem] to partially apply it to its ``natural'' continuation. -let rec scan_elems ib scan_elem accu = +let rec scan_elems scan_elem accu ib = (* We use [kscanf], so that: if the element reader fails, we can return the list of elements read so far. *) @@ -817,22 +824,25 @@ let rec scan_elems ib scan_elem accu = (* Cannot find a semi-colon: no more elements to read. *) if s = "" then accu (* We found a semi-colon: go on with the new accu. *) - else scan_elems ib scan_elem accu) + else scan_elems scan_elem accu ib) ;; let scan_list scan_elem ib = - bscanf ib "[ " (); - let accu = scan_elems ib scan_elem [] in - bscanf ib " ]" (); - List.rev accu + bscanf ib "[ %r ]" (scan_elems scan_elem []) List.rev ;; +(* For instance: let scan_float f ib = Scanf.bscanf ib "%f" f;; # scan_list scan_float;; - : Scanf.Scanning.scanbuf -> float list = <fun> +*) +(* The element scanner builder. *) let make_scan_elem fmt f ib = Scanf.bscanf ib fmt f;; +(* Promote an element reader format to an element list reader. *) +let list_scanner fmt = scan_list (make_scan_elem fmt);; + let scan_float = make_scan_elem "%f";; scan_list scan_float;; @@ -841,13 +851,6 @@ list_scanner "%f";; - : Scanf.Scanning.scanbuf -> float list = <fun> *) -let scan_list scan_elem ib = - bscanf ib "[ " (); - let accu = scan_elems ib scan_elem [] in - bscanf ib " ]" (); - List.rev accu -;; - (* The prototype of a [scan_elem] function for the generic [scan_list] functional. This [scan_elem] scans a floating point number. *) @@ -914,6 +917,49 @@ let test35 () = test (test35 ()) ;; +(* The prefered reader functionnals. *) + +(* To read a list as in Caml (elements are ``blank + semicolon + blank'' + separated, and the list is enclosed in brackets). *) +let rec read_elems read_elem accu ib = + kscanf ib (fun ib exc -> accu) + "%r %1[;] " + (read_elem (function elem -> elem :: accu)) + (fun accu s -> if s = "" then accu else read_elems read_elem accu ib) +;; + +let read_list read_elem ib = + bscanf ib "[ %r ]" (read_elems read_elem []) List.rev +;; + +(* The element reader builder. *) +let make_read_elem fmt f ib = Scanf.bscanf ib fmt f;; + +(* Promote an element reader format to an element list reader. *) +let scan_List fmt = read_list (make_read_elem fmt);; + +(* Example for list of floatting point numbers. *) +scan_List "%f";; +- : Scanf.Scanning.scanbuf -> float list = <fun> + +(* To read a list as a succession of elements separated by a blank. *) +let rec read_elems read_elem accu ib = + kscanf ib (fun ib exc -> accu) + "%r " + (read_elem (function elem -> elem :: accu)) + (fun accu -> read_elems read_elem accu ib) +;; + +let read_list read_elem ib = + List.rev (read_elems read_elem [] ib) +;; + +(* Promote an element reader format to an element list reader. *) +let scan_list fmt = read_list (make_read_elem fmt);; + +scan_list "%f";; +*) + (* Testing the %n format. *) let test36 () = sscanf "" "%n" (fun x -> x) = 0 && |