---
breaks: false
tags: public-tech
---
# Dune と Menhir を組み合わせて使う
この記事は [OCaml Tips Advent Calendar 2022](https://adventar.org/calendars/8396) の三日目です。
[Menhir](http://gallium.inria.fr/~fpottier/menhir/) は LR(1) パーサジェネレータで、要するに yacc の OCaml 版である。
OCaml 版 lex であるところの ocamllex と組み合わせて、
インタプリタ・コンパイラみたいなものを作るときに使う。
とりあえず menhir を入れる。
```
$ opam install menhir
```
でもって字句解析器と構文解析器を作って `lib/lexer.mll` と `lib/parser.mly` に
入れる。
ビルドのときに Menhir と ocamllex を使うように `lib/dune` ファイルを編集する。
Menhir に `--explain` オプションを渡しておくと、ルールにコンフリクトが発生した
ときに、状況を説明するログファイルを吐いてくれるようになるので、つけておく。
```
$ vim lib/dune
(menhir
(flags (--explain))
(modules parser))
(ocamllex
(modules lexer))
(library
(name yourfavname))
```
このままビルドしようとすると `dune-project` を編集しろと言われる。
```
File "lib/dune", line 1, characters 0-26:
1 | (menhir
2 | (modules parser))
Error: 'menhir' is available only when menhir is enabled in the dune-project
file. You must enable it using (using menhir 2.1) in your dune-project file.
```
これに従って `dune-project` を編集する。
```
$ vim dune-project
# 末尾
(using menhir 2.1)
```
これでビルドが通るようになる。