1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="gprolog.css">
<TITLE>
Term expansion
</TITLE>
</HEAD>
<BODY TEXT=black BGCOLOR=white>
<A HREF="gprolog039.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="gprolog023.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="gprolog041.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>
<H3 CLASS="subsection"><A NAME="htoc178">7.17</A> Term expansion</H3><UL>
<LI><A HREF="gprolog040.html#toc140">Definite clause grammars</A>
<LI><A HREF="gprolog040.html#toc141"><TT>expand_term/2</TT>,
<TT>term_expansion/2</TT></A>
<LI><A HREF="gprolog040.html#toc142"><TT>phrase/3</TT>,
<TT>phrase/2</TT></A>
</UL>
<A NAME="Term-expansion"></A>
<A NAME="toc140"></A>
<H4 CLASS="subsubsection"><A NAME="htoc179">7.17.1</A> Definite clause grammars</H4>
<A NAME="DCG"></A>
Definite clause grammars are a useful notation to express grammar rules.
However the ISO reference does not include them, so they should be considered
as a system dependent feature. Definite clause grammars are an extension of
context-free grammars. A grammar rule is of the form:
<DL CLASS="list" COMPACT="compact"><DT CLASS="dt-list"><DD CLASS="dd-list">head<TT> –> </TT>body<TT>.</TT></DL>
<TT>–></TT> is a predefined infix operator (section <A HREF="gprolog037.html#op/3:(Term-input/output)">7.14.10</A>).<BR>
<BR>
Here are some features of definite clause grammars:
<UL CLASS="itemize"><LI CLASS="li-itemize">a non-terminal symbol may be any callable term.<BR>
<BR>
<LI CLASS="li-itemize">a terminal symbol may be any Prolog term and is written as a list. The
empty list represents an empty sequence of terminals.<BR>
<BR>
<LI CLASS="li-itemize">a sequence is expressed using the Prolog conjunction operator
<TT>(</TT>(',')/2).<BR>
<BR>
<LI CLASS="li-itemize">the head of a grammar rule consists of a non-terminal optionally
followed by a sequence of terminals (i.e. a Prolog list).<BR>
<BR>
<LI CLASS="li-itemize">the body of a grammar rule consists of a sequence of non-terminals,
terminals, predicate call, disjunction (using <TT>;/2</TT>), if-then (using
<TT>(->)/2</TT>) or cut (using <TT>!</TT>).<BR>
<BR>
<LI CLASS="li-itemize">a predicate call must be enclosed in curly brackets (using
<TT>{}/1</TT>). This makes it possible to express an extra
condition.</UL>
A grammar rule is nothing but a “syntactic sugar” for a Prolog clause. Each
grammar rule accepts as input a list of terminals (tokens), parses a prefix
of this list and gives as output the rest of this list (possibly enlarged).
This rest is generally parsed later. So, each a grammar rule is translated
into a Prolog clause that explicitly the manages the list. Two arguments
are then added: the input list (<TT>Start</TT>) and the output list
(<TT>Stop</TT>). For instance:
<DL CLASS="list" COMPACT="compact"><DT CLASS="dt-list"><DD CLASS="dd-list"><TT>p –> q.</TT></DL>
is translated into:
<DL CLASS="list" COMPACT="compact"><DT CLASS="dt-list"><DD CLASS="dd-list"><TT>p(Start, End) :- q(Start, End).</TT></DL>
Extra arguments can be provided and the body of the rule can contain several
non-terminals. Example:
<DL CLASS="list" COMPACT="compact"><DT CLASS="dt-list"><DD CLASS="dd-list">
<PRE CLASS="verbatim">
p(X, Y) -->
q(X),
r(X, Y),
s(Y).
</PRE></DL>
is translated into:
<DL CLASS="list" COMPACT="compact"><DT CLASS="dt-list"><DD CLASS="dd-list">
<PRE CLASS="verbatim">
p(X, Y, Start, End) :-
q(X, Start, A),
r(X, Y, A, B),
s(Y, B, End).
</PRE></DL>
Terminals are translated using unification:
<DL CLASS="list" COMPACT="compact"><DT CLASS="dt-list"><DD CLASS="dd-list"><TT>assign(X,Y) –> left(X), [:=], right(Y), [;].</TT></DL>
is translated into:
<DL CLASS="list" COMPACT="compact"><DT CLASS="dt-list"><DD CLASS="dd-list">
<PRE CLASS="verbatim">
assign(X,Y,Start,End) :-
left(X, Start, A),
A=[:=|B],
right(Y, B, C),
C=[;|End].
</PRE></DL>
Terminals appearing on the left-hand side of a rule are connected to the
output argument of the head.<BR>
<BR>
It is possible to include a call to a prolog predicate enclosing it in curly
brackets (to distinguish them from non-terminals):
<DL CLASS="list" COMPACT="compact"><DT CLASS="dt-list"><DD CLASS="dd-list"><TT>assign(X,Y) –> left(X), [:=], right(Y0), {Y is Y0 },
[;].</TT></DL>
is translated into:
<DL CLASS="list" COMPACT="compact"><DT CLASS="dt-list"><DD CLASS="dd-list">
<PRE CLASS="verbatim">
assign(X,Y,Start,End) :-
left(X, Start, A),
A=[:=|B],
right(Y0, B, C),
Y is Y0,
C=[;|End].
</PRE></DL>
Cut, disjunction and if-then(-else) are translated literally (and do not need
to be enclosed in curly brackets).<BR>
<BR>
<A NAME="toc141"></A>
<H4 CLASS="subsubsection"><A NAME="htoc180">7.17.2</A> <TT>expand_term/2</TT>,
<TT>term_expansion/2</TT></H4>
<B>Templates</B>
<DL CLASS="list" COMPACT="compact"><DT CLASS="dt-list"><DD CLASS="dd-list"><TT>
expand_term(?term, ?term)<BR>
term_expansion(?term, ?term)</TT></DL>
<B>Description</B><BR>
<BR>
<TT>expand_term(Term1, Term2)</TT> succeeds if
<TT>Term2</TT> is a transformation of <TT>Term1</TT>. The transformation
steps are as follows:
<UL CLASS="itemize"><LI CLASS="li-itemize">if <TT>Term1</TT> is a variable, it is unified with <TT>Term2</TT><BR>
<BR>
<LI CLASS="li-itemize">if <TT>term_expansion(Term1, Term2)</TT> succeeds <TT>Term2</TT> is
assumed to be the transformation of <TT>Term1</TT>.<BR>
<BR>
<LI CLASS="li-itemize">if <TT>Term1</TT> is a DCG then <TT>Term2</TT> is its translation
(section <A HREF="#DCG">7.17.1</A>).<BR>
<BR>
<LI CLASS="li-itemize">otherwise <TT>Term2</TT> is unified with <TT>Term1</TT>.</UL>
<TT>term_expansion(Term1, Term2)</TT> is a hook predicate allowing the user
to define a specific transformation. <BR>
<BR>
The GNU Prolog compiler (section <A HREF="gprolog008.html#The-GNU-Prolog-compiler">3.4</A>) automatically calls
<TT>expand_term/2</TT> on each <TT>Term1</TT> read in. However, in the
current release, only DCG transformation are done by the compiler (i.e.
<TT>term_expansion/2</TT> cannot be used). To use
<TT>term_expansion/2</TT>, it is necessary to call <TT>expand_term/2</TT>
explicitly.<BR>
<BR>
<B>Errors</B><BR>
<BR>
None.<BR>
<BR>
<B>Portability</B><BR>
<BR>
GNU Prolog predicate.<BR>
<BR>
<A NAME="toc142"></A>
<H4 CLASS="subsubsection"><A NAME="htoc181">7.17.3</A> <TT>phrase/3</TT>,
<TT>phrase/2</TT></H4>
<B>Templates</B>
<DL CLASS="list" COMPACT="compact"><DT CLASS="dt-list"><DD CLASS="dd-list"><TT>
phrase(?term, ?list, ?list)<BR>
phrase(?term, ?list)</TT></DL>
<B>Description</B><BR>
<BR>
<TT>phrase(Phrase, List, Remainder)</TT> succeeds if the list
<TT>List</TT> is in the language defined by the grammar rule body
<TT>Phrase</TT>. <TT>Remainder</TT> is what remains of the list after a
phrase has been found. <BR>
<BR>
<TT>phrase(Phrase, List)</TT> is equivalent to
<TT>phrase(Phrase, List, [])</TT>.<BR>
<BR>
<B>Errors</B><BR>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD>
</TR>
<TR><TD VALIGN=top ALIGN=left><TT>List</TT> is neither a list nor a partial list</TD>
<TD VALIGN=top ALIGN=center NOWRAP> </TD>
<TD VALIGN=top ALIGN=left><TT>type_error(list, List)</TT></TD>
</TR>
<TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD>
</TR>
<TR><TD VALIGN=top ALIGN=left><TT>Remainder</TT> is neither a list nor a partial list</TD>
<TD VALIGN=top ALIGN=center NOWRAP> </TD>
<TD VALIGN=top ALIGN=left><TT>type_error(list, Remainder)</TT></TD>
</TR>
<TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD>
</TR></TABLE><BR>
<B>Portability</B><BR>
<BR>
GNU Prolog predicates.<BR>
<BR>
<HR SIZE=2>
Copyright (C) 1999-2007 Daniel Diaz
<BR>
<BR>
Verbatim copying and distribution of this entire article is permitted in any
medium, provided this notice is preserved. <BR>
<BR>
<A HREF="index.html#copyright">More about the copyright</A>
<HR>
<A HREF="gprolog039.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="gprolog023.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="gprolog041.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
|