Skip to content

Conversation

@rlch
Copy link

@rlch rlch commented Nov 26, 2025

Implements error recovery inspired by Chumsky's recovery system in Rust, addressing GitHub issue #342.

Features:

  • RecoveryStrategy interface with multiple implementations:
    • SkipUntil/SkipPast: classic panic-mode recovery
    • SkipThenRetryUntil: skip and retry parsing
    • NestedDelimiters: balanced delimiter recovery
    • TokenSyncStrategy: sync on token types
    • CompositeStrategy: try multiple strategies in order
  • RecoveryError type for multi-error reporting
  • ParseOptions: Recover(strategies...) and MaxRecoveryErrors(n)

The implementation allows parsers to continue after errors, collecting
multiple errors and producing partial ASTs - useful for IDE integration,
linters, and comprehensive error messages.

Includes comprehensive test coverage (100% on new code) and example at
_examples/recovery/.

rlch and others added 2 commits November 26, 2025 20:26
Implements error recovery inspired by Chumsky's recovery system in Rust,
addressing GitHub issue alecthomas#342.

New features:
- RecoveryStrategy interface with multiple implementations:
  - SkipUntil/SkipPast: classic panic-mode recovery
  - SkipThenRetryUntil: skip and retry parsing
  - NestedDelimiters: balanced delimiter recovery
  - TokenSyncStrategy: sync on token types
  - CompositeStrategy: try multiple strategies in order
- RecoveryError type for multi-error reporting
- ParseOptions: Recover(strategies...) and MaxRecoveryErrors(n)

Integration points:
- parseContext with tryRecover(), recoveryEnabled(), addRecoveryError()
- Recovery hooks in strct.Parse and group.Parse (nodes.go)
- Error aggregation in parser.go

The implementation allows parsers to continue after errors, collecting
multiple errors and producing partial ASTs - useful for IDE integration,
linters, and comprehensive error messages.

Includes comprehensive test coverage (100% on new code) and example at
_examples/recovery/.

Amp-Thread-ID: https://ampcode.com/threads/T-b95d5ac9-6023-4947-a477-53364956f203
Co-authored-by: Amp <[email protected]>
Extends the error recovery system with Chumsky-inspired features:

Per-Node Recovery (via struct tags):
- Add 'recover' struct tag for per-field recovery strategies
- Syntax: \`parser:"@Ident" recover:"skip_until(;)"\`
- Supports: skip_until(), skip_past(), nested(), retry_until()
- Multiple strategies via pipe: \`recover:"nested((,))|skip_until(;)"\`
- Labels for error messages: \`recover:"label:expression|skip_until(;)"\`

Recovery Metadata Fields:
- Recovered bool - set to true when struct was recovered
- RecoveredSpan lexer.Position - position where recovery started
- Auto-injected like Pos/EndPos fields

Implementation:
- recoveryNode wrapper applies recovery to any node
- Handles both errors AND 'no match' cases (nil, nil)
- Creates meaningful error messages for recovery reporting
- Updated visit.go, ebnf.go for recoveryNode support

This brings participle closer to Chumsky's recovery capabilities,
enabling fine-grained recovery control per grammar rule.

Amp-Thread-ID: https://ampcode.com/threads/T-b95d5ac9-6023-4947-a477-53364956f203
Co-authored-by: Amp <[email protected]>
Copy link
Owner

@alecthomas alecthomas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome! I'll try to take a comprehensive look on the weekend.

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.

2 participants