Other extensions
Previous
Up
Next
Camlp4 provides a system of functions defined by pattern matching,
which are extensible.
The library module is
Extfun and the syntax to be loaded is
"pa_extfun.cmo". The empty function is
Extfun.empty.
You can extend a function using the statement
extfun whose
syntax is:
extfun expression with
[ pattern-1 -> expression-1
| pattern-2 -> expression-2
...
| pattern-n -> expression-n ]
The patterns are ordered in lexicographic order (for example, in a
tuple, first comparing the first elements of the tuple). Variables are
inserted after constructors. In an extension, the patterns do not need
to be in a ``good'' order, since they are sorted. Non exhaustive
pattern matching do not generate a warning.
``Or'' patterns can be used only at the first level. In this case:
pat1 | pat2 -> expr
The binding is split into two cases (the expr is duplicated):
pat1 -> expr
| pat2 -> expr
Internal ``or'' patterns inside patterns are not accepted.
The statement
extfun returns another extensible function. The
type of extensible functions is
('a, 'b) Extfun.t. To use an
extensible function, one must use the function
Extfun.apply
which transforms it in a function of type
'a -> 'b. If matching
failed, such a function raises the exception
Extfun.Failure.
The contents (patterns) of an extensible function can be displayed
using
Extfun.print.
Remark: extensible functions are not efficient: when applied, all
patterns are tested, one by one, until one of them matches.
Extensible functions are used in Camlp4 extensible pretty printing.
The functional streams are another implementation of streams. Like
normal streams, their contents can be accessible only one element at a
time. But the elements are not removed. A functional stream parser
returns the couple of a result and the remaining stream.
The library module is
Fstream and the syntax to be loaded is
"pa_fstream.cmo". The syntax of a functional stream is:
functional-stream ::=
fstream
[: list-of-components-separated-by-semicolon :]
component ::=
` stream-element
| stream
and a functional parser, applying to a functional stream is:
functional-parser ::=
fparser
[ stream-pattern-1 -> expression-1
| stream-pattern-2 -> expression-2
..
| stream-pattern-n ->
expression-n ]
stream-pattern ::=
[: list-of-components-separated-by-semicolon :]
component ::=
` stream-pattern-element
| pattern = expression
| stream-pattern
The functional stream patterns elements syntax are actually the same
than in normal stream pattern.
A functional stream is of type
'a Fstream.t and a functional
stream parser of type
'a Fstream.t -> ('a * 'a Fstream.t) option. When a parser
fails, it returns
None, otherwise
Some of the result and
the remaining stream. The elements in the initial stream are not
removed.
A functional parser use limited backtrack. It is a backtrack in a
sense that when a rule fails, the next rule is tested with the initial
stream. If no rule applies, the functional parser returns
None. There is no Error exception causing the parsing to be
abandoned.
The backtrack is limited in a sense that if a rule is
[: p1 = e1; p2 = e2 :], if
e2 fails, the rule is
abandoned: there is no attempt to try the next possible rule inside
e1 (which would suppose continuations).
The functions available in the module
Fstream are like the ones
in
Stream. But there is no function ``Fstream.peek'', only
Fstream.next.
Functional parsers have a drawback that in case of syntax error, one
cannot know where, since the parsing continues until all rules have
been tested. To turn around this problem, the function
Fstream.count_frozen returns the number of unfrozen tokens in
the stream, allowing to find the location of the error, providing a
location array have been used (which is normal usage in stream parsing
and grammars). It works if the stream had not been unfrozen before.
Previous
Up
Next