Now that I had to try and motivate my choices, I changed my mind. Greedy parsing is probably more useful if we do not generate a list, by default. Maybe the functionality in my half-baked module detparse is meant to be used with library(intercept). You can still collect all elements to a list using intercept_all/4 and nb_intercept_all/4.
$ cat greedyparse.pl
:- module(greedyparse, [greedy_sequence//1,
greedy_sequence//2,
greedy_sequence//4]).
:- meta_predicate greedy_sequence(3, ?, ?).
:- meta_predicate greedy_sequence(3, //, ?, ?).
:- meta_predicate greedy_sequence(//, 3, //, //, ?, ?).
:- use_module(library(intercept)).
greedy_sequence(Goal) -->
call(Goal, X),
{ send_signal(X) },
!,
greedy_sequence(Goal).
greedy_sequence(_) --> [].
greedy_sequence(Goal, Sep) -->
call(Goal, X),
{ send_signal(X) },
greedy_sequence_1(Goal, Sep).
greedy_sequence_1(Goal, Sep) -->
Sep,
call(Goal, X),
{ send_signal(X) },
!,
greedy_sequence_1(Goal, Sep).
greedy_sequence_1(_, _) --> [].
greedy_sequence(Start, Goal, Sep, End) -->
Start,
greedy_sequence(Goal, Sep),
End.
With this, I can still make a list if I wanted to:
?- intercept_all(N, phrase(greedy_sequence("|", integer, "|", "|"), `|1|2|3|`), N, L).
L = [1, 2, 3].
… but I can also parse a large file in constant memory, intercepting only those elements that are interesting to me.
@jan Do you think there is any merit to doing this? How about adding those predicates to a library? Where should they go and what should they be called and so on? Are they useful and is the interface good?