Pass variables to nom?

Is it possible to pass variables to a nom macro? I’d like the delimiter to be parsed to be provided by stdin.


I’m not entirely clear on what you’re struggling with here.
Yes, it’s possible. nom isn’t special in looking for a literal or anything. delimited! only expects a beginning and ending parser, tries to apply those against bytes until they both match, and then pass the interior portion to the parser indicated. Most people use tag! for the end delimiters, and tag takes any &[T] where &[T] : nom::AsBytes (which is implemented for [u8], str, and some others).

If you’re using named! you may be looking for named_args!, if you need to pass and handle additional arguments, though you may be better off writing your own named fns.

If this hasn’t been helpful, could you provide a bit of code (or better, a playground with the code) that shows what you’re trying to do?

1 Like

It was named_args I was looking for. Thanks!

error: expected open delimiter                                                                         
  --> src/                                                                      
55 |             short_description: preceded!(take_until_and_consume!(delims.comm), take_until_and_consume!("\n")) >>
   |                                                                                                       ^ expected open delimiter

Do you know why I would then get this error? here

I’m not certain, but that seems to be an error in parsing the code that’s returning the wrong error message. If the repo is current, I think the , instead of >> at the end of line 59 may be to blame. Because of the way do_parse! works, it’s especially susceptible to this kind of error.

If that solves your issue, would you mind opening an issue against the nom repo, describing the error and including that entire do_parse! expression?

I had the same problem when I switched from named! to my own functions. The problem is that nom-macros like named! or method! pass the input to the first parser. If you write your own functions you need to pass the input by your own, i.e. first argument of the first parser in your functions must be input. In your case:

 fn parse_doc(input: &str, delims: Delimiters) -> IResult<&str, Doc> {
        do_parse!(input, // <-- add here
            short_description: preceded!(take_until_and_consume!(delims.comm), take_until_and_consume!("\n")) >>
1 Like

Good catch, @farnbams! I totally missed that the input parameter is missing.
I think the , I pointed out is still what is triggering the error looking as strangely as it does, but I think what you’re pointing out is needed to get the parser working.

@farnbams, @Zarenor I needed to change the , -> >> and add input to the beginning of do_parse!. Thanks for the help!

I have, hopefully one last question with regards to nom. I have a part which I want to make a Vec of key,values but it has to be optional.

// ...
// ...
    fn as_kv(input: &str) -> Result<KV, u32> {
        let parts: Vec<_> = input.split(": ").collect();
        let result = KV {
            key: parts[0].trim().to_string(),
            value: parts[1..].join("").to_string(),
         println!("{:#?}", result);

KV is just a struct key,value

    struct KV {
        key: String,
        value: String,

I can see with println! statements that the KVs are being successfully parsed when it’s called but it never actually consumes that part of the string. Thanks again for the help!