Skip to content

How to create a parser for later reuse. #1840

Open
@CyanHillFox

Description

@CyanHillFox

We want to use nom to parse the streaming output text of the LLM, which contains a bunch of structured content. So we're trying to create a parser and save it for later reuse, because it is very often to match on streaming output.

But when I tried it, I ran into a problem. For example, the nom::branch::Choice<T> implements Parser only for T = &mut [A] / [A; N] / (A, B, ..), in which Vec<A> is not included. But in our use case, the tag_names is not fixed. So we tried passing the Vec to nom::branch::alt, but the result Choice doesn't implement Parser, if we pass the reference of Vec to nom::branch::alt, the result Choice will borrow the local variable tags.
The sample code:

use nom::Parser;
use nom::{self, IResult};

fn new_matcher<'a>(tag_names: &[&'static str],) -> impl Parser<&'a str, Output = &'a str, Error = nom::error::Error<&'a str>> {
    let mut tags: Vec<_> = tag_names
        .iter()
        .map(|tag_name: &&str| {
            nom::bytes::streaming::tag::<&str, &'a str, nom::error::Error<&'a str>>(*tag_name)
        })
        .collect();
    // wrong because all_tag_name will borrow local variable
    let all_tag_name = nom::branch::alt(tags.as_mut());
    // wrong because the result Choice doesn't implement nom Parser
    // let all_tag_name = nom::branch::alt(tags);
    all_tag_name
}

I'm wondering what the correctway to create and save a nom Parser for later use.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions