Thank you, Ralph for your kind reply.<div><br></div><div>It seems there is at least one problem with this approach. The thing is that a whole file is one huge string, as it doesn't contain '\n' (floats are separated by " " space char). If you are interested in more formal description of a problem you could refer</div>
<div><br></div><div><a href="http://www.rsdn.ru/forum/decl/2848651.flat.aspx">http://www.rsdn.ru/forum/decl/2848651.flat.aspx</a> (russian)</div><div><a href="http://translate.google.ru/translate?js=y&prev=_t&hl=ru&ie=UTF-8&layout=1&eotf=1&u=http://www.rsdn.ru/forum/decl/2848651.flat.aspx&sl=ru&tl=en">http://translate.google.ru/translate?js=y&prev=_t&hl=ru&ie=UTF-8&layout=1&eotf=1&u=http://www.rsdn.ru/forum/decl/2848651.flat.aspx&sl=ru&tl=en</a> (google-translated)</div>
<div><br></div><div>So I believe your solution would be close to reading whole file to memory.</div><div><br></div><div>Also, I don't like <span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; ">parsing_utils for several reasons.</span></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;">First - it's not flexible. Say, I want to parse not floats, but hex nubers or smth. else.</span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;">Second - its stability stated as low..</span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;">And third - it operates over string and current position, and my experiments seem to show that this way is not as fast as operating on list of chars. </span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;">(Btw, interesting that Visual Prolog is very fast when operating on strings, namely their predicates front, frontChar, etc.. as if internally they represent string as list of chars(?). Sad, but Mercury analog string.first_char (and others) creating a copy of Rest in favour of GC, thus resulting in poor performance and large mem usage. But even using approach parse_state(position, string) performs way slowly then dcg over list of chars or Visual Prolog strings) </span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;"><br>
</span></font><div class="gmail_quote">On Tue, May 18, 2010 at 3:52 AM, Ralph Becket <span dir="ltr"><<a href="mailto:rafe@csse.unimelb.edu.au">rafe@csse.unimelb.edu.au</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hi Vladimir,<br>
<br>
I'd recommend doing something like this: reading your file one line at a<br>
time with io.read_line_as_string then using the parsing_utils library to<br>
extract the floats from each line:<br>
<br>
    io.read_line_as_string(Result, !IO),<br>
    (<br>
        Result = ok(String),<br>
        some [!PS] (<br>
            parsing_utils.new_src_and_ps(String, Src, PS),<br>
            ( if<br>
                parsing_utils.zero_or_more(parsing_utils.float_literal,<br>
                    Src, Xs, !PS),<br>
                parsing_utils.eof(Src, _, !PS)<br>
              then<br>
                ... do something with Xs (a list of floats) ...<br>
              else<br>
                ... report a syntax error ...<br>
            )<br>
        )<br>
    ;<br>
        Result = eof<br>
    ;<br>
        Result = error(ErrorCode),<br>
        ... report the IO error ...<br>
    )<br>
<br>
Hope this helps!<br>
-- Ralph<br>
<br>
Vladimir Gubarkov, Monday, 17 May 2010:<br>
<div><div></div><div class="h5">><br>
>    Hi,<br>
><br>
>    Imagine I have a long enough (to fit in memory) text file with regular<br>
>    data, say, a lot of float numbers, divided by space.<br>
><br>
>    Now I want to parse those to find the sum of all numbers. In prolog<br>
>    (namely, SWI) I used 'phrase_from_file' predicate which allowed to<br>
>    parse file by DCG in lazy manner (no need to read whole file to<br>
>    memory). If it's interesting I used next code:<br>
><br>
>    :- set_prolog_flag(float_format,'%.15g').<br>
>    integer(I) --><br>
>            digit(D0),<br>
>            digits(D),<br>
>            { number_chars(I, [D0|D])<br>
>            }.<br>
>    digits([D|T]) --><br>
>            digit(D), !,<br>
>            digits(T).<br>
>    digits([]) --><br>
>            [].<br>
>    digit(D) --><br>
>            [D],<br>
>            { code_type(D, digit)<br>
>            }.<br>
>    float(F) --><br>
>        ( "-", {Sign = -1}<br>
>        ; "", {Sign = 1}<br>
>        ), !,<br>
>        integer(N),<br>
>        ",",<br>
>        integer(D),<br>
>        {F is Sign * (N + D / 10^(ceiling(log10(D))))<br>
>        }.<br>
>    sum(S, Total) --><br>
>        float(F1), !,<br>
>        " ",<br>
>        { S1 is S + F1},<br>
>        sum(S1, Total).<br>
>    sum(Total, Total) --><br>
>        [].<br>
>    go1 :-<br>
>        phrase_from_file(sum(0, S),'numbers_large.txt',<br>
>    [buffer_size(16384)]),<br>
>        writeln(S).<br>
><br>
>    Now, for an excercise in mercury, I'm willing to write the mercury<br>
>    analog. If I understand correctly there is no direct analog to<br>
>    'phrase_from_file' in mercury, am I right?<br>
><br>
>    So, I decided to fake this by constructing some type like:<br>
><br>
>    :- type parse_state ---> state(buffer_size, buffer, io.state).<br>
>    :- type buffer_size == int.<br>
>    :- type buffer == list(char).<br>
><br>
>    and pass this aroung those predicates like<br>
><br>
>    :- pred some_dcg_pred(some_term::out, parse_state::in,<br>
>    parse_state::out) is semidet.<br>
><br>
>    My thought was that I would take chars from 'buffer', and if it's<br>
>    empty -> read 'buffer_size' chars from io.state.<br>
><br>
>    But! It seems that io library provides no support for buffered reading<br>
>    Oo. And without that, I guess, it'll be rather slow (reading 1 char at<br>
>    a time). Interesting, that I've looked inside the source of io module<br>
>    and it internally uses buffered reading, but predicates not exported<br>
>    to interface of those.<br>
><br>
>    Diar sirs, what could you recommend on writing efficient (as well as<br>
>    elegant) analog to prolog code?<br>
><br>
>    Sincerely yours,<br>
><br>
>    Vladimir.<br>
</div></div>--------------------------------------------------------------------------<br>
mercury-users mailing list<br>
Post messages to:       <a href="mailto:mercury-users@csse.unimelb.edu.au">mercury-users@csse.unimelb.edu.au</a><br>
Administrative Queries: <a href="mailto:owner-mercury-users@csse.unimelb.edu.au">owner-mercury-users@csse.unimelb.edu.au</a><br>
Subscriptions:          <a href="mailto:mercury-users-request@csse.unimelb.edu.au">mercury-users-request@csse.unimelb.edu.au</a><br>
--------------------------------------------------------------------------<br>
</blockquote></div><br></div>