combine icon indicating copy to clipboard operation
combine copied to clipboard

Tools for debugging recursion problems?

Open jwiegley opened this issue 3 years ago • 4 comments

Hello, I'm using combine to write a parser for a language that's not LL(1), and don't know if it's LALR(1). The code is here, with the original grammar all in comments:

https://github.com/jwiegley/motoko_parse/blob/main/src/lib.rs

When I try to runcargo test, I get the following error:

error: reached the recursion limit while instantiating `<(Ignore<&mut &mut combine::pars...<&str>>::parse_mode::<FirstMode>`
   --> /Users/johnw/Products/motoko_expr/target/.cargo-home/registry/src/github.com-1ecc6299db9ec823/combine-4.6.2/src/parser/sequence.rs:527:9
    |
527 |         self.0.parse_mode(mode, input, state).map(|(_, b)| b)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
note: `parse_mode` defined here
   --> /Users/johnw/Products/motoko_expr/target/.cargo-home/registry/src/github.com-1ecc6299db9ec823/combine-4.6.2/src/parser/mod.rs:267:5
    |
267 | /     fn parse_mode<M>(
268 | |         &mut self,
269 | |         mode: M,
270 | |         input: &mut Input,
...   |
274 | |         M: ParseMode,
275 | |         Self: Sized,
    | |____________________^
    = note: the full type name has been written to '/Users/johnw/Products/motoko_expr/target--custom/debug/deps/motoko_parse-3f75fd538faec618.long-type.txt'

At this point I've tried simplifying things and cutting down the use of closures to the bare minimum, etc., but I can't seem to move past this error. What would be the best approach to debugging something like this?

Thanks, John

jwiegley avatar Nov 20 '21 04:11 jwiegley

I've worked around this for now with:

#![recursion_limit = "1024"]

jwiegley avatar Nov 21 '21 00:11 jwiegley

There isn't any tools directly to debug it (unless rustc provides some general ability to print out the entire, long type). But if you have a good idea of how your grammar looks you may be able to figure out where these large types appear as they would correlate to wide and deeply constructed parsers that use impl Parser.

If you know (or guess) where these large parsers are then you can use the parser! macro, the opaque parser or just box the parser to break this large parser up.

Marwes avatar Nov 21 '21 13:11 Marwes

How do I determine which parsers are the deeply constructed ones? None of mine are beyond 20 lines long.

jwiegley avatar Dec 09 '21 00:12 jwiegley

"Deeply" in this case relates to multiple impl Parser returning functions calls, each call will create a larger and larger actual type, but you can break it up by using parser! or opaque.

Marwes avatar Dec 09 '21 09:12 Marwes