This file is indexed.

/usr/share/doc/camlp5/html/printers.html is in camlp5 6.16-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
<!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>
  <!-- printers.html,v -->
  <!-- Copyright (c) INRIA 2007-2014 -->
  <title>extensible printers</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 6.16</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="directives.html">Directives</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="redef.html">Redefining OCaml syntax</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">Extensible printers</h1>

<p>This chapter describes the syntax and semantics of the extensible
  printers of Camlp5.</p>

<p>Similar to the <a href="grammars.html">extensible grammars</a>, the
  extensible printers allow to define and extend printers of data or
  programs. A specific statement "<tt>EXTEND_PRINTER</tt>" allow to
  define these extensions.</p>

<div id="tableofcontents">
  <ol>
    <li><a href="#a:Getting-started">Getting started</a></li>
    <li><a href="#a:Syntax-of-the-EXTEND_PRINTER-statement">Syntax of the EXTEND_PRINTER statement</a></li>
    <li><a href="#a:Semantics-of-EXTEND_PRINTER">Semantics of EXTEND_PRINTER</a>
      <ul>
        <li><a href="#b:Printers-definition-list">Printers definition list</a></li>
        <li><a href="#b:Rules-insertion">Rules insertion</a></li>
        <li><a href="#b:Semantic-action">Semantic action</a></li>
      </ul>
    </li>
    <li><a href="#a:The-Eprinter-module">The Eprinter module</a></li>
    <li><a href="#a:Examples">Examples</a>
      <ul>
        <li><a href="#b:Parser-and-Printer-of-expressions">Parser and Printer of expressions</a></li>
        <li><a href="#b:Printing-OCaml-programs">Printing OCaml programs</a></li>
      </ul>
    </li>
  </ol>
</div>

<h2 id="a:Getting-started">Getting started</h2>

<p>A printer is a value of type "<tt>Eprinter.t a</tt>" where
  "<tt>a</tt>" is the type of the item to be printed. When applied, a
  printer returns a string, representing the printed item.</p>

<p>To create a printer, one must use the function
  "<tt>Eprinter.make</tt>" with, as parameter, the name of the
  printer, (used in error messages). A printer is created empty,
  i.e. it fails if it is applied.</p>

<p>As with grammar entries, printers may have several levels. When the
  function "<tt>Eprinter.apply</tt>" is applied to a printer, the
  first level is called.  The function "<tt>Eprinter.apply_level</tt>"
  allows to call a printer at some specific level possibly different
  from the first one. When a level does not match any value of the
  printed item, the next level is tested. If there is no more levels,
  the printer fails.</p>

<p>In semantic actions of printers, functions are provided to
  recursively call the current level and the next level. Moreover,
  a <em>printing context</em> variable is also given, giving the
  current indentation, what should be printed before in the same line
  and what should be printed after in the same line (it is not
  mandatory to use them).</p>

<p>The extension of printers can be done with the
  "<tt>EXTEND_PRINTER</tt>" statement added by the <em>parsing
  kit</em> "<tt>pa_extprint.cmo</tt>".</p>

<h2 id="a:Syntax-of-the-EXTEND_PRINTER-statement">Syntax of the EXTEND_PRINTER statement</h2>

<pre>
        expression ::= extend-statement
  extend-statement ::= "EXTEND_PRINTER" extend-body "END"
       extend-body ::= extend-printers
   extend-printers ::= extend-printer extend-printers
                     | &lt;nothing&gt;
    extend-printer ::= printer-name ":" position-opt "[" levels "]"
      position-opt ::= "FIRST"
                     | "LAST"
                     | "BEFORE" label
                     | "AFTER" label
                     | "LEVEL" label
                     | &lt;nothing&gt;
            levels ::= level "|" levels
                     | level
             level ::= label-opt "[" rules "]"
         label-opt ::= label
                     | &lt;nothing&gt;
             rules ::= rule "|" rules
                     | rule
              rule ::= pattern "->" expression
                     | pattern "when" expression "->" expression
      printer-name ::= qualid
            qualid ::= qualid "." qualid
                     | uident
                     | lident
            uident ::= 'A'-'Z' ident
            lident ::= ('a'-'z' | '_' | misc-byte) ident
             ident ::= ident-char*
        ident-char ::= ('a'-'a' | 'A'-'Z' | '0'-'9' | '_' | ''' | misc-byte)
         misc-byte ::= '\128'-'\255'
</pre>

<h2 id="a:Semantics-of-EXTEND_PRINTER">Semantics of EXTEND_PRINTER</h2>

<h3 id="b:Printers-definition-list">Printers definition list</h3>

<p>All printers are extended according to their corresponding
  definitions which start with an optional "position" and follow with
  the "levels" definition.</p>

<h4>Optional position</h4>

<p>After the colon, it is possible to specify where to insert the
  defined levels:</p>

<ul>
  <li>The identifier "<tt>FIRST</tt>" (resp. "<tt>LAST</tt>")
    indicates that the level must be inserted before (resp. after) all
    possibly existing levels of the entry. They become their first
    (resp. last) levels.</li>
  <li>The identifier "<tt>BEFORE</tt>" (resp. "<tt>AFTER</tt>")
    followed by a level label (a string) indicates that the levels
    must be inserted before (resp. after) that level, if it exists. If
    it does not exist, the extend statement fails at run time.</li>
  <li>The identifier "<tt>LEVEL</tt>" followed by a label indicates
    that the first level defined in the extend statement must be
    inserted at the given level, extending and modifying it. The other
    levels defined in the statement are inserted after this level, and
    before the possible levels following this level. If there is no
    level with this label, the extend statement fails at run
    time.</li>
  <li>By default, if the entry has no level, the levels defined in the
    statement are inserted in the entry. Otherwise the first defined
    level is inserted at the first level of the entry, extending or
    modifying it. The other levels are inserted afterwards (before the
    possible second level which may previously exist in the entry).</li>
</ul>

<h4>Levels</h4>

<p>After the optional "position", the <em>level</em> list follow. The
  levels are separated by vertical bars, the whole list being between
  brackets.</p>

<p>A level starts with an optional label, which corresponds to its
  name. This label is useful to specify this level in case of future
  extensions, using the <em>position</em> (see previous section) or
  for possible direct calls to this specific level.</p>

<h4>Rules</h4>

<p>A level is a list of <em>rules</em> separated by vertical bars, the
  whole list being between brackets.</p>

<p>A rule is an usual pattern association (in a function or in the
  "match" statement), i.e. a pattern, an arrow and an expression. The
  expression is the semantic action which must be of type
  "<tt>string</tt>".</p>

<h3 id="b:Rules-insertion">Rules insertion</h3>

<p>The rules are sorted by their patterns, according to the rules of
  the <a href="extfun.html">extensible functions</a>.</p>

<h3 id="b:Semantic-action">Semantic action</h3>

<p>The semantic action, i.e. the expression following the right arrow
  in rules, contains in its environment the variables bound by the
  pattern and three more variables:</p>

<ul>
  <li>The variable "<tt>curr</tt>" which is a function which can be
    called to recursively invoke the printer at the current
    level,</li>
  <li>The variable "<tt>next</tt>" which is a function which can be
    called to invoke the printer at the next level,</li>
  <li>The variable "<tt>pc</tt>" which contains the printing context
    of type "<tt>Pprintf.pr_context</tt>" (see
    chapter <a href="pprintf.html">Pprintf</a>).</li>
</ul>

<p>The variables "<tt>curr</tt>" and "<tt>next</tt>" are of type:</p>

<pre>
  pr_context -> t -> string
</pre>

<p>where "<tt>t</tt>" is the type of the printer (i.e. the type of its
  patterns).</p>

<p>The variable "<tt>curr</tt>", "<tt>next</tt>" and "<tt>pc</tt>"
  have predefined names and can hide the possible identifiers having
  the same names in the pattern or in the environment of the
  "<tt>EXTEND_PRINTER</tt>" statement.</p>

<h2 id="a:The-Eprinter-module">The Eprinter module</h2>

<p>See its <a href="library.html#a:Eprinter-module">section</a> in the
  chapter "Library".</p>

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

<h3 id="b:Parser-and-Printer-of-expressions">Parser and Printer of expressions</h3>

<p>This example illustrates the symmetry between parsers and
  printers. A simple type of expressions is defined. A parser converts
  a string to a value of this type, and a printer converts a value of
  this type to a string.</p>

<p>In the printer, there is no use of the "<tt>pc</tt>" parameter and
  no use of the "<tt>Pretty</tt>" module. The strings are printed on
  a single line.</p>

<p>Here is the source (file "<tt>foo.ml</tt>"):</p>

<pre>
  #load "pa_extend.cmo";
  #load "pa_extprint.cmo";

  open Printf;

  type expr =
    [ Op of string and expr and expr
    | Int of int
    | Var of string ]
  ;

  value g = Grammar.gcreate (Plexer.gmake ());
  value pa_e = Grammar.Entry.create g "expr";
  value pr_e = Eprinter.make "expr";

  EXTEND
    pa_e:
      [ [ x = SELF; "+"; y = SELF -> Op "+" x y
        | x = SELF; "-"; y = SELF -> Op "-" x y ]
      | [ x = SELF; "*"; y = SELF -> Op "*" x y
        | x = SELF; "/"; y = SELF -> Op "/" x y ]
      | [ x = INT -> Int (int_of_string x)
        | x = LIDENT -> Var x
        | "("; x = SELF; ")" -> x ] ]
    ;
  END;

  EXTEND_PRINTER
    pr_e:
      [ [ Op "+" x y -> sprintf "%s + %s" (curr pc x) (next pc y)
        | Op "-" x y -> sprintf "%s - %s" (curr pc x) (next pc y) ]
      | [ Op "*" x y -> sprintf "%s * %s" (curr pc x) (next pc y)
        | Op "/" x y -> sprintf "%s / %s" (curr pc x) (next pc y) ]
      | [ Int x -> string_of_int x
        | Var x -> x
        | x -> sprintf "(%s)" (Eprinter.apply pr_e pc x) ] ]
    ;
  END;

  value parse s = Grammar.Entry.parse pa_e (Stream.of_string s);
  value print e = Eprinter.apply pr_e Pprintf.empty_pc e;

  if Sys.interactive.val then ()
  else print_endline (print (parse Sys.argv.(1)));
</pre>

<p>Remark on the use of "curr" and "next" while printing operators:
  due to left associativity, the first operand uses "curr" and the
  second operand uses "next". For right associativity operators, they
  should be inverted. For no associativity, both should use
  "next".</p>

<p>The last line of the file allows use in either the OCaml toplevel
  or as standalone program, taking the string to be printed as
  parameter. It can be compiled this way:</p>

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

<p>Examples of use (notice the redundant parentheses automatically
  removed by the printing algorithm):</p>

<pre>
  $ ./a.out "(3 * x) + (2 / y)"
  3 * x + 2 / y
  $ ./a.out "(x+y)*(x-y)"
  (x + y) * (x - y)
  $ ./a.out "x + y - z"
  x + y - z
  $ ./a.out "(x + y) - z"
  x + y - z
  $ ./a.out "x + (y - z)"
  x + (y - z)
</pre>

<h3 id="b:Printing-OCaml-programs">Printing OCaml programs</h3>

<p>Complete examples of usage of extensible printers are the printers
  in syntaxes and extended syntaxes provided by Camlp5 in the pretty
  printing <em>kits</em>:</p>

<ul>
  <li><tt>pr_r.cmo</tt>: pretty print in revised syntax</li>
  <li><tt>pr_o.cmo</tt>: pretty print in normal syntax</li>
  <li><tt>pr_rp.cmo</tt>: also pretty print the parsers in revised
    syntax</li>
  <li><tt>pr_op.cmo</tt>: also pretty print the parsers in normal
    syntax</li>
</ul>

<p>See the chapter entitled "<a href="opretty.html">Printing
  programs</a>".</p>

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

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

  <p class="bottom">
    <a href="http://validator.w3.org/check?uri=referer"><img
       alt="Valid XHTML 1.1" height="31" width="88" /></a>
  </p>

</div>

</div>

</body>
</html>