mparser icon indicating copy to clipboard operation
mparser copied to clipboard

Parsing a C-like language

Open basus opened this issue 5 years ago • 3 comments

This is not a bug, but I'm wondering how I can use MParser to write a parser for a C-like language? The main issue I'm running into is when defining the different kinds statements which need to be mutually recursive:


  let rec while_ : (stmt, bytes list) MParser.t =
    while' >> parens (cond) >>= fun cond ->
    (braces block) >>= fun bl -> return (While(cond, bl))
  and block : (block, bytes list) MParser.t =
    braces (many statement)
  and statement : (stmt, bytes list) MParser.t =
    attempt assign <|>
    attempt call <|>
    attempt while_

Here assign and call have been defined separately and work fine. However, while needs to be mutually recursive with block and statement, but this definition violates OCaml's rules for mutually recursive definitions.

Is there some other way to define rules like this using MParser?

basus avatar May 03 '19 20:05 basus

I too would like to know this. An example from the author would be useful.

While we're waiting, I'd like to note that:

  1. Angstrom has a fix function for recursion; MParser could make use of something like that.
  2. Because the parsers are functions of state, you should be able to fix your example as
let rec while_ state = (
  while' >> parens (cond) >>= fun cond ->
  (braces block) >>= fun bl -> return (While(cond, bl))
) state
and block state = (
  braces (many statement)
) state
and statement state = (
  attempt assign <|>
  attempt call <|>
  attempt while_
) state

Ugly, I know, but should satisfy OCaml's demands on recursive definitions.

An alternative would be to introduce some indirection. For example first define your recursive parsers as ref xxx, and then := all of their values.

magv avatar Jun 15 '20 20:06 magv

Any update on this? I created a similar issue in angstrom https://github.com/inhabitedtype/angstrom/issues/213 which allows recursive parser (via the fix trick), but does not allow mutually recursive parsers. The fastparse scala parser combinator library allows those mutualy recursive parsers, which then enable to parse full languages like Python using parser combinators.

aryx avatar Apr 08 '21 10:04 aryx

cc @murmour

aryx avatar Apr 08 '21 10:04 aryx