Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > 15d4ac4853ddceb54c8d74e8c6e99bb2 > files > 38

ocaml-camlp5-doc-5.12-1mdv2010.0.i586.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <!-- $Id: syntext.html 1823 2007-12-28 13:43:03Z deraugla $ -->
  <!-- Copyright (c) 2007-2008 INRIA -->
  <title>Extensions of syntax</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <link rel="stylesheet" type="text/css" href="styles/base.css"
        title="Normal" />
  <link rel="alternate" type="application/rss+xml" href="rss/camlp5.rss" 
        title="Camlp5"/>
</head>
<body>

<div id="menu">
  <h1>- <a href="http://pauillac.inria.fr/~ddr/camlp5">Camlp5</a> -</h1>
  <p class="subtitle">Version 5.11</p>
  <ul>
    <li><a href="index.html">Introduction</a></li>
    <li><a href="strict.html">Transitional and Strict</a></li>
    <li><a href="ptools.html">Parsing and printing tools</a></li>
  </ul>
  <ul>
    <li>Parsing tools
      <ul>
        <li><a href="parsers.html">Stream parsers</a></li>
        <li><a href="lexers.html">Stream lexers</a></li>
        <li><a href="fparsers.html">Functional parsers</a></li>
        <li><a href="bparsers.html">Backtracking parsers</a></li>
        <li><a href="grammars.html">Extensible grammars</a></li>
      </ul>
    </li>
    <li>Printing tools
      <ul>
        <li><a href="printers.html">Extensible printers</a></li>
        <li><a href="pprintf.html">Pprintf</a></li>
        <li><a href="pretty.html">Pretty print</a></li>
      </ul>
    </li>
    <li>Language extensions
      <ul>
        <li><a href="locations.html">Locations</a></li>
        <li><a href="ml_ast.html">Syntax tree</a></li>
        <li><a href="ast_transi.html">Syntax tree - transi</a></li>
        <li><a href="ast_strict.html">Syntax tree - strict</a></li>
        <li><a href="q_ast.html">Quotation kit q_ast.cmo</a></li>
        <li><a href="pcaml.html">The Pcaml module</a></li>
        <li><a href="syntext.html">Extensions of syntax</a></li>
        <li><a href="opretty.html">Extensions of printing</a></li>
        <li><a href="quot.html">Quotations</a></li>
        <li><a href="revsynt.html">Revised syntax</a></li>
        <li><a href="scheme.html">Scheme syntax</a></li>
        <li><a href="macros.html">Macros</a></li>
        <li><a href="pragma.html">Pragma directive</a></li>
        <li><a href="extfun.html">Extensible functions</a></li>
      </ul>
    </li>
    <li>Appendix
      <ul>
        <li><a href="commands.html">Commands and Files</a></li>
        <li><a href="library.html">Library</a></li>
        <li><a href="sources.html">Camlp5 sources</a></li>
        <li><a href="about.html">About Camlp5</a></li>
      </ul>
    </li>
  </ul>
</div>

<div id="content">

<h1 class="top">Extensions of syntax</h1>

<p>Camlp5 allows one to extend the syntax of the OCaml language, and
  even change the entire syntax.</p>

<p>It uses for that one of its parsing tools:
  the <a href="grammars.html">extensible grammars</a>.</p>

<p>To understand the whole syntax in the examples given in this
  chapter, it is good to understand this parsing tool (the extensible
  grammars), but we shall try to give some minimal explanations to
  allow the reader to follow them.</p>

<p>A syntax extension is an OCaml object file (ending with ".cmo" or
  ".cma") which is loaded inside Camlp5. The source of this file uses
  calls to the specific statement EXTEND applied to entries defined in
  the Camlp5 module "<tt>Pcaml</tt>".</p>

<div id="tableofcontents">
  <ol>
    <li><a href="#a:Entries">Entries</a></li>
    <li><a href="#a:Syntax-tree-quotations">Syntax tree quotations</a></li>
    <li><a href="#a:An-example-:-repeat--until">An example : repeat..until</a>
      <ul>
        <li><a href="#b:The-code">The code</a></li>
        <li><a href="#b:Compilation">Compilation</a></li>
        <li><a href="#b:Testing">Testing</a></li>
      </ul>
    </li>
  </ol>
</div>

<h2 id="a:Entries">Entries</h2>

<p>The grammar of OCaml contains several entries, corresponding to the
  major notions of the language, which are modifiable this way, and
  even erasable. They are defined in this module "<tt>Pcaml</tt>".</p>

<p>Most important entries:</p>

<ul>
  <li><tt>expr</tt>: the expressions.</li>
  <li><tt>patt</tt>: the patterns.</li>
  <li><tt>ctyp</tt>: the types.</li>
  <li><tt>str_item</tt>: the structure items, i.e. the items between
    "struct" and "end", and the toplevel phrases in a ".ml" file.</li>
  <li><tt>sig_item</tt>: the signature items, i.e. the items between
    "sig" and "end", and the toplevel phrases in a ".mli" file.</li>
  <li><tt>module_expr</tt>: the module expressions.</li>
  <li><tt>module_type</tt>: the module types.</li>
</ul>

<p>Entries of object programming:</p>

<ul>
  <li><tt>class_expr</tt>: the class expressions.</li>
  <li><tt>class_type</tt>: the class types.</li>
  <li><tt>class_str_item</tt>: the objects items.</li>
  <li><tt>class_sig_item</tt>: the objects types items.</li>
</ul>

<p>Main entries of files and interactive toplevel parsing:</p>

<ul>
  <li><tt>implem</tt>: the phrases that can be found in a ".ml" file.</li>
  <li><tt>interf</tt>: the phrases that can be found in a ".mli" file.</li>
  <li><tt>top_phrase</tt>: the phrases of the interactive toplevel.</li>
  <li><tt>use_file</tt>: the phrases that can be found in a file
    included by the directive "use".</li>
</ul>

<p>Extra useful entries also accessible:</p>

<ul>
  <li><tt>let_binding</tt>: the bindings "expression = pattern" found in
    the "let" statement.</li>
  <li><tt>type_declaration</tt>: the bindings "name = type" found in
    the "type" statement.</li>
</ul>

<h2 id="a:Syntax-tree-quotations">Syntax tree quotations</h2>

<p>A grammar rule is a list of rule symbols followed by the semantic
  action, i.e. the result of the rule. This result is a syntax tree,
  whose type is the type of the extended entry. The description of the
  types of the syntax tree are in the Camlp5 module
  "<tt>MLast</tt>".</p>

<p>There is however a simpler way to make values of these syntax tree
  types: the system quotations (see chapters
  about <a href="quot.html">quotations</a>
  and <a href="ml_ast.html">syntax tree</a>). With this system, it is
  possible to represent syntax tree in concrete syntax, between
  specific parentheses, namely "<tt>&lt;&lt;</tt>" and
  "<tt>&gt;&gt;</tt>", or between "<tt>&lt;:name&lt;</tt>" and
  "<tt>&gt;&gt;</tt>".</p>

<p>For example, the syntax node of the "if" statement is, normally:</p>

<pre>
  MLast.ExIfe loc e1 e2 e3
</pre>

<p>where loc is the source location, and e1, e2, e3 are the
  expressions constituting the if statement. With quotations, it is
  possible to write it like this (which is stricly equivalent because
  this is evaluated at parse time, not execution time):</p>

<pre>
  &lt;:expr&lt; if $e1$ then $e2$ else $e3$ >>
</pre>

<p>With quotations, it is possible to build pieces of program as
  complex as desired. See the chapter
  about <a href="ml_ast.html">syntax trees</a>.</p>

<h2 id="a:An-example-:-repeat--until">An example : repeat..until</h2>

<p>A classical extension is the creation of the "repeat" statement.
  The "repeat" statement is like a "while" except that the loop is
  executed at least one time and that the test is at the end of the
  loop and is inverted. The equivalent of:</p>

<pre>
  repeat x; y; z until c
</pre>

<p>is:</p>

<pre>
  do {
    x; y; z;
    while not c do { x; y; z }
  }
</pre>

<p>or, with a loop:</p>

<pre>
  loop () where rec loop () = do {
    x; y; z;
    if c then () else loop ()
  }
</pre>

<h3 id="b:The-code">The code</h3>

<p>This syntax extension could be written like this (see the detail of
  syntax in the chapter about <a href="grammars.html">extensible
  grammars</a> and the syntax tree quotations in the chapter
  about <a href="ml_ast.html">them</a>):</p>

<pre>
  #load "pa_extend.cmo";
  #load "q_MLast.cmo";
  open Pcaml;
  EXTEND
    expr:
      [ [ "repeat"; el = LIST1 expr SEP ";"; "until"; c = expr ->
            let el = el @ [&lt;:expr&lt; while not $c$ do { $list:el$ } >>] in
            &lt;:expr&lt; do { $list:el$ } >> ] ]
    ;
  END;
