DCGs are in principle not limited to the parsing of lists. The predicate 'C'/3 is responsible for reading resp. generating the input tokens. The default definition is
The first argument represents the parsing input before consuming Token and Rest is the input after consuming Token. By redefining 'C'/3, it is possible to apply a DCG to other input sources than a list, e.g. to parse directly from an I/O stream:'C'([Token|Rest], Token, Rest).
This can then be applied to a string as follows:'C'(Stream-Pos0, Token, Stream-Pos1) :- seek(Stream, Pos0), read_string(Stream, " ", _, TokenString), atom_string(Token, TokenString), at(Stream, Pos1). sentence --> noun, [is], adjective. noun --> [prolog] ; [lisp]. adjective --> [boring] ; [great].
Unlike the default definition, this definition of 'C'/3 is not bi-directional. Consequently, the grammar rules using it can only be used for parsing, not for generating sentences.[eclipse 1]: String = "prolog is great", open(String, string, S), phrase(sentence, S-0, S-End). .. End = 15 yes.
Note that every grammar rule uses the definition of 'C'/3 which is visible in the module where the grammar rule itself is defined.