Basic implementation of recursive parsers macro
(The use of Unpin is arbitrary, I just wanted some dyn-compatible trait that worked for non-'static lifetimes)
After having played around with this version a bit, it has the same benefit that the (improved) recursive_n function does, which is "returning" multiple of the parsers, but without the tuple games that you mentioned. So... despite also normally shying away from macros, I think this one would be a great tool. rust-analyzer didn't seem to have any issues with the macro, which is a blessing. It may be worth considering offering the arm without = <expr> (if at all possible), so that the user gets auto-complete while trying to type names. It was the only real advantage I noticed while comparing the two (ignoring that the current impl doesn't allow for declaring parsers! multiple times in the same scope, but that fix is easy).
Neat solution :) Out of curiosity, what is your opinion on removing define and declare from the public API Recursive (either through renaming to _define and declare or deprecating the methods while mentioning the leak?
I'm glad you like it, your recursive_n approach inspired me to come up with the drop closure solution.
It may be worth considering offering the arm without
= <expr>(if at all possible), so that the user gets auto-complete while trying to type names.
Hmm, what do you mean by this? My editor doesn't have LSP support, so I don't really understand.
My plan is to add some way to include a type hint (like <name> $(: <type>)? = ...).
Out of curiosity, what is your opinion on removing define and declare from the public API Recursive (either through renaming to _define and declare or deprecating the methods while mentioning the leak?
Very much in favour. I've been of the view for a while that they're a stop-gap, and one that's easy to accidentally misuse. I think deprecation is fine for the time being (leaks aren't ideal, but they're not really an actual problem for the most-part), at least until a 1.0 release finally comes around.
Hmm, what do you mean by this? My editor doesn't have LSP support, so I don't really understand.
Ah. I would not survive programming Rust without my LSP, props to you. So, I mean:
// With `recursive_n` you effectively have to forward declare the parsers
recursive_n(|(expr, statement)|
let expr = expr_atom(expr.clone(), , sta▍)
})
// With `parsers!` you are encouraged to finish the definition before moving to the next time
parsers! {
expr = expr_atom(expr.clone(), sta▍)
}
For this example, we can treat ▍as the cursor position. At this point with recursive_n there is enough information to get auto-complete for statement where as it's not possible to do something similar with parsers! without doing statement = chumsky::prelude::todo() somewhere in the macro. Perhaps just having a way to forward declare like:
parsers! {
declare: expr, statement;
/* rest */
}
I don't think it's really a big problem, but just something I noticed :)