OK, well I have produced this tiny little program which so far does what I 
wanted as a first step, but I am a little confused by my somewhat miraculous 
arrival at this point and I want to make sure that I understand what is going 
on.

I ran it with tracing enabled on a small file containing just "ABC\n" and it 
was reassuring to see it do exactly what I thought it would do in the order 
that I expected it to BUT even so I would appreciate a little reassurance that 
I am on the right lines with it.

Here is the code:

lexit(Filename, Tokens) :-
    open(Filename, read, In),
    lexread(In, Tokens),
    close(In).

lexread(In, _) :- at_end_of_stream(In), !.

lexread(In, [ chr(C, Line, Col) | Tokens ]) :-
    stream_line_column(In, Line, Col),
    get_char(In, C),
    lexread(In, Tokens).

Running it:

lexit('small.txt',T).

T = [chr('A',1,1),chr('B',1,2),chr('C',1,3),chr('\n',1,4)|_]

Somehow I managed to figure out that I could put the "chr()" term inside the 
head as I read somewhere on stack overflow recently that you could do that to 
save a step or something. See, I am already running on vague, that's my lack of 
Prolog experience showing already!

The "confusing" bit is this:

    lexread(In, [ chr(C, Line, Col) | Tokens ]) :-

I can see that "Tokens" remains uninstantiated until the end-of-file condition 
triggers, at which point the complete call stack is picked up but I am unsure 
of the reasoning as to why the list comes out in the correct order, I think. I 
am seeing in my head a whole bund go .() "conses" all waiting to go ff one 
after the other.

Then this line:

    stream_line_column(In, Line, Col),

instantiates Line and Col thus the term cur(C,Line,Col) is now fully 
instantiated and then when the tail call to lexread() is made, a new temporary 
variable is created for Tokens because it is still uninstantiated. This 
continues until EOF at which point the stack frame is unwound and the list is 
constructed but why does it appear to be "right" i.e. the tokens read left to 
right in the same order as the characters in the file. I think I know but I am 
still al title shaky at this point!

I have used Haskell for a few years now and on a memory consumption 
perspective, I have a hunch this method is very very bad as it would be 
creating huge swathes of stack frames especially for a very very large file but 
I am still learning. I have no doubt that there is a cleaner way using DCG-s 
but for now this is where I am thinking on.

Thanks,
Sean.



_______________________________________________
Users-prolog mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/users-prolog

Reply via email to