# Using Menhir to parse into idiomatic JS (TypeScript) structures

**URL:** <https://discuss.ocaml.org/t/using-menhir-to-parse-into-idiomatic-js-typescript-structures/13809>\
**Category:** Ecosystem\
**Tags:** menhir, atd, atdgen, js\_of\_ocaml\
**Created:** [January 7, 2024, 4:16pm UTC](https://discuss.ocaml.org/t/using-menhir-to-parse-into-idiomatic-js-typescript-structures/13809 "2024-01-07T16:16:56Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![shonfeder](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/shonfeder/32/424_2.png) [@shonfeder](https://discuss.ocaml.org/u/shonfeder)\
**Post date:** [January 7, 2024, 4:16pm UTC](https://discuss.ocaml.org/t/using-menhir-to-parse-into-idiomatic-js-typescript-structures/13809/1 "2024-01-07T16:16:56Z")

</div>

Hello and Happy New Year!

As we all know, despite being named an [Objective Categorical Abstract Machine Language](https://en.wikipedia.org/wiki/Caml), OCaml is Obviously a Completely Awesome [Meta Language](https://en.wikipedia.org/wiki/ML_(programming_language)). The awesomeness is founded on the wonderful language, but obviously completed by the extraordinary ecosystem of tools and techniques that take life in that language. 😜

This is a note to share a solution I hacked together using a handful of these awesome tools in our lovely language, but also a request for any suggestions on a more elegant solution to the problem posed.

* * *

## The Problem

I wanted to use Menhir and Sedlex to write a fault-tolerant, incremental parser for a preexisting project that has an intermediate representation (IR), and a bunch of other tools, written in TypeScript.

## Non-solutions

Unfortunately, achieving this outcome was not quite as simple as adding a `(mode js)` to dune to have the generated parser compiled by [Js\_os\_ocaml (Jsoo)](https://ocsigen.org/js_of_ocaml/latest/manual/overview). Of course, that _does_ work like a charm, and if we could justify rewriting everything in OCaml, we’d be able to produce JS easy as pie. But for interop with the existing TypeScript code this won’t fly. We need to parse into JS objects that represent the IR in a human-readable way, ideally matching our existing TypeScript types, but Jsoo gives something like this.

```auto
> parser.parse('def foo(a,b) = 123')
[0, [ 0, [ 0, [Array], [Array] ], 0 ] ]

```

My next thought was to use Melange: it seems to be a great project with a lot of excellent work going in to it, and, iiuc, its purpose is precisely to compile OCaml into idiomatic(ish) JS. But I hit a road block right away, which led me to ask [What are the limits and prerequisites of using dependencies with melange?](https://discuss.ocaml.org/t/what-are-the-limits-and-prerequisites-of-using-dependencies-with-melange/13688) and to try something else.

## A Solution

Fortunately, the wealth of shining jewels-of-tools in the OCaml ecosystem made this short work. The solution I ended up with is hacky as heck, but its doing what I needed:

- I define our types using the excellent [atd](https://github.com/ahrefs/atd).

- I generate OCaml and TypeScript representations of the types, along with JSON serializers, via a dune config like

- I use menhir and sedlex to define a parser that produces inhabitants of the OCaml types generated in `lang_ir_t.ml`. (Working out the incremental, fault-tolerant parsing was its own exhilarating side quest, but I’ll save a report on that for it’s own post.)

- Then I use Jsoo to run the parser in JS and then serialize its optimized but inscritable representation into the JSON dictated by atd:

- And, finally, I make a little `wrapper.js` that invokes the atd-generated deserializer to parse into the TypeScript representation:

## The result

I now can use the wrapper script to parse into the nice TypeScript (compatible) structures I need:

```auto
[me@comp mparsing]$ node
> var p = require('./wrapper.js')
undefined
> p.parse("def foo(a,b) = 123")
[
{
    loc: { start_: [Object], end_: [Object] },
    v: { name: 'foo', params: [Array], body: [Object] }
}
]

```

* * *

I have three hopes for this post:

1. I hope to contribute yet another note celebrating the virtues of our extraordinary programming language ecosystem.
2. I hope it might be useful for others who need to solve similar problems.
3. I hope there is a more elegant way to achieve this result (namely, without having to go through serialization) and that one of y’all can point the way.

❤ 🐪

---

_[View the full topic](https://discuss.ocaml.org/t/using-menhir-to-parse-into-idiomatic-js-typescript-structures/13809)._
