Pass Extra Arguments To Child Parsers In Rust's nom
This is how I'm passing supplemental arguments/parameters to nom parsers inside other parsers (e.g. inside many1
). The key is on lines 21-22 between the comments. More notes below the code.
//! ```cargo
//! [dependencies]
//! nom = "7.1.3"
//! ```
use nom::bytes::complete::tag;
use nom::error::ParseError;
use nom::multi::many1;
use nom::IResult;
use nom::{ Compare, InputLength, InputTake };
fn main() {
let left = Ok((" bravo", vec!["alfa"]));
let right = parse("alfa bravo");
assert_eq!(left, right);
println!("test past");
}
fn parse(source: &str) -> IResult<&str, Vec<&str>> {
let extra_arg = "alfa";
/////////////////////////////////////////////
// let (source, result) = many1(|src|
// grabber(src, extra_arg))(source)?;
// TODO: Write up this version above ^ too//
/////////////////////////////////////////////
let (source, result) = many1(grabber(extra_arg))(source)?;
/////////////////////////////////////////////
Ok((source, result))
}
fn grabber<T, Input, Error: ParseError<Input>>(
extra: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTake + Compare<T>,
T: InputLength + Clone,
{
tag(extra)
}
//fn grabber<'a>(source: &'a str, extra: &'a str) ->
// IResult<&'a str, &'a str> {
// let (source, result) = tag(extra)(source)?;
// Ok((source, result))
//}
Output:
test past
Notes
-
The standard way to use
many1
without passing extra arguments looks like this:many1(grabber)(source)?
-
This is what I'm using instead to pass the arguments:
many1(PIPEHEREsrcPIPEHERE grabber(src, extra_arg))(source)?
(NOTE: PIPEHERE is for a
|
, but they have trouble parsing right now.) -
The methodology is to pass a closure to
many1
with the originalsource
assrc
and then add the extra argument via theextra_arg
variable -
This method require adding explict lifetimes to the method that's getting the extra arguments (
grabber
in this case) - This looks to be the way to do it with alt, but I need to test it more:
alt ((
|src| block_section_name(src, config),
|src| block_section_name(src, config),
))(source)
TODO
☐
Get other examples of parsers this works with besides many1
. Look at alt
, opt
, tuple
, pair
, etc...)
-- end of line --