-
-
Notifications
You must be signed in to change notification settings - Fork 157
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
Documentation request: State and Context #534
Comments
'State' is just a mutable value that gets carried around during parsing. It can contain arbitrary data and can be whatever you like: common choices include string interners and arena allocators (or both! Just make a struct containing both of them). There are good examples of both in the doc examples of Context is different: it's some information passed from a parser earlier in the input to one later in the input that changes how the latter behaves. For example, an indentation-sensitive parser might pass the indentation level from the first indentation parser to all of the trailing indentation in a block, allowing it to properly parse indentation (despite this usually being a context-sensitive thing that recursive descent parsers struggle with). Here's an example of this. Hopefully I'll get the time to write up proper long-form guides for both of these soon. |
Btw, I think there's a typo in the documentation for ignore_with_ctx. It should probably say "if you do" Line 1098 in af4e2b1
|
Yep, you're right. I think this was due to the combinator roles being switched at one point. |
For when you're going to write up a guide, here are a few questions that I personally have:
use chumsky::{extra, prelude::EmptyErr, text, IterParser, Parser};
#[derive(Clone, Debug, Default)]
struct TestContext {
value: char,
}
#[test]
fn test_chumsky_recursive_context() {
let number = text::digits::<char, &str, extra::Full<EmptyErr, (), TestContext>>(10)
.exactly(1)
.collect::<Vec<_>>()
.map_with_ctx(|result, ctx| {
println!("result: {:?}, ctx: {:?}", result, ctx);
if ctx.value == result[0] {
Some(result[0])
} else {
None
}
})
.boxed();
assert_eq!(
number
.with_ctx(TestContext { value: '1' })
.parse("1")
.into_output(),
Some(Some('1'))
);
}
|
There is a
Context is local to a section of the parser tree. When using |
If you imagine a parser as a tree with ordered children, context is 'created' by a node, and can only be used by nodes that share the same parent and come after the creator, and children of those nodes. It flows 'forwards and down', which is the opposite of most parse results, which flow 'backwards and up' from where they are generated until they are returned as output at the top of the tree. |
I see. Apparently I'm running into the same type inference issue in both cases. The piece of code above should demonstrate the problem. For example:
Without an explanation, my default assumption was "I'm doing something wrong". But I'm glad to see that
Ah, I see. Thank you! |
Oh hmm, looks like we need to thread |
If you hitch yourself up to the latest commit, it should work fine without the explicit type parameter now. |
Woah, |
@stefnotch @zesterer Seems to me like this is solved. Objections to closing it? |
I'll close it in favour of the more general 'improve the docs' point in #543. |
I tried looking up "state" and "context" again in the Chumsky documentation, and not all of the results link to a clear description/example. For example, state and context are referenced here, but I can't see a straightforward way of answering the questions
https://docs.rs/chumsky/1.0.0-alpha.7/chumsky/input/struct.InputRef.html#method.state For most things in Chumsky's documentation, I can click on the relevant traits or structs and get a centralised description. Feel free to roll this issue into the general "improve docs" issue. Hopefully I properly explained what I'm looking for? |
Chumsky has a concept of a state and context. And quite a few combinators that do things with them. And a
map_ctx
standalone function.I personally never quite managed to wrap my head around that featureset. What is it intended to be used for, and how does one work with it?
e.g. How do I take an existing context, and change it into a new type of context?
The text was updated successfully, but these errors were encountered: