Camlp4
Camlp4 is a software system for writing extensible parsers for programming languages. It provides a set of
Camlp4 was part of the official OCaml distribution which is developed at the
Version 4.08, released in the summer of 2019,[1] was the last official version of this library. It is currently deprecated; [2] instead, it is recommended to use the PPX (PreProcessor eXtensions)[3][4] libraries.[5]
Concrete and abstract syntax
A Camlp4 preprocessor operates by loading a collection of compiled modules which define a
For instance, the OCaml
The abstract syntax tree is at the center of the syntax extensions, which are in fact OCaml programs. Although the definition of grammars must be done in OCaml, the parser that is being defined or extended is not necessarily related to OCaml, in which case the syntax tree that is being manipulated is not the one of OCaml. Several libraries are provided which facilitate the specific manipulation of OCaml syntax trees.
Fields of application
Domain-specific languages are a major application of Camlp4. Since OCaml is a multi-paradigm language, with an interactive toplevel and a native code compiler, it can be used as a backend for any kind of original language. The only thing that the developer has to do is write a Camlp4 grammar which converts the domain-specific language in question into a regular OCaml program. Other target languages can also be used, such as C.
If the target language is OCaml, simple syntax add-ons or syntactic sugar can be defined, in order to provide an expressivity which is not easy to achieve using the standard features of the OCaml language. A syntax extension is defined by a compiled OCaml module, which is passed to the camlp4o executable along with the program to process.
Camlp4 includes a domain-specific language as it provides syntax extensions which ease the development of syntax extensions. These extensions allow a compact definition of grammars (EXTEND
statements) and quotations such as <:expr< 1 + 1 >>, i.e. deconstructing and constructing abstract syntax trees in concrete syntax.
Example
The following example defines a syntax extension of OCaml. It provides a new
memo
, which can be used as a replacement for function
and provides automatic memoization of functions with pattern matching. Memoization consists in storing the results of previous computationsThis is pa_memo.ml, the file which defines the syntax extension:
let unique =
let n = ref 0 in
fun () -> incr n; "__pa_memo" ^ string_of_int !n
EXTEND
GLOBAL: Pcaml.expr;
Pcaml.expr: LEVEL "expr1" [
[ "memo"; OPT "|"; pel = LIST1 match_case SEP "|" ->
let tbl = unique () in
let x = unique () in
let result = unique () in
<:expr<
let $lid:tbl$ = Hashtbl.create 100 in
fun $lid:x$ ->
try Hashtbl.find $lid:tbl$ $lid:x$
with [ Not_found ->
let $lid:result$ = match $lid:x$ with [ $list:pel$ ] in
do { Hashtbl.replace $lid:tbl$ $lid:x$ $lid:result$;
$lid:result$ } ]
>> ]
];
match_case: [
[ p = Pcaml.patt; w = OPT [ "when"; e = Pcaml.expr -> e ];
"->"; e = Pcaml.expr ->
(p, w, e) ]
];
END
Example of program using this syntax extension:
let counter = ref 0 (* global counter of multiplications *)
(* factorial with memoization *)
let rec fac = memo
0 -> 1
| n when n > 0 ->
(incr counter;
n * fac (n - 1))
| _ -> invalid_arg "fac"
let run n =
let result = fac n in
let count = !counter in
Printf.printf "%i! = %i number of multiplications so far = %i\n"
n result count
let _ =
List.iter run [5; 4; 6]
The output of the program is as follows, showing that the fac function (factorial) only computes products that were not computed previously:
5! = 120 number of multiplications so far = 5 4! = 24 number of multiplications so far = 5 6! = 720 number of multiplications so far = 6
References
- ^ "ocaml/camlp4". GitHub. Retrieved 2020-02-04.
- ^ Dimino, Jérémie (2019-08-07). "The end of Camlp4". OCaml. Archived from the original on 2020-02-04. Retrieved 2020-02-04.
- ^ "PPX". ocamllabs.io. Retrieved 2020-02-04.
- ^ Metzger, Perry. "A Guide to PreProcessor eXtensions". OCamlverse. Archived from the original on 2020-02-05. Retrieved 2020-02-05.
- ^ Dimino, Jeremie. "Converting a code base from camlp4 to ppx". Jane Street Tech Blog. Archived from the original on 2020-02-04. Retrieved 2020-02-04.
External links
- Official website
- Camlp4 Wiki - covers version 3.10
- Camlp4 reference manual and tutorial - cover version 3.07
- Camlp4 undocumented features - covers versions up to 3.09
- How to customize the syntax of OCaml, using Camlp5 - Everything you always wanted to know, but were afraid to ask - covers versions up to 3.10
- One-Day Compilers or How I learned to stop worrying and love metaprogramming
- Tutorial on building extensible parsers with Camlp4