[ANN] first release of nice_parser

I’m pleased to announce the first release of nice_parser, a single functor library that wraps your {menhir, ocamlyacc}-generated parser with a nice, high-level interface with beautiful loaction-aware error messages:

opam install nice_parser
ocaml
#use "topfind";;
#require “nice_parser”;;
#show_module Nice_parser.Make;;
module Make :
  functor (P : Nice_parser.RAW_PARSER) ->
    sig
      type token = P.token
      type result = P.result
      exception LexError of { msg : string; loc : Location.t; }
      exception ParseError of { token : token; loc : Location.t; }
      val pp_exceptions : unit -> unit
      val parse_string : ?pos:Lexing.position -> string -> result
      val parse_chan : ?pos:Lexing.position -> in_channel -> result
      val parse_file : string -> result
    end

The library relies on OCaml 4.08’s new source highlighting mechanism for pretty lexing and parsing errors,

File "examples/illegal.katbb", line 1, characters 10-17:
1 | this!; is illegal!; isntit?
              ^^^^^^^
Error: [parser] unexpected token

but can also be used with earlier versions of OCaml.

The nice_parser repository includes an example that helps you get started with your own parser in seconds. The API is documented here.

Happy parsing!

11 Likes

Cool! Any possibility of supporting Sedlex for the Unicode fans?

I don’t have time to work on it myself in the immediate future, but would very much appreciate a pull request. I agree it would be great to support sedlex.

1 Like

Nice idea! And happy to see enthusiasm about my error highlighting code :-).

On the implementation side however, I would recommend against hijacking the compiler’s Location module as you seem to be doing currently. Relying on this is quite hackish and fragile, and may break in future versions of ocaml (there’s no retro-compatibility guarantees made for compiler-libs in general; ocaml-migrate-parsetree provides some support but Location is borderline).

Even if it’s a bit more work, I think it would make sense to package the source highlighting code that currently lives in the compiler as a standalone library. I wanted to do that actually, after my initial implementation in the compiler, but I haven’t had the time yet. I think it would make a lot of sense to integrate it into your nice_parser library!

Unfortunately, I will have very little time to write code myself in the coming month, but otherwise I’ll be happy to help with reusing my code. I think it makes a lot of sense to have it as part of a more generic library than simply in the compiler’s code base, since it’s a piece of code that’s useful and also a tad annoying to reimplement.

4 Likes

I think that little usability improvements like that can go a long way. :slight_smile: Thanks for making that happen! I also think that now that we have this infrastructure, every parser wirtten in OCaml should benefit from it.

I think it would make sense to package the source highlighting code that currently lives in the compiler as a standalone library. I think it would make a lot of sense to integrate it into your nice_parser library!

I agree this would make a lot of sense, and it would be wonderful to integrate it with nice_parser! (Unfortunately I also won’t have time for this anytime in the near future.)

Your points are of course correct. But there are also some good arguments in favor of the current design:

  • Because we’re hijacking compiler modules, (i) nice_parser has less than 100 LoC and (ii) will profit – for free – from future improvements on the compiler.
  • I’m not worried about fragility. Should the interfaces change in the future, we only have to release a new version of nice_parser. We can maintain backwards compatibility using something like ppx_optcomp. And because there is so little code, doing this will be trivial.

Putting things in a standalone library, as you suggested, makes of course sense, but will also result in a much larger library with a non-trivial maintenance burden.

I’m not against the standalone library idea, I just wanted to point out that there are pros and cons, and that maybe fragility is not really an issue. What do you think?

1 Like

In general things that depend on unstable parts of OCaml and that may break on any new OCaml releases are bad for the eco-system. They are a burden both for the OCaml compiler developer which can’t test their changes on meaningful samples of the opam-repository and for the larger eco-system and end-users by the amount of work and churn that is needed on new OCaml releases (the ppx cancer is a good example of this).

2 Likes

This makes sense from a more holistic point of view. Maybe this suggests that the current design is acceptable as long as the library has few dependents (currently 0), but no longer acceptable if it sees strong adoption? Strong adoption would also justify an increased maintenance burden.

Maybe you could write up a good TODO list for nice_parser including the interfaces you would want from a library that was detached from the compiler itself? It isn’t as good as someone having the time to do the work, but it makes it slightly more likely that someone would notice that these things need doing.

Well, coming up with nice interfaces is the hard part, the rest is simply copy-pasting code from the compiler.
Anyway, I’ve just done most of the required work, I think:

This standalone mini library isolates the pretty-priting code, and I’m relatively satisfied by its interface. The name could probably be better, I’m open to suggestions :-).
The library needs a bit more packaging work (just the usual stuff), and I also haven’t really tested it, but it should work, hopefully.
I’ll also gladly give commit rights to anyone that wants to actually use it (I won’t, in the near future)!

6 Likes

Awesome!
I would be happy to take care of the packaging.
We can integrate it with nice_parser as a first test, though I can’t promise that I find time for it immediately.

RE names, “quote_loc” is not much better but maybe slighlty more descriptive.