Parsing a C-like language
basus opened this issue · 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?
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:
- Angstrom has a
fix
function for recursion; MParser could make use of something like that. - 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.
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.