DCGs normally operate on lists of tokens. However, by redefining 'C'/3, it is possible to let them manipulate other data structures. The example shows how to parse directly from an I/O stream.
[eclipse 1]: [user]. sentence --> noun, [is], adjective. noun --> [prolog] ; [lisp]. adjective --> [boring] ; [great]. user compiled traceable 560 bytes in 0.05 seconds yes. [eclipse 2]: phrase(sentence, [prolog,is,great], []). yes. [eclipse 3]: [user]. :- local 'C'/3. % to avoid a redefinition warning 'C'(Stream-Pos0, Token, Stream-Pos1) :- seek(Stream, Pos0), read_string(Stream, " ", _, TokenString), atom_string(Token, TokenString), at(Stream, Pos1). user compiled traceable 308 bytes in 0.00 seconds yes. [eclipse 4]: open(string("prolog is great"), read, S), phrase(sentence, S-0, S-End). S = 9 End = 15 More? (;) yes.