combine icon indicating copy to clipboard operation
combine copied to clipboard

Where is State?

Open dave-doty opened this issue 1 year ago • 5 comments

I'm trying the tutorial. The very first code snippet fails for me.

use combine::parser::range::{range, take_while1};
use combine::parser::repeat::{sep_by};
use combine::parser::Parser;
use combine::stream::{state::State, RangeStream};
use combine::error::ParseError;
use combine::EasyParser; // I added this line because otherwise the line calling `easy_parse` fails.
 
// Copy the fn header as is, only change ------------╮
//                                                   v
fn tools<'a, I>() -> impl Parser<I, Output = Vec<&'a str>>
    where I: RangeStream<Token = char, Range=&'a str>,
          I::Error: ParseError<I::Token, I::Range, I::Position>,
{
    let tool = take_while1(|c : char| c.is_alphabetic());
    sep_by(tool, range(", "))
}

fn decode(input : &str) -> Result<Vec<&str>, String> {
    match tools().easy_parse(State::new(input)) {
        Ok((output, _remaining_input)) => Ok(output),
        Err(err) => Err(format!("{} in `{}`", err, input)),
    }
}

fn main() {
    let input = "Hammer, Saw, Drill";
    let output = decode(input).unwrap();
    println!("{:?}", output);
}

It can't fine combine::stream::state::State:

error[E0432]: unresolved import `combine::stream::state::State`
 --> src/main.rs:6:23
  |
6 | use combine::stream::{state::State, RangeStream};
  |                       ^^^^^^^^^^^^ no `State` in `stream::state`

Also, the tutorial says

The only real difference is, that I wrapped the input with a State which adds line and column information to the parser errors.

But if you click on that link to State you see this:

image

I imagine the explanation is that State got renamed or moved, but I've scoured the source code and cannot find what it could be referring to.

The state subcrate only has one struct, Stream, but it has no new constructor, so I don't think that it simply got renamed.

dave-doty avatar Aug 17 '24 20:08 dave-doty

I think I have a clue. The State struct appears to have been dropped when going from version 3 to version 4:

https://docs.rs/combine/3.8.1/combine/stream/state/index.html https://docs.rs/combine/4.0.1/combine/stream/state/index.html

However, this was not listed as a breaking change in the changelog. Also that was 5 years ago, so it seems the tutorial is very outdated to still reference State.

I would appreciate any guidance as to what is the current recommended method for obtaining more contextual error messages with line and column numbers. Of course I'm not sure what used to happen because the tutorial does not show what errors would have looked like, so I'm not sure if I actually want whatever it is that State did.

dave-doty avatar Aug 18 '24 16:08 dave-doty

Yes the tutorial was not updated for v4 (it was contributed by someone else and I honestly forgot about it since), added a note that it is for a previous version.

What you are looking for is https://docs.rs/combine/latest/combine/stream/position/index.html and you can see an example use of it in the main page of the rustdocs https://docs.rs/combine/latest/combine/index.html#overview .

Basically to go zero-cost for everything the position tracking was made opt-in for v4, not even indices are tracked by default since those can be calculated on demand after parsing https://docs.rs/combine/latest/combine/stream/struct.PointerOffset.html#method.translate_position. For any first time use just sticking to easy_parse and wrapping with https://docs.rs/combine/latest/combine/stream/position/struct.Stream.html#method.new is the way to go.

Marwes avatar Aug 21 '24 08:08 Marwes

I might be getting this slightly mixed up, but I think the only difference you encountered here is that state::State in 3.x was renamed to position::Stream (since the state module now contains a wrapper where you can include arbitrary state). It should have been in the changelog but I think it wasn't picked up because i didn't type anything below BREAKING CHANGE in this commit https://github.com/Marwes/combine/commit/e83699a1fba710849f97aaaac388cdedeca7d517

Marwes avatar Aug 21 '24 08:08 Marwes

Yes the tutorial was not updated for v4 (it was contributed by someone else and I honestly forgot about it since), added a note that it is for a previous version.

I found the tutorial on this site: https://github.com/Marwes/combine/wiki

If that website is not up-to-date, where is the "official" documentation? Is it just the API, or is there a similar document that explains the concepts and examples?

Thanks.

dave-doty avatar Aug 27 '24 15:08 dave-doty

The examples in the crate and the rust docs are up to date and there is a short "tutorial" in https://docs.rs/combine/latest/combine/index.html . The pages on the wiki are still mostly correct, there weren't that many changes from combine 3 so at least the broader concepts will be the same.

Marwes avatar Aug 28 '24 10:08 Marwes