An entry can be extended using the function
``Grammar.extend''. But its interface being quite complicated
and, as it must be used with appropriate type constraints, the Camlp4
library provides a file, named ``pa_extend.cmo'', compatible
with ``pa_o.cmo'' and ``pa_r.cmo'' which creates a new
instruction doing this work.
This instruction is ``EXTEND'' which has the following
format:
EXTEND |
{ GLOBAL : global-list ; } |
| entry : { position } extension ; |
| ... |
| entry : { position } extension ; |
END |
EXTEND, GLOBAL and END are keywords.
There are some other keywords in this instruction, all in uppercase.
The entry is a name of an entry variable (simple identifier or prefixed by a module name). It is extended according to the rules given by extension. The optional position tells how to insert the extension among the entry precedence levels: by default, the extension is done at the first precedence level (creating this level if the entry is empty).
The optional global-list restricts the list of the global
entries (separated by spaces) extended in the ``EXTEND''
instruction. The other entries are created locally. By default, all
entries are global and must correspond to entry variables visible at
the ``EXTEND'' instruction point.
A position can be:
FIRST: The extension is inserted at the beginning
of the precedence levels.
LAST: The extension is inserted as the end of the
precedence levels.
BEFORE label: The extension is inserted
before the precedence level so labelled.
AFTER label: The extension is inserted
after the precedence level so labelled.
LEVEL label: The extension is inserted
at the precedence level so labelled.
Only the case LEVEL extends already existing levels: the other
cases create new levels.
The syntax of an entry extension is:
[ |
{ label } { associativity } level-rules | |
| |
... | |
| |
{ label } { associativity } level-rules | ] |
The optional label identifies the current level for possible
future extensions. The optional associativity can be
LEFTA, RIGHTA or NONA for respectively left,
right and no associativity: the default is left associativity.
The level-rules have the format:
[ |
{ pattern = } symbol ; ... { pattern
= } symbol { -> action } |
|
| |
... | |
| |
{ pattern = } symbol ; ... { pattern
= } symbol { -> action } |
] |
The pattern is a language simple pattern, limited to identifiers, wildcard (character ``underscore'') and tuples of patterns. If not present, it is equivalent to the wildcard.
The action is a language expression where the patterns are bound
to the result of their corresponding symbol; in addition, the
variable ``loc'' is bound to the source location of the rule.
The action part is optional; by default it is the value ``()''.
A symbol is either:
string.
LIDENT or UIDENT optionally followed by a string:
its type is string.
INT optionally followed by a string: its type is string.
FLOAT of type string.
STRING of type string.
CHAR of type char.
QUOTATION of type (string * string).
ANTIQUOT followed by a string: its type is string.
LOCATE of type (int * string).
EOI of type unit.
Token.pattern'' (section 6.7). Their meaning is
suggested by their name, but in fact, depends on what is generated by
the lexer used. The provided lexer ``Plexer.make'' interprets
them canonically according to the rules of Objective Caml and
Righteous syntax (section 6.4).
LIST0 and LIST1 whose syntax is:
LISTx symbol1 { SEP symbol2 }
LIST0 and with at least
one element for LIST1) of symbol1, whose
elements are optionally separated by symbol2.
The type is t1 list where t1 is the type of
symbol1 (the result of the optional symbol2 is lost).
OPT followed by a symbol, meaning this symbol or
nothing. The type is t option where t is the type of
symbol.