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
for separating the head and body rather than -->
/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.
:-
/2
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, ;
/;
and ,
/2
) can be used in grammar rules.
!
/0
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]