Skip to content

Conversation

@91khr
Copy link

@91khr 91khr commented Feb 21, 2025

Closes #630, which first mentioned something like this.

This can be used in syntaxes like Rust's let statement, which has an optional type notation:

let a = 0;
let b: i32 = 0;

.then(...).or_not() doesn't work well in such cases, because when there's a parse error in the type, or_not would just suppress it and return None, leaving the following parsers confusing, or even worse, mistakenly starting parsing from the wrong position. In this particular example, when the type has an error, the parser may complain something like expected '=', got ':', rather than pointing out the error in the type.

With then_or_not, Rust's let statement can roughly be parsed with:

let let_stmt = group((
        just("let").padded(),
        pattern,
        just(':').padded().then_or_not(rust_type),
        just('=').padded().then_or_not(expr),
    ))
    .map(|(_, pat, ty, val)| Stmt::Let(pat, ty.map(|t| t.1), val.map(|v| v.1)));

And this would correctly report the errors in rust_type and expr.

@zesterer
Copy link
Owner

zesterer commented Feb 23, 2025

.then(...).or_not() doesn't work well in such cases, because when there's a parse error in the type, or_not would just suppress it and return None, leaving the following parsers confusing, or even worse, mistakenly starting parsing from the wrong position

I'm not sure I follow this logic. Optional type annotations can be expressed perfectly well (I've been doing so in my own lang for years) with the following

let pat = ... ; // Pattern
let ty = ... ;// Type annotation

text::keyword("let").padded()
    .ignore_then(pat)
    .then(just(":").padded().ignore_then(ty).or_not())
    .then_ignore(just("=").padded())
    .then(...)

Chumsky doesn't get confused by this, and the fact that the error is suppressed when parsing fails is not a problem: chumsky will still remember that the error could have been hit and will make use of that information when generating the final syntax error.

@zesterer
Copy link
Owner

zesterer commented Apr 6, 2025

Is this still an API hole for you, or is my suggested solution sufficient?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Combine then and or_not preventing extraneous backtracking

2 participants