Grammar rules form a comfortable interface to difference-lists. They are designed both to support writing parsers that build a parse-tree from a list as for generating a flat list from a term. Unfortunately, Definite Clause Grammar (DCG) handling is not part of the Prolog standard. Most Prolog engines implement DCG, but the details differ slightly.
Grammar rules look like ordinary clauses using -->/2 for separating the head and body rather then :-/2 . Expanding grammar rules is done by expand_term/2, which adds two additional argument to each term for representing the difference list. We will illustrate the behaviour by defining a rule-set for parsing an integer.
integer(I) --> digit(D0), digits(D), { number_chars(I, [D0|D]) }. digits([D|T]) --> digit(D), !, digits(T). digits([]) --> []. digit(D) --> [D], { code_type(D, digit) }.
The body of a grammar rule can contain three types of terms. A
compound term interpreted as a reference to a grammar-rule. Code between
{
...}
is interpreted as a reference to
ordinary Prolog code and finally, a list is interpreted as a sequence of
literals. The Prolog control-constructs ( \+/1 , ->/2 , ;// 2, ,/2
and !/0 ) can be used in grammar rules.
Grammar rule-sets are called using the built-in predicates phrase/2 and phrase/3:
phrase(RuleSet, InputList, [])
.
?- phrase(integer(X), "42 times", Rest). X = 42 Rest = [32, 116, 105, 109, 101, 115]