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:

extfunexpressionwith

[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.

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.