Quotations
Previous
Up
Next
This chapter presents the Camlp4 quotation system. A quotation is a
part of a program enclosed by special parentheses in position of
expression or pattern (exclusively), and whose treatment is done by an
user function, called a ``quotation expander''. Several quotations are
usable in the same source code.
When
Camlp4 encounters such a construction, the appropriate
quotation expander is called with the string contents of the
quotation.
There are two kinds of quotation expanders:
-
Those returning strings. The result of the expander is parsed by
Camlp4 afterwards. They are easy to use, but they depend on the
language syntax: the returned string must be of
OCaml syntax if the
language syntax used is the normal syntax, in revised syntax if the language
syntax is the revised syntax, etc.
- Those returning syntax trees. They are independent from
the language syntax used, but to use them, one muse know how to create
syntax tree nodes. See appendix A.
There are two kinds of quotations:
-
The anonymous quotations start with ``
<<'' and end with
``>>''. The associated expander is the ``default'' expander.
- The named quotations start with ``
<:id<'' and end with
``>>'', where ``id'' is any identifier. The associated
expander is the expander named ``id''.
The string inside a quotation is any string. It can hold other
quotations. The string sequences ``
<<'', ``
<:id<'' and
``
>>'', if not matching, must be prefixed by a backslash and
backslashes must be doubled.
3.2
Creating a quotation expander
A quotation expander is a function written in OCaml. A call
to the Camlp4 library function ``
Quotation.add'' (see
section
??) adds the quotation expander. The variable
``
Quotation.default'' holds the name of the default
quotation.
The file holding the quotation expander must be compiled using the
OCaml compiler, with the
Camlp4 library directory in its
directory path (option ``
-I''). An object file (ending with
``
.cmo'') is created, which is loadable in Camlp4, as parameter
of the command ``camlp4'', or in the OCaml toplevel using the
directive ``
#load''.
Antiquotation is a programming technique to specify expressions or
patterns in a quotation, parsed in the context of the enclosing
expression or pattern where the quotation is.
The way an antiquotation is specified depends on the quotation
expander: typically a specific character and an identifier, or
specific parentheses and a complete expression or pattern.
If some kind of error happens while compiling a quotation, an error
message is displayed, which shows the source position of the error. By
default, the error message highlights the whole quotation, but a
quotation expander can specify more precise ``locations'' while
parsing and generating its returning string.
A ``location'' is a couple of integers: the first one is the position
of the first character of the concerned text, the second one the
position of the first character after the concerned text.
3.4.1
Exception raised in an expander
If an exception is raised in the expander, the quotation is
highlighted, the exception name is displayed, and the parsing
fails.
To be more precise, the expander can call the function
``
Stdpp.raise_with_loc'' instead instead of ``
raise'',
this first function having a supplementary parameter which is the
location of the error relative to the begin of the quotation. In this
case, the error message highlights only the located part of the
quotation.
3.4.2
Error while parsing the expander result (string
expanders)
A problem can arise in
string expanders (those returning
strings). The resulting string may hold syntax errors. In this case,
because there is no ``input location'' for the error, it is not
directly possible to see this error.
To solve this problem, a special option of Camlp4 can be used:
``
-QD'' (see the manual page). It is also possible to set the
variable ``
Pcaml.quotation_dump_file'' (see section
??). The offending string is then written in a file (whose
name is specified by this option or this variable) and the error
message gives the location of the error in this file. This technique
is useful when perfecting or debugging the quotation expander: a good
quotation expander should never generate errored strings.
This problem cannot arise in
syntax trees expanders, because there
is no parsing following the expansion.
It is possible to specify precise source locations to some parts
(antiquotations) of the expander resulting string. For this, there are
to ways depending on the expander kind:
-
In a string expander, enclose
the resulting string with a location directive, which will be
interpreted by the language lexer. Its syntax recognized by the
default language lexer (
Plexer), is:
location_directive ::= $ int : string $
The int value is the source location of the first character of
the antiquotation, relative to the beginning of the quotation
string. The string is the antiquotation itself.
- In a syntax tree expander, the locations of the
antiquotations must be relative to the beginning of the antiquotation,
and the tree generated must be enclosed with a location node
(see appendix sections A.2 and A.3).
Remark: the subtrees not enclosed with this location node are relocated
with the entire quotation after expansion.
3.5
Predefined quotation expanders
A quotation expander is provided in the file ``
q_MLast.cmo''
allowing to create abstract syntax tree nodes from concrete revised
syntax. It is used in language syntax extensions
(chapter
5).
Another quotation expander provided is ``
q_phony.cmo''. It
transforms all quotations into variables whose name holds all the text
of the quotation,
<< and
>> included. It is useful for
pretty printing programs with the quotations not expanded.
Previous
Up
Next