# Parser for the Scala programming language?

**URL:** <https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541>\
**Category:** Ecosystem\
**Created:** [March 26, 2021, 12:12pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541 "2021-03-26T12:12:36Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![aryx](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/aryx/32/2356_2.png) [@aryx](https://discuss.ocaml.org/u/aryx)\
**Post date:** [March 26, 2021, 12:12pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/1 "2021-03-26T12:12:36Z")

</div>

Does anyone know of an OCaml library to parse Scala programs? I’ve searched a bit on the Web but I could not even find a Yacc grammar for Scala (there’s an official EBNF spec, but not sure how easy it is to translate in a working LALR(1) grammar).

---

<div class="post-metadata">

**Author:** ![mnxn](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mnxn/32/2445_2.png) [@mnxn](https://discuss.ocaml.org/u/mnxn)\
**Post date:** [March 26, 2021, 4:01pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/3 "2021-03-26T16:01:57Z")

</div>

Is there are reason you need a library in OCaml? I would expect most Scala parsing tools to be written in Scala.

I can’t find any existing libraries, so if you really need to do it in OCaml, I think these are your options:

1. Write JNI bindings to an existing JVM library for parsing Scala. I’d imagine that the Scala compiler exposes its parser as a library. There are probably some other Scala projects that can parse Scala code too. You can use [camljava](https://github.com/xavierleroy/camljava) to use the JNI from OCaml.

2. Use the [ANTLR4 Scala grammar](https://github.com/antlr/grammars-v4/blob/master/scala/Scala.g4) and generate C++ code. You will have to write a lot of binding code to make it usable from OCaml.

3. Write the parser in your OCaml yourself. I don’t think this is very easy, but neither are the other options.

---

<div class="post-metadata">

**Author:** ![roddy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/roddy/32/2261_2.png) [@roddy](https://discuss.ocaml.org/u/roddy)\
**Post date:** [March 27, 2021, 1:37am UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/4 "2021-03-27T01:37:10Z")

</div>

I wrote [a library](https://github.com/roddyyaga/jay) a while ago for making Earley parsers (I think they’re pretty underrated). If you want to use it I would warn you that it is not polished and contains at least one bug. You could also try writing a specialised one for the Scala grammar, which could probably be nicer in terms of typing. Not sure how the difficulty of that would compare to (a) writing your own with a parser generator like menhir or (b) writing your own with a parser combinator library like angstrom.

---

<div class="post-metadata">

**Author:** ![kanishka](https://avatars.discourse-cdn.com/v4/letter/k/3e96dc/32.png) [@kanishka](https://discuss.ocaml.org/u/kanishka)\
**Post date:** [March 27, 2021, 2:20am UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/5 "2021-03-27T02:20:07Z")

</div>

This is a long shot attempt.

Look through [GitHub - scalafiddle/scalafiddle-core: Source code for the scalafiddle.io compilation service](https://github.com/scalafiddle/scalafiddle-core) to see how it accesses scala compiler from scalajs. Hack it to expose a scala parser, if it’s exposed from compiler. Define a function for converting the tree to Json. Compile it for nodejs. Use jsoo to invoke the exposed functionality. Define deserializer in ocaml.

---

<div class="post-metadata">

**Author:** ![aryx](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/aryx/32/2356_2.png) [@aryx](https://discuss.ocaml.org/u/aryx)\
**Post date:** [March 27, 2021, 9:53am UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/6 "2021-03-27T09:53:31Z")

</div>

Cool stuff. How does it differ from the other early parser ocaml libraries:

- [GitHub - rlepigre/ocaml-earley: Parsing library based on Earley Algorithm](https://github.com/rlepigre/ocaml-earley)
- [GitHub - tomjridge/tjr\_simple\_earley: Simple implementation of a parsing algorithm inspired by Earley](https://github.com/tomjridge/tjr_simple_earley)

One thing I like about yacc/menhir is that you have some static checks that your grammar is unambigous. Can you have the same kind of guarantees with your tool?

---

<div class="post-metadata">

**Author:** ![roddy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/roddy/32/2261_2.png) [@roddy](https://discuss.ocaml.org/u/roddy)\
**Post date:** [March 27, 2021, 12:20pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/7 "2021-03-27T12:20:02Z")

</div>

Oh cool, I wasn’t aware of those! They definitely look more polished than mine! I don’t think you do get guarantees like that; one major use of Earley parsers is in NLP where the grammars usually are ambiguous (and you want to get all parses or something). But the nice thing about them is that you can get a parser pretty directly from the BNF (my library consumes RFC5234 ABNF) so as long as you trust whoever wrote the spec you’re probably OK.

---

<div class="post-metadata">

**Author:** ![thomas\_ridge](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thomas_ridge/32/1478_2.png) [@thomas\_ridge](https://discuss.ocaml.org/u/thomas_ridge)\
**Post date:** [March 27, 2021, 2:08pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/8 "2021-03-27T14:08:30Z")

</div>

I did this in 2016 I think. It resulted in a patch to clean up the grammar (my single contribution to the Scala project):

> **[Scala 2.12.0-RC1 is now available!](https://www.scala-lang.org/news/2.12.0-RC1/)**

Unfortunately I cannot now locate the parser code ☹

I do remember that the grammar was surprisingly nice. Probably this doesn’t help much.

---

<div class="post-metadata">

**Author:** ![aryx](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/aryx/32/2356_2.png) [@aryx](https://discuss.ocaml.org/u/aryx)\
**Post date:** [March 27, 2021, 3:28pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/9 "2021-03-27T15:28:03Z")

</div>

Try harder @thomas_ridge ! Also the lexer for Scala seems to not be trivial, especially how it must handle newlines. Do you remember troubles writing the lexer?

---

<div class="post-metadata">

**Author:** ![dbuenzli](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dbuenzli/32/18_2.png) [@dbuenzli](https://discuss.ocaml.org/u/dbuenzli)\
**Post date:** [March 27, 2021, 5:11pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/10 "2021-03-27T17:11:45Z")

</div>

I asked a former Scala dev, he suggests the following:

> Maybe have a look at [scalaparse](https://com-lihaoyi.github.io/fastparse/#ScalaParse), a subproject of FastParse a combinator parser library.
> 
> It seems scalaparse is fairly good and complete but also reasonably simple (~700 loc) so it _could_ serve as a starting point or serve as some kind of specification.

HTH.

---

<div class="post-metadata">

**Author:** ![Chet\_Murthy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chet_murthy/32/1501_2.png) [@Chet\_Murthy](https://discuss.ocaml.org/u/Chet_Murthy)\
**Post date:** [March 28, 2021, 4:55pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/11 "2021-03-28T16:55:51Z")

</div>

If you’re willing to write some Scala code (which might be easy-to-write, or there might even be a tool, there might be a way to convert a Scala parse-tree into … JSON? s-expressions? something that is easy-to-parse unambiguously.

Can you explain a little about what your goal is? Maybe there’s a way to avoid most of the parsing burden? I once needed to do some aspect-oriented code-injection for Java, and was able to get by with just _lexing_ plus parenthesis (well, parens, brackets, braces) counting. And a regular expression to recognize method declaration headers. It was a hairy Perl regexp, but really, so much easier than writing a Java parser.

---

<div class="post-metadata">

**Author:** ![XVilka](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/xvilka/32/5334_2.png) [@XVilka](https://discuss.ocaml.org/u/XVilka)\
**Post date:** [March 29, 2021, 5:50am UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/12 "2021-03-29T05:50:24Z")

</div>

There is a maintained [tree-sitter grammar for Scala](https://github.com/tree-sitter/tree-sitter-scala) and Tree-Sitter is the pure C library, so you could just use FFI to call it.  
You could even create a generic OCaml binding for the Tree-Sitter and publish it to the official GitHub organization. Good examples in similar languages are:

- [GitHub - tree-sitter/haskell-tree-sitter: Haskell bindings for tree-sitter](https://github.com/tree-sitter/haskell-tree-sitter)
- [tree-sitter/lib/binding\_rust at master · tree-sitter/tree-sitter · GitHub](https://github.com/tree-sitter/tree-sitter/tree/master/lib/binding_rust)

---

<div class="post-metadata">

**Author:** ![Khady](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/khady/32/469_2.png) [@Khady](https://discuss.ocaml.org/u/Khady)\
**Post date:** [March 29, 2021, 6:21am UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/13 "2021-03-29T06:21:44Z")

</div>

the people from onivim wrote some bindings [oni2/src/reason-tree-sitter at master · onivim/oni2 · GitHub](https://github.com/onivim/oni2/tree/master/src/reason-tree-sitter)

---

<div class="post-metadata">

**Author:** ![aryx](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/aryx/32/2356_2.png) [@aryx](https://discuss.ocaml.org/u/aryx)\
**Post date:** [March 29, 2021, 7:03am UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/14 "2021-03-29T07:03:06Z")

</div>

Yes, I know about tree-sitter-scala, @mjambon actually extended reason-tree-sitter and wrote a binding for tree-sitter ( [GitHub - returntocorp/ocaml-tree-sitter: Generate OCaml parsers based on tree-sitter grammars.](https://github.com/returntocorp/ocaml-tree-sitter/) ) but in our experiments tree-sitter-scala could not parse most scala projects out there, there was a 85% parsing success rate. We could extend tree-sitter-scala, and we tried a little, but the grammar in tree-sitter-scala differs quite a bit from the official EBNF spec, so I was wondering if someone wrote a working, complete, scala parser in OCaml. Apparently someone did, @thomas_ridge, but he lost the code … I guess scalaparse from fastparse mentioned before could be a good starting point. Thanks everybody!

---

<div class="post-metadata">

**Author:** ![Jason\_Nielsen](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jason_nielsen/32/2097_2.png) [@Jason\_Nielsen](https://discuss.ocaml.org/u/Jason_Nielsen)\
**Post date:** [March 29, 2021, 6:03pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/15 "2021-03-29T18:03:06Z")

</div>

I just came across [ocaml-tree-sitter](https://github.com/returntocorp/ocaml-tree-sitter) the other day. How battle hardened are the tree-sitter parsers currently? The last time I played around with some of them they were not complete. Clearly the original purpose of tree-sitter was for a better text editor experience. My guess is that being 85% complete is probably enough to greatly improve text edition but isn’t so great if you are trying to use it to parse and generate code. The last few percent are the hard miles in my experience when trying to create a complete parser for a language… all the weird and wonderful corner cases rear their heads.

---

<div class="post-metadata">

**Author:** ![mjambon](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mjambon/32/6180_2.png) [@mjambon](https://discuss.ocaml.org/u/mjambon)\
**Post date:** [March 29, 2021, 7:36pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/16 "2021-03-29T19:36:56Z")

</div>

> [@Jason\_Nielsen](#):
>
> How battle hardened are the tree-sitter parsers currently?

It depends on the language and how much work was put into it. One nice thing about tree-sitter is error recovery. Most often, parsing errors due to unsupported syntax can be skipped over, affecting only a small region of the source file. This is useful for code browsing and code search. With error recovery, a given file could be parsed with 90% success rather than 0%. That’s how we get to 99.8% success overall for typescript.

---

<div class="post-metadata">

**Author:** ![314eter](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/314eter/32/25_2.png) [@314eter](https://discuss.ocaml.org/u/314eter)\
**Post date:** [March 29, 2021, 7:56pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/17 "2021-03-29T19:56:31Z")

</div>

Even tree-sitter grammars that are 100% complete are not necessarily usable for code generation. [tree-sitter-ocaml](https://github.com/tree-sitter/tree-sitter-ocaml) parses all valid OCaml code (as far as I know, there may be bugs that I didn’t find yet), but it parses some invalid code too (which can be a problem for some applications), and may attach attributes to wrong nodes.

---

<div class="post-metadata">

**Author:** ![aryx](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/aryx/32/2356_2.png) [@aryx](https://discuss.ocaml.org/u/aryx)\
**Post date:** [May 11, 2021, 1:11pm UTC](https://discuss.ocaml.org/t/parser-for-the-scala-programming-language/7541/18 "2021-05-11T13:11:44Z")

</div>

I ended up porting the recursive descent parser in the Scala compiler to OCaml …  
I think it was the fastest way to get a working parser from OCaml …

> <https://github.com/returntocorp/pfff/blob/develop/lang_scala/parsing/Parser_scala_recursive_descent.ml>
