Ocamlbuild with camlp4 stream parsers

Hello ,

I am in a beginner’s bind. Indeed, while a beginner, many tools, each unique, have to be learned due to mutual dependencies of the environment. At times, I wish I had a lil’ of help :slight_smile:

Right now I can’t compile this program https://github.com/milvi/llc-exemple-ch12. I understand stream parsers where removed from Stdlib/Pervasives. Hence the learning exemple is not self-contained in a fresh install of ocaml.

I am at loss as how to compile with ocamlbuild as “ocamlbuild demo.byte” or using make, since both fail. Can anyone do a PR with the correct packaging, _tags, annotations, dependencies which enables back [< 'Ident s >] syntax ?

Thanks sincerly,

Note : The book can be found here https://caml.inria.fr/pub/distrib/books/llc.pdf. I am reading it in french which eases the way for natives (very nice prose). I was quite relieved to find out that whitequark did https://github.com/whitequark/ocaml-m17n that provides unicode/utf-8 support ahead of the time latin1 warnings will turn into errors.

I tried to reset the environment at the time of the book’s edition comparing with ocaml’s git history around 2009.

Turns out that branching with ocaml 3.10.0 did it : opam switch create 3.10.0 ,

I get various warnings but it works :smile:

[ Warning E: this pattern-matching is fragile."
It will remain exhaustive when constructors are added to type Lexuniv.lex�me.]

Note, however, that entering, opam switch create 3.07, up to 3.09.0 included all failed to compile.

In my opinion, it is better not to learn “dead” technologies like camlp4. It is better to focus on the extension points (see the links from this issue: RWO Book - #2852), and sedlex.

1 Like

Oh, c’mon. Stream parsers and expressions are wonderful, wonderful stuff. Sure I know how to write menhir grammars (and I do when I must) but LL(1) grammars using stream-parsers are 100% sweetness and light! And sure, camlp4 is moribund if not dead; camlp5 is very much alive, and I use
it all the time. Even if we grant that extension-points are great for many uses, they clearly aren’t going to replace stream-parsers/expressions – at least, I’ve seen nobody who can show how they’ll pull that off.

It’s late so I won’t start now, but I’ll have a crack at porting this forward to a modern version of ocaml and camlp5 tomorrow. I doubt it’ll take much work.


You can compile your code with a current version of OCaml by adding a file _tags containing

true: pp(camlp4of), unsafe_string

and doing ocamlbuild demo.byte.


You don’t really need the stream parser syntax sugar to write a recursive descent parser by hand.

Also, I don’t see any major difficulty in writing a ppx for the stream parser syntax (with some adjustment). Which kind of obstruction did you have in mind?

1 Like

Thanks :slightly_smiling_face:
I have
switch compiler description
3.10.0 ocaml-base-compiler.3.10.0 3.10.0
4.04.0 ocaml-base-compiler.4.04.0 4.04.0
4.07.1 ocaml-base-compiler.4.07.1 4.07.1
→ 4.08.0 ocaml-base-compiler.4.08.0 4.08.0
system ocaml-system.4.05.0 base-bigarray.base base-threads.base
base-unix.base ocaml-system.4.05.0

and got back
'+ ocamlfind ocamldep -pp camlp4of -modules demo.ml > demo.ml.depends
Fatal error: cannot load shared library dllunix
Reason: /home/user/.opam/4.08.0/lib/ocaml/stublibs/dllunix.so: undefined symbol: caml_sigmask_hook
File “demo.ml”, line 1:
Error: Error while running external preprocessor
Command line: camlp4of ‘demo.ml’ > /tmp/ocamlppb1b279

On my side (student), the book builds this example on the abstraction alone (of stream parsers). The syntax [< ’ >] is magical in my read yet “I will understand later” if need be. All I care is the syntax sugar that hides the hairy details beyond the scope of a closed and themed exercise. I don’t know of anything else at all, but it is so simple and elegant to use I can follow. At the time it was perhaps embedded with Ocaml compiler and seemed natural to use without further ado. This syntax is actually very light and powerful.

I followed the links but it’s way beyond my level to port the dependencies of this pedagogical example.

Don’t you think it’s cool to revert/travel back in time with git and opam to a state it works ? It’s a time machine :smile:. I see old compiler Caml light as an educational compiler with a minimal grammar. While Caml’s history itself is akin to school grades.

If Opam switch 3.10.0 time machine had failed I would have said it is dead technology indeed.

Note 1: Wow, at this moment, to each question containing the magic word camlp4 (on discord, so, #caml …) the answer is, more or less, f *** you. Hard times …

Anyway, if it helps, we can use OCaml 4.08.0 and camlp5

$ opam install camlp5

As suggested by @nojb, create a _tags file containing the only line

true: pp(camlp5o), unsafe_string

then doing

$ ocamlbuild demo.native (or demo.byte)
$ ./demo.native

And here we are. Nice and easy.

Note 2: Je voudrais simplement dire que ce livre est un modèle du genre, l’un des meilleurs en français sans doute. Difficilement critiquable techniquement (on a affaire au Big Boss XL, là) et superbement écrit (merci Pierre Weis je suppose).
Lire un bouquin technique comme on lit un roman est un plaisir extrêmement rare.

Un autre livre grandiose est “Programmation fonctionnelle, générique et objet” de Philippe Narbel (épuisé - dispo sur libgen). Les seuls Modules/Foncteurs occupent 164 pages… Et le livre date de 2005 !

Imaginons des versions récentes de ces deux livres!

Mais bon, c’est du taf sérieux.

Very true. But I’ve written parsers for decades using the stream-parser syntax, and it is clear to me that it makes writing them much, much, much more labor-efficient

I’m not trying to argue against this PPX stuff, and sure, if somebody produces something as usable as stream-parsers, I’ll try it out. But I haven’t seen it yet, and I’ve been using stream-parsers since long before camlp4 (used to be called “chamau”) existed.

It looks like a problem with your environment. Try resetting your shell or doing eval $(opam env).


Also, I’m not sure camlp4 works with 4.08 yet; if it doesn’t, it will with 4.07.


OK, it wasn’t very hard to write a bare makefile and modify the sources (b/c String and Bytes are no longer the same) to get it working (I tested with “A=>A”). Here’s a git repo; let me know when I can delete it?

1 Like

Oh, forgot:I replaced an accented “Equialen” with the US-ASCII version. I’ve never messed-around with non-ascii code. Maybe it works, and sure I guess I could look it up, but … easier to just switch to ASCII.

@nojb , @spop
true: pp(camlp5o), unsafe_string
it works like a charm.

@Chet_Murthy, I cloned the repo, it works seamlessly, like anew.

Thanks for the patches everyone

@spop Mais carrément ! Quelle lecture facile, du moins, tant qu’il nous tient la main ! Et il nous emmène partout partout.
Je n’aurais pas découvert Narbel sans cette mention, merci.

Regarding stream parsers - they came up during the discussion of labgl and lablgtk: https://github.com/garrigue/lablgl/issues/1#issuecomment-518969249

1 Like