Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parsing a C-like language #9

Open
basus opened this issue May 3, 2019 · 3 comments
Open

Parsing a C-like language #9

basus opened this issue May 3, 2019 · 3 comments

Comments

@basus
Copy link

basus commented May 3, 2019

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?

@magv
Copy link

magv commented Jun 15, 2020

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.

@aryx
Copy link

aryx commented Apr 8, 2021

Any update on this? I created a similar issue in angstrom inhabitedtype/angstrom#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
Copy link

aryx commented Apr 8, 2021

cc @murmour

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants