Previous Up Next
Chapter 6 The Revised syntax
The revised syntax is an alternative syntax for OCaml. Its purpose is to b/DTD HTMA>
4.3 Parsed language

Entries are stream parsers improved. Streams use recursive descendant parsing (something close to LL(1)). Each precedence level can be seen as an independent extensible stream parser.

In a precedence level, the rules are factorized, i.e. several rules can start with the same symbols, and the parser is represented by a tree of symbols where leaves are either semantic actions, or dead ends.

When an extension is done, the new rules are inserted in the precedence level tree. The system does not check whether the entry precedence level will ``work'', nor whether it would work together with the other levels and the other entries.

This insertion is generally done at the end of the rules list. The special cases are for symbols of type token, which are always inserted before the other symbols (non terminals, lists, options, etc), tokens with parameters before tokens without parameters (parameter is the empty string).

There is no factorization of rules between different levels nor, a fortiori, with other entries.

While parsing an entry, the system tries the first precedence level. Then, if it fails, it tries the second one, etc. If the last one fails, the entry fails and the caller of this entry resumes, either by raising a parse error (the parsing is then stopped), or by trying other rules.

4.4 Deletion

Entries rules can be deleted using the function ``Grammar.delete_rule''. But, like for ``Grammar.extend'', it is not documented. One must use the instruction ``DELETE_RULE'', generating a call to this function. This instruction is a syntax extension, loaded together with the instruction ``EXTEND'' by the file ``pa_extend.cmo''.

The syntax of ``DELETE_RULE'' is:
DELETE_RULE
entry : symbol ; ... symbol
END

The rule defined by the list of symbols (semantic actions forgotten), if found, is deleted.

4.5 Writing a lexer

The lexers have to create tokens of any type you want. In the lexer interface (see below), you have to provide the way a token pattern (which is of type (string * string)) has to be compared with a token value of your token type.

A simple token type is (string * string) like the token pattern type. Its advantage is that a default function is provided in the module Token for the way the token patterns are parsed.

The token patterns are defined in the EXTEND statement, as terminal symbols in the rules. In a rule, an identifier in uppercase character not among the reserved ones (LIST0, OPT, and so on) is a token pattern. The identifier is the first string in the token pattern type. If the symbol is followed by a string, it is the second string of the token pattern type; if not, the string is empty. Moreover a string alone is also a token pattern with the first string being empty.

Examples: the following symbol rules in an EXTEND statement:
     IDENT "bar"
     INT "32"
     x = IDENT
     i = INT
     "let"
correspond (resp.) to the following token patterns:
     ("IDENT", "bar")
     ("INT", "32")
     ("IDENT", "")
     ("INT", "")
     ("", "let")
A lexer appropriate for the Grammar.gcreate function is a record of type Token.glexer which is a record with the following fields:
For remarks about Camlp4, write to: email

Previous Up Next ./usr/share/doc/ocaml-doc/camlp4.html/manual006.html0000644000000000000000000001547010106422314022203 0ustar rootroot00000000000000 Syntax extensions Previous Up Next
Chapter 5 Syntax extensions
This chapter introduces the way to extend the syntax of OCaml, and how to redefine the whole syntax of the language.

5.1 The abstract syntax tree

A syntax extension or redefinition holds grammar rules which must return abstract syntax tree nodes. The provided file ``q_MLast.cmo'' holds quotations expanders allowing to create such nodes using a concrete syntax: the description of the abstract syntax tree is not necessary. The complete description of these quotations is given in appendix A.

5.2 Extending the language

The language predefined syntaxes, ``pa_o.cmo'' and ``pa_r.cmo'' use the Camlp4 grammar system: so they are extensible.

The module ``Pcaml'' holds grammars and entries variables used by the language predefined syntaxes files. Syntax extensions can be done by extensions of the appropriate entries.

In some entries, ``pa_o.cmo'' and ``pa_r.cmo'' define labels allowing to locate some levels and to add new rules relative to these levels. The entries and their labels are:
5.3 Examples of language extensions

All examples must be compiled using ``camlp4''. As they use the ``EXTEND'' instruction, Camlp4 must load ``pa_extend.cmo''. As they use the quotations to create abstract syntax tree nodes, Camlp4 must load ``q_MLast.cmo''. The compilation command is therefore:
    ocamlc -pp "camlp4o pa_extend.cmo q_MLast.cmo" -I camlp4-lib-dir -c file.ml
After this, the syntax extension takes place in Camlp4 when ``file.cmo'' is loaded.

5.3.1 Infix

This is an example to add the infix operator ``o'', composition of two functions. For the meaning of the quotation expr used here, see appendix A.
       open Pcaml;;
       EXTEND
         expr: AFTER "apply"
           [[ f = expr; "o"; g = expr -> <:expr< fun x -> $f$ ($g$ x) >> ]];
       END;;
5.3.2 Repeat until à la Pascal

The ``repeat...until'' loop of Pascal is closed to the ``while'' loop except that it is executed at least once. We can implement it like this:
       open Pcaml;;
       EXTEND
         expr: LEVEL "let"
           [[ "repeat"; e1 = expr; "until"; e2 = expr ->
                 <:expr< do { $e1$; while not $e2$ do { $e1$ } >> ]];
       END;;
5.4 Redefining the whole syntax

To redefine the whole syntax, one must start with an empty grammar and empty entries and extend them. The library module ``Grammar.Unsafe'' hold functions to clean up the grammars and the entries.

Examples can be found in the distribution: the files ``meta/pa_r.ml'' and ``etc/pa_o.ml'' which are the sources of ``pa_r.cmo'' and ``pa_o.cmo''.


For remarks about Camlp4, write to: email

Previous Up Next ./usr/share/doc/ocaml-doc/camlp4.html/manual007.html0000644000000000000000000004600410106422314022201 0ustar rootroot00000000000000 The Revised syntax Previous Up Next
Chapter 6 The Revised syntax
The revised syntax is an alternative syntax for OCaml. Its purpose is to b/DTD HTMA>
4.3 Parsed language

Entries are stream parsers improved. Streams use recursive descendant parsing (something close to LL(1)). Each precedence level can be seen as an independent extensible stream parser.

In a precedence level, the rules are factorized, i.e. several rules can start with the same symbols, and the parser is represented by a tree of symbols where leaves are either semantic actions, or dead ends.

When an extension is done, the new rules are inserted in the precedence level tree. The system does not check whether the entry precedence level will ``work'', nor whether it would work together with the other levels and the other entries.

This insertion is generally done at the end of the rules list. The special cases are for symbols of type token, which are always inserted before the other symbols (non terminals, lists, options, etc), tokens with parameters before tokens without parameters (parameter is the empty string).

There is no factorization of rules between different levels nor, a fortiori, with other entries.

While parsing an entry, the system tries the first precedence level. Then, if it fails, it tries the second one, etc. If the last one fails, the entry fails and the caller of this entry resumes, either by raising a parse error (the parsing is then stopped), or by trying other rules.

4.4 Deletion

Entries rules can be deleted using the function ``Grammar.delete_rule''. But, like for ``Grammar.extend'', it is not documented. One must use t