Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility with VerboseError #36

Open
perlindgren opened this issue Sep 4, 2019 · 10 comments
Open

Compatibility with VerboseError #36

perlindgren opened this issue Sep 4, 2019 · 10 comments

Comments

@perlindgren
Copy link

perlindgren commented Sep 4, 2019

Hi fflorent and others.

Is there some example how to use nom_locate with the VerboseError type.

I tried changing the example.

fn parse_foobar(s: Span) -> IResult<Span, Token, VerboseError<&str>> {
    let (s, _) = take_until("foo")(s)?;
    let (s, pos) = position(s)?;
    let (s, foo) = tag("foo")(s)?;
    let (s, bar) = tag("baz")(s)?;

    Ok((
        s,
        Token {
            position: pos,
            foo: foo.fragment,
            bar: bar.fragment,
        },
    ))
}
fn parse_foobar(s: Span) -> IResult<Span, Token, VerboseError<&Span>> {
    let (s, _) = take_until("foo")(s)?;
    let (s, pos) = position(s)?;
    let (s, foo) = tag("foo")(s)?;
    let (s, bar) = tag("baz")(s)?; // just to trigger the error

    Ok((
        s,
        Token {
            position: pos,
            foo: foo.fragment,
            bar: bar.fragment,
        },
    ))
}

as well as:

fn parse_foobar(s: Span) -> IResult<Span, Token, VerboseError<&Span>> {
     ...
}

(The latter perhaps makes no sense...).

In both cases I end up with missing trait implementations, so I wonder if I made some stupid mistake, or that there is a compatibility issue?

(By the way, I use the latest released versions of both nom and nom_locate.)

Best regards
Per

@progval
Copy link
Collaborator

progval commented Sep 4, 2019

Hi,

I didn't use verbose errors with nom 5 yet, but it looks like this is not related to nom_locate. Individual parser functions are not supposed to override the error type, it's chosen by the caller of the parsers, which will generate specialized code for all the parser functions. See https://github.com/Geal/nom/blob/master/doc/error_management.md

@Lythenas
Copy link

I'm using:

pub type Input<'i> = LocatedSpanEx<&'i str, ()>;
pub type PResult<'i, O> = IResult<Input<'i>, O, VerboseError<Input<'i>>>;

and this works for writing parsers. But I can't use the convert_error function of nom because that only accepts &str. I'm not sure if this can be generalized in nom or if this library needs its own convert_error.

@progval
Copy link
Collaborator

progval commented Nov 12, 2019

Indeed. I wonder why nom implemented it only for &str instead of ToStr or something. ping @Geal

@sunjay
Copy link

sunjay commented Dec 26, 2019

Could a new version of this crate be released? 7eb8155 fixes this issue but it's only on master, not on crates.io yet.

@kaj
Copy link

kaj commented Mar 23, 2020

v2.0.0 is released since the previous comment. Maybe this issue can be closed?

@chipsenkbeil
Copy link

To my knowledge, convert_error is still only for &str, which means it cannot be used with a span. There's an open PR for nom to enable AsStr support: rust-bakery/nom#1050 Separately, there was an issue opened for just this scenario, but didn't receive a response: rust-bakery/nom#1149

@Geal
Copy link

Geal commented Aug 30, 2020

hello, I just change convert_error to require Deref<Target=str> on the input type, that should be easy enough to support with nom_locate?

@Geal
Copy link

Geal commented Aug 30, 2020

although I think a different approach would be needed, since convert_error wants to count lines, while nom_locate already provides the position

@progval progval reopened this Aug 30, 2020
@simon-bourne
Copy link

This still isn't working as LocatedSpan<T, X> is Deref<Target = T>, so LocatedSpan<&str> is Deref<Target=&str> (note that target is an &str, not a str). As a workaround, I'm successfully using:

let errors = e
    .errors
    .into_iter()
    .map(|(input, error)| (*input.fragment(), error))
    .collect();

convert_error(input.as_str(), VerboseError { errors })

@rassvet2
Copy link

rassvet2 commented Oct 14, 2022

Hello. I also tried to use convert_error and LocatedSpan together and failed.
How about this?

impl<T: Deref, X> Deref for LocatedSpan<T, X> {
    type Target = <T as Deref>::Target;
    fn deref(&self) -> &Self::Target {
        &self.fragment.deref()
    }
}

I haven't thought it through, but it should work. I'll try it in my code after this.

PS: I tried it, but it makes the code less cleanly written. I had to rewrite my code where I used *span to get &str with &*span or span.fragment().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants