caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Christoph Bauer <c_bauer@informatik.uni-kl.de>
To: OCaml List <caml-list@inria.fr>
Subject: Re: [Caml-list] Better option to read a file
Date: Wed, 17 Mar 2004 08:31:17 +0100	[thread overview]
Message-ID: <m34qso53qy.fsf@diebuntekuh.de> (raw)
In-Reply-To: <E2DFEE92-7790-11D8-938F-000393B21E00@ctima.uma.es>  =?utf-8?q?=28Agust=C3=ADn?= Valverde's message of "Tue, 16 Mar 2004 22:28:37 +0100")

Hi Agustín,

I'm not quite sure, what you want.  `leer' reads a whole file (this
whitout a upper limit on `long' a bad idea), `unir' doesn't work and
`leer2' is `read the first line of file and don't close the file'.
(Do you mean `let leer2 = input_line'?)

Because of `leer2', I assume you have a parser operating on lines.  As
Pietro I suggest the use of streams. A slightly more general approach
could improve the reuse of your code.


A file is a stream of chars but mostly you want to access whole lines
or words. Therefore we write this three functions:


let splitted_stream ~on_words char_stream = 
  let buf = Buffer.create 256 in
  let this_string () = 
    let str = Buffer.contents buf in
      Buffer.reset buf; str in
  let rec accumulate =
    parser 
	[< ''\n'; rest >] -> [< '(this_string ()); remove_cr rest >]
      | [< '' ' | '\t' as c; rest >] -> 
	  if on_words then [< '(this_string ()); accumulate rest >] 
	  else (
	    Buffer.add_char buf c;
	    accumulate rest
	  )
      | [< 'c; rest >] ->
	  Buffer.add_char buf c;
	  accumulate rest
      | [< >] -> [< >]
  and remove_cr = 
    parser 
	[< ''\r'; rest >] -> accumulate rest
      | [< rest >] -> accumulate rest
  in accumulate char_stream


let line_stream = splitted_stream ~on_words:false
let word_stream = splitted_stream ~on_words:true


Please note, that the input Stream could be obtained by Stream.of_channel,
Stream.of_string or Stream.from. The next function should apply your parser.

let rec stream_map f =
  parser
      [< 'a; rest >] -> [< '(f a); iter f rest >]
    | [< >] -> [< >]


The functions so far should be put in a generic library.

Assummed your parser is a function

parse_line: string -> 'a

then you can get the desired 'a Stream with

  let astream = stream_map parse_line (line_stream (Stream.of_channel (open_in fl)))

Regards,
Christoph Bauer




> Hi
>
> In a program  I need to read the input data from a file and I have
> written several options. I want to obtain the string of characters
> from a text file and I don't know what is the better option. Among
> others, I have written the following:
>
> First option:
>
> let leer_file fl =
>       let form = ref "" in
>       let arch = open_in fl in
>       let long = in_channel_length arch in
>       form := String.create (long-1);
>       really_input arch (!form) 0 (long-1);
>       close_in arch;
>       !form;;
>
> Second:
>
> let rec unir c ac = unir ac^(Char.escaped c);;
>
> let leer2 fl =
>       let form = ref "" in
>       let c = ref '-' in
>       let arch = open_in fl in
>       (try
>         (while true do (c := input_char arch); (if !c != '\n' then
> (form := unir !c !form) else ()) done)
>       with End_of_file -> close_in arch);
>       !form;;
>
> I also have a parser to convert the string, could I to improve these
> functions merging them with the parser in some way?
>
> Thanks for your help
>
> Agustín Valverde
> Department of Applied Mathematics
> University of Malaga, Spain
>
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>

-- 
beginfig(1)u=3cm;draw fullcircle scaled 2u;x0=x1=y1=x2=y3=0;-y0=y2=x3=1u;
filldraw z0..{left}z1{left}..z2{curl 1}..z3..z0..cycle;def t(expr p)=fullcircle
scaled .25u shifted(0,p*u);enddef;unfill t(.5);fill t(-.5);endfig;bye

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


  parent reply	other threads:[~2004-03-17  7:25 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-03-16 21:28 Agustín Valverde
2004-03-17  3:48 ` Pietro Abate
2004-03-17  7:31 ` Christoph Bauer [this message]
2004-03-17 16:42   ` Agustin Valverde Ramos
2004-03-17 17:46     ` Markus Mottl
2004-03-17 18:20       ` Agustin Valverde Ramos
2004-03-17 18:54         ` Markus Mottl
2004-03-17  8:22 ` Jean-Christophe Filliatre
2004-03-17 10:11   ` Markus Mottl
  -- strict thread matches above, loose matches on Subject: below --
2004-03-16 20:38 Agustín Valverde

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m34qso53qy.fsf@diebuntekuh.de \
    --to=c_bauer@informatik.uni-kl.de \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).