Catching a Menhir-generated exception

I’m learning how to use Menhir for parsing a language, and so far it’s been great except for error handling. I have a few questions. I’m working with Menhir version 20231231.

First, the manual seems to imply that “new-style” error handling (with the .messages file etc.) only works if the parser is incremental. Is that true? My parser isn’t, because I didn’t want to add any extra complexity I didn’t need. But if the only way to handle errors in a monolithic parser is with the error token, that should be made clear.

Second, how to use the error token effectively is not discussed in the manual and as far as I can tell, there are no examples of it in the demos.

Third, even if I just wanted to catch the Error exception raised by a parse error, I have been unable to do so. The generated parser.mli file exports the Error exception, but my parser raises a Parser.MenhirBasics.Error exception which I can’t catch because the module Parser.MenhirBasics is not exported.

This is just a huge headache, and I would greatly appreciate any suggestions/advice. Thanks!

Ah, I solved one of my problems, at least! I was trying to catch the Error exception in the wrong place.

For your first question, the .messages-style error handling is compatible with the monolithic API as long as you pass the --exn-carries-state flag to Menhir. This causes the exception Error to become Error of int where the integer maps to one of the messages. Then you can print error messages with code like try Parser.parse Lexer.token lexbuf with Parser.Error i -> prerr_endline (Messages.message i) (assuming your modules are called Parser, Lexer, and Messages).

2 Likes

Thanks! That’s very helpful.