#### 11.3.155 `phrase/[2,3]`

#### Synopsis

`phrase(``+PhraseType`, `+List`)

`phrase(``+PhraseType`, `+List`, `-Rest`)

Used in conjunction with a grammar to parse or generate strings.

#### Arguments

`:PhraseType`
*callable*, must be nonvar

Name of a phrase type.

`List`
*list of term*

A list of symbols — tokens or *codes*.

`Rest`
*list of term*

A suffix of `List`; what remains of
`List` after `PhraseType` has been found.
Defaults to `[]`

.

#### Description

This predicate is a convenient way to start execution of grammar
rules. Runs through the grammar rules checking whether there is a
path by which `PhraseType` can be rewritten as `List`.

If `List` is bound, then this goal corresponds
to using the grammar for parsing. If `List` is unbound, then this
goal corresponds to using the grammar for generation.

`phrase/[2,3]`

succeeds when the portion of `List` between the start of
`List` and the start of `Rest` is a phrase of type
`PhraseType` (according to the current grammar rules), where
`PhraseType` is either a non-terminal or, more generally, a grammar
rule body.

`phrase/[2,3]`

allows variables to occur as non-terminals in grammar
rule bodies, just as `call/1`

allows variables to occur as goals
in clause bodies.

#### Backtracking

Depends on `PhraseType`.

#### Exceptions

Call errors (see ref-sem-exc).

#### Examples

Here is a simple grammar that parses an arithmetic expression (made up
of digits and operators) and computes its value. Create a file
containing the following rules:

*grammar.pl*

expr(Z) --> term(X), "+", expr(Y), {Z is X + Y}.
expr(Z) --> term(X), "-", expr(Y), {Z is X - Y}.
expr(X) --> term(X).
term(Z) --> number(X), "*", term(Y), {Z is X * Y}.
term(Z) --> number(X), "/", term(Y), {Z is X / Y}.
term(Z) --> number(Z).
number(C) --> "+", number(C).
number(C) --> "-", number(X), {C is -X}.
number(X) --> [C], {"0"=<C, C=<"9", X is C - "0"}.

In the last rule, C is the character code of a decimal digit.

This grammar can now be used to parse and evaluate an expression:

| ?- `[grammar]`.
| ?- `phrase(expr(Z), "-2+3*5+1").`
Z = 14
| ?- `phrase(expr(Z), "-2+3*5", Rest).`
Z = 13,
Rest = [] `;`
Z = 1,
Rest = "*5" `;`
Z = -2,
Rest = "+3*5" `;`
no

#### See Also

ref-lod-exp, ref-gru.

Send feedback on this subject.