</pre>

<p>Alternatively, with the loop version:</p>

<pre>
  #load "pa_extend.cmo";
  #load "q_MLast.cmo";
  open Pcaml;
  EXTEND
    expr:
      [ [ "repeat"; el = LIST1 expr SEP ";"; "until"; c = expr ->
            let el = el @ [&lt;:expr&lt; if $c$ then () else loop () >>] in
            &lt;:expr&lt; loop () where rec loop () = do { $list:el$ } >> ] ]
    ;
  END;
</pre>

<p>The first "<tt>#load</tt>" in the code (in both files) means that a
  syntax extension has been used in the file, namely the "EXTEND"
  statement. The second "<tt>#load</tt>" means that abstract
  tree <a href="quot.html">quotations</a> has been used, namely the
  "<tt>&lt;:expr&lt; ... >></tt>".</p>

<p>The quotation, found in the second version:</p>

<pre>
  &lt;:expr&lt; loop () where rec loop () = do { $list:el$ } >>
</pre>

<p>is especially interesting. Written with abstract syntax tree, it would
  be:</p>

<pre>
  MLast.ExLet loc True
    [(MLast.PaLid loc "loop",
      MLast.ExFun loc [(MLast.PaUid loc "()", None, MLast.ExSeq loc el)])]
    (MLast.ExApp loc (MLast.ExLid loc "loop") (MLast.ExUid loc "()"));
</pre>

<p>This shows the interest of writing abstract syntax tree with quotations:
  it is easier to program and to understand.</p>

<h3 id="b:Compilation">Compilation</h3>

<p>If the file "foo.ml" contains one of these versions, it is possible to
  compile it like this:</p>

<pre>
  ocamlc -pp camlp5r -I +camlp5 -c foo.ml
</pre>

<p>Notice that the ocamlc option "-c" means that we are interested
  only in generating the object file "foo.cmo", not achieving the
  compilation by creating an executable. Anyway the link would not
  work because of usage of modules specific to Camlp5.</p>

<h3 id="b:Testing">Testing</h3>

<h4>In the OCaml toplevel</h4>

<pre>
  ocaml -I +camlp5 camlp5r.cma
          Objective Caml version ...

          Camlp5 Parsing version ...

  # #load "foo.cmo";
  # value x = ref 42;                                                     
  value x : ref int = {val=42}
  # repeat
      print_int x.val; print_endline ""; x.val := x.val + 3
    until x.val > 70;
  42
  45
  48
  51
  54
  57
  60
  63
  66
  69
  - : unit = ()
</pre>

<h4>In a file</h4>

<p>The code, above, used in the toplevel, can be written in a file,
  say "bar.ml":</p>

<pre>
  #load "./foo.cmo";
  value x = ref 42;                                                  
  repeat
    print_int x.val;
    print_endline "";
    x.val := x.val + 3
  until x.val > 70;
</pre>

<p>with a subtile difference: the loaded file must be "<tt>./foo.cmo</tt>"
  and not just "<tt>foo.cmo</tt>" because Camlp5 does not have, by default,
  the current directory in its path.</p>

<p>The file can be compiled like this:</p>

<pre>
  ocamlc -pp camlp5r bar.ml
</pre>

<p>or in native code:</p>

<pre>
  ocamlopt -pp camlp5r bar.ml
</pre>

<p>And it is possible to check the resulting program by typing:</p>

<pre>
  camlp5r pr_r.cmo bar.ml
</pre>

<p>whose displayed result is:</p>

<pre>
  #load "./foo.cmo";
  value x = ref 42;
  do {
    print_int x.val;
    print_endline "";
    x.val := x.val + 3;
    while not (x.val > 70) do {
      print_int x.val;
      print_endline "";
      x.val := x.val + 3
    }
  };
</pre>

<p>See also the <a href="opretty.html#a:Example-:-repeat..until">same
  example</a> pretty printed in its original syntax, using the
  extendable <a href="opretty.html">programs printing</a>.</p>

<a class="toplink" href="syntext.html">↑</a>
<div class="trailer">

  <hr style="margin:0" /><div style="font-size: 80%"><em>Copyright 2007
      Daniel de Rauglaudre (INRIA)</em></div>

  <p class="bottom">
    <a href="http://validator.w3.org/check?uri=referer"><img
       src="images/valid-xhtml11.png" style="border:0"
       alt="Valid XHTML 1.1" height="31" width="88" /></a>
  </p>

</div>

</div>

</body>
</html>