Previous Contents Next
Chapter 2 Grammars in Camlp4
A grammar in Camlp4 is a value of type Grammar.g. It is created by the function Grammar.make which takes a lexer as parameter (see also the functorial interface, another way to create a grammar). Let's ignore for the moment how to create lexers and let's just take a lexer provided in Camlp4, which is the default OCaml lexer. It is in the module Plexer and you can create an instantiation by using Plexer.make ().

2.1 Grammar, entries: an example

You can create your grammar like this:

     # let gram = Grammar.create (Plexer.make ());;
A grammar is composed of entries. Entries are values of type 'a Grammar.Entry.e. The 'a type parameter represents the type of values which the entry returns. To create an entry, use Grammar.Entry.create, which has two parameters: 1/ the associated grammar 2/ a string, the entry name, used for error messages.

An entry is a mutable value. When you create it, it is empty, its type is '_a Grammar.Entry.e (not generalized, you cannot create entries returning polymorphic values), the type parameter being set when the entry is extended, showing then the type of its results. Let's take an entry expr:

     # let expr = Grammar.Entry.create gram "expr";;
Entries apply to char streams via the function Grammar.Entry.parse. If you apply an empty entry (an entry just created, for example), the exception Stream.Failure is raised.

To define rules to an entry, you must use the statement EXTEND. Note that EXTEND is not a syntactic construction in OCaml: it is a syntax extension provided by Camlp4. The syntax of EXTEND is:

     extend-statement ::=
        EXTEND
           list-of-entries-extensions
        END
Notice that EXTEND is an expression (i.e. not a declaration): it can be evaluated at toplevel, but also inside a function: in this case, the syntax extension takes place when the function is called.

An entry extension has the syntax:

     entry-extension ::=
        identifier : [ list-of-levels-separated-by-bars ] ;
The identifier is an entry name. An entry can have one or several levels, representing precedences and associativity.

A level has the syntax:

     level ::=
        [ list-of-rules-separated-by-bars ]

     rule ::=
        list-of-symbols-separated-by-semicolons -> action
A rule is like a pattern matching case: it can introduce patterns variables which can be used in the action part. When the rule is accepted, the action is executed. The type of the action is 'a for an 'a entry ('a Grammar.Entry.e, more precisely).

Let's define our ex