Skip to content

fix(parser): notify listeners for fatal entry errors - #234

Merged
tinovyatkin merged 1 commit into
mainfrom
fix/issue-200-error-listeners
Jul 27, 2026
Merged

fix(parser): notify listeners for fatal entry errors#234
tinovyatkin merged 1 commit into
mainfrom
fix/issue-200-error-listeners

Conversation

@tinovyatkin

@tinovyatkin tinovyatkin commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • notify registered parser error listeners when a committed public entry-rule parse returns an unrecovered ParserError
  • preserve the offending token and original AntlrError, while keeping nested and speculative failures silent
  • distinguish adaptive interpreted fallback errors from generated fatal errors so recovery cannot report the same syntax error twice
  • retain earlier committed recovery diagnostics and syntax-error counts when a later outer decision fails fatally
  • drain retained diagnostics before semantic-hook or parser-abort overrides so failed entries cannot leak diagnostics into parser reuse
  • update the conformance smoke harness to rely on recognizer listener output and refresh the self-hosted parser artifact

Root cause

Parser diagnostics were dispatched after successful interpreted parses and committed generated recovery. A fatal entry-rule Err bypassed both paths, so listener-driven consumers received no syntax error even though ANTLR calls notifyErrorListeners before recovery is attempted.

The generated fatal unwind also restored the entry checkpoint wholesale. If a child rule had already recovered and committed a diagnostic, a later outer fatal error erased that diagnostic and its syntax-error count. Fatal entries now roll back only partial tree state, drain all committed generated diagnostics before any semantic-hook or parser-abort override can return, and then report the final parser error when it remains authoritative.

Validation

  • cargo fmt --all -- --check
  • cargo clippy --locked --all-targets --all-features -- -D warnings
  • cargo test --locked --all-features --workspace
  • cargo run --release --quiet --bin antlr4-runtime-testsuite (357 passed, 0 failed, 0 skipped)
  • tools/grammar-frontend/update-stage0.sh --check

Fixes #200

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@tinovyatkin, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 30 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e2d29b2a-8b73-4a7e-9835-583ad9c37c3f

📥 Commits

Reviewing files that changed from the base of the PR and between d89c988 and 774959a.

⛔ Files ignored due to path filters (4)
  • src/bin_support/grammar/generated/antlr_v4_parser.rs is excluded by !**/generated/**
  • src/snapshots/antlr4_runtime__parser__tests__failed_interpreted_parse_notifies_error_listener.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__fatal_entry_preserves_prior_recovery_diagnostics.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__semantic_override_does_not_leak_prior_recovery_diagnostics.snap is excluded by !**/*.snap
📒 Files selected for processing (5)
  • src/bin/antlr4-runtime-testsuite.rs
  • src/bin/antlr4-rust-gen.rs
  • src/parser.rs
  • tests/antlr4_rust_gen_cli.rs
  • third_party/antlr-v4-grammar/self-hosted.sha256
📝 Walkthrough

Walkthrough

Changes

The parser now notifies error listeners for committed unrecovered entry-rule failures. Generated parsers distinguish interpreted fallback errors from fatal errors, roll back partial trees, report fatal errors conditionally, and return converted errors once. Tests and generated grammar checks were updated.

Changes

Parser error reporting

Layer / File(s) Summary
Top-level parser error notification
src/parser.rs
BaseParser detects top-level failures, preserves committed diagnostics during generated-tree rollback, resolves offending tokens, and notifies listeners for unrecovered generated and interpreted errors.
Generated error classification and reporting
src/bin/antlr4-rust-gen.rs
Generated error variants, fallback mapping, tree rollback, fatal reporting, and one-time error conversion are updated.
Generated and runtime regression coverage
src/parser.rs, src/bin/antlr4-rust-gen.rs, tests/antlr4_rust_gen_cli.rs, src/bin/antlr4-runtime-testsuite.rs, third_party/antlr-v4-grammar/self-hosted.sha256
Tests verify listener notification and non-duplication; generated-output expectations, smoke handling, and the recorded grammar checksum are updated.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GeneratedParser
  participant BaseParser
  participant TokenStore
  participant ErrorListener
  GeneratedParser->>BaseParser: report_unrecovered_parser_error(error)
  BaseParser->>TokenStore: resolve offending token
  BaseParser->>ErrorListener: notify syntax error
  GeneratedParser-->>GeneratedParser: return converted fatal error
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The parser now reports unrecovered top-level ParserErrors once, while speculative and nested errors stay silent, matching the issue requirements.
Out of Scope Changes check ✅ Passed The test harness and checksum updates appear ancillary to the parser-error fix and do not look unrelated to the linked issue.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: notifying listeners for fatal entry parser errors.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-200-error-listeners

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

Copy/Paste Detection

Found 60 duplication(s) across 5 changed Rust file(s) (threshold: 100 tokens).

Show duplications

Found a 44 line (264 tokens) duplication in the following files:

  • Starting at line 15383 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16478 of src/bin_support/grammar/generated/antlr_v4_parser.rs
                                let __child = self.parse_generated_rule_38_dispatch(0, false).map_err(GeneratedRuleError::into_error);
                                self.base.discard_invoking_state(__invoking_marker);
                                let __child = __child?;
                                self.base.add_parse_child(&mut __ctx, __child);
                            }
                            2 => {
                                break;
                            }
                            _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
                        }
                    }
                }
                2 => {
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_38_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 40 line (257 tokens) duplication in the following files:
* Starting at line 16796 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 19070 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                            let __child = self.parse_generated_rule_47_dispatch(0, false).map_err(GeneratedRuleError::into_error);
                            self.base.discard_invoking_state(__invoking_marker);
                            let __child = __child?;
                            self.base.add_parse_child(&mut __ctx, __child);
                        }
                        2 => {
                        }
                        _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
                    }
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_47_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {

Found a 39 line (254 tokens) duplication in the following files:

  • Starting at line 15648 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17625 of src/bin_support/grammar/generated/antlr_v4_parser.rs
                            let __match = self.base.match_token_recovering(63, 416, atn())?;
                            __consumed_eof |= __match.consumed_eof();
                            for __child in __match.into_child_iter() { self.base.add_parse_child(&mut __ctx, __child); }
                        }
                        2 => {
                        }
                        _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
                    }
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_39_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 37 line (250 tokens) duplication in the following files:
* Starting at line 17091 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 19365 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                            let __match = self.base.match_token_recovering(11, 505, atn())?;
                            __consumed_eof |= __match.consumed_eof();
                            for __child in __match.into_child_iter() { self.base.add_parse_child(&mut __ctx, __child); }
                        }
                        _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
                    }
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_49_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {

Found a 38 line (248 tokens) duplication in the following files:

  • Starting at line 17999 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 18806 of src/bin_support/grammar/generated/antlr_v4_parser.rs
                    let __invoking_marker = self.base.push_invoking_state(549isize);
                    let __child = self.parse_generated_rule_63_dispatch(0, false).map_err(GeneratedRuleError::into_error);
                    self.base.discard_invoking_state(__invoking_marker);
                    let __child = __child?;
                    self.base.add_parse_child(&mut __ctx, __child);
                }
                2 => {
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_56_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 36 line (244 tokens) duplication in the following files:
* Starting at line 17768 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17897 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                    let __invoking_marker = self.base.push_invoking_state(539isize);
                    let __child = self.parse_generated_rule_55_dispatch(0, false).map_err(GeneratedRuleError::into_error);
                    self.base.discard_invoking_state(__invoking_marker);
                    let __child = __child?;
                    self.base.add_parse_child(&mut __ctx, __child);
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_54_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {

Found a 39 line (243 tokens) duplication in the following files:

  • Starting at line 13022 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13128 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14175 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14415 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14645 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15087 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15830 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16283 of src/bin_support/grammar/generated/antlr_v4_parser.rs
                        let __child = self.parse_generated_rule_33_dispatch(0, false).map_err(GeneratedRuleError::into_error);
                        self.base.discard_invoking_state(__invoking_marker);
                        let __child = __child?;
                        self.base.add_parse_child(&mut __ctx, __child);
                    }
                    2 => {
                        break;
                    }
                    _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
                }
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_17_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 37 line (240 tokens) duplication in the following files:
* Starting at line 13756 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 14756 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17318 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 18000 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 18807 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                    let __child = self.parse_generated_rule_22_dispatch(0, false).map_err(GeneratedRuleError::into_error);
                    self.base.discard_invoking_state(__invoking_marker);
                    let __child = __child?;
                    self.base.add_parse_child(&mut __ctx, __child);
                }
                2 => {
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_21_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {

Found a 35 line (236 tokens) duplication in the following files:

  • Starting at line 11553 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12149 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13245 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14000 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15951 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17214 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17769 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17898 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 18114 of src/bin_support/grammar/generated/antlr_v4_parser.rs
                    let __child = self.parse_generated_rule_12_dispatch(0, false).map_err(GeneratedRuleError::into_error);
                    self.base.discard_invoking_state(__invoking_marker);
                    let __child = __child?;
                    self.base.add_parse_child(&mut __ctx, __child);
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_4_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 36 line (235 tokens) duplication in the following files:
* Starting at line 13022 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 19534 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                        let __child = self.parse_generated_rule_33_dispatch(0, false).map_err(GeneratedRuleError::into_error);
                        self.base.discard_invoking_state(__invoking_marker);
                        let __child = __child?;
                        self.base.add_parse_child(&mut __ctx, __child);
                    }
                    2 => {
                        break;
                    }
                    _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
                }
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

Found a 34 line (233 tokens) duplication in the following files:

  • Starting at line 11417 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 11916 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12757 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16063 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16174 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 18450 of src/bin_support/grammar/generated/antlr_v4_parser.rs
                    let __match = self.base.match_token_recovering(43, 160, atn())?;
                    __consumed_eof |= __match.consumed_eof();
                    for __child in __match.into_child_iter() { self.base.add_parse_child(&mut __ctx, __child); }
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_3_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 33 line (227 tokens) duplication in the following files:
* Starting at line 12641 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 13827 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 13889 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 14310 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
            let __invoking_marker = self.base.push_invoking_state(244isize);
            let __child = self.parse_generated_rule_14_dispatch(0, false).map_err(GeneratedRuleError::into_error);
            self.base.discard_invoking_state(__invoking_marker);
            let __child = __child?;
            self.base.add_parse_child(&mut __ctx, __child);
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_13_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {

Found a 33 line (227 tokens) duplication in the following files:

  • Starting at line 14064 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14243 of src/bin_support/grammar/generated/antlr_v4_parser.rs
            let __invoking_marker = self.base.push_invoking_state(329isize);
            let __child = self.parse_generated_rule_15_dispatch(0, false).map_err(GeneratedRuleError::into_error);
            self.base.discard_invoking_state(__invoking_marker);
            let __child = __child?;
            self.base.add_parse_child(&mut __ctx, __child);
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_25_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 40 line (221 tokens) duplication in the following files:
* Starting at line 795 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 945 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 1087 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 1227 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 1376 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 1519 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 1661 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 1807 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 1950 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 2083 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 2224 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 2365 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 2496 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 2648 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 2787 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 2917 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 3056 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 3202 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 3330 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 3464 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 3647 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 3780 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 3922 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 4058 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 4192 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 4328 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 4465 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 4601 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 4743 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 4871 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 5015 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 5145 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 5276 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 5416 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 5574 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 5704 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 5835 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 5969 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 6097 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 6246 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 6388 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 6525 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 6670 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 6804 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 6938 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 7069 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 7202 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 7361 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 7504 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 7658 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 7808 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 7943 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 8073 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 8210 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 8364 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 8508 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 8643 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 8783 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 8926 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 9075 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 9231 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 9371 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 9504 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 9643 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 9786 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 9935 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 10069 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
impl<'a> GrammarSpecContext<'a> {
    fn __from_node(node: RuleNodeView<'a>) -> Self {
        Self::__from_node_with_invocation_states(node, None)
    }

    fn __from_child_node(
        node: RuleNodeView<'a>,
        parent_invocation_states: Option<&[isize]>,
    ) -> Self {
        let invocation_states = parent_invocation_states.map(|states| {
            let mut invocation_states = Vec::with_capacity(states.len() + 1);
            invocation_states.push(node.invoking_state());
            invocation_states.extend_from_slice(states);
            invocation_states
        });
        Self::__from_node_with_invocation_states(node, invocation_states)
    }

    fn __from_listener_node(node: RuleNodeView<'a>, invocation_states: Option<&[isize]>) -> Self {
        Self::__from_node_with_invocation_states(
            node,
            invocation_states.map(|states| states.to_vec()),
        )
    }

    fn __from_node_with_invocation_states(
        node: RuleNodeView<'a>,
        invocation_states: Option<Vec<isize>>,
    ) -> Self {
        Self {
            __node: __GeneratedRuleContext::Stored(node),
            __invocation_states: invocation_states,
            __state: std::marker::PhantomData,
        }
    }

}

#[allow(dead_code, clippy::all)]
impl<'a, State> GrammarSpecContext<'a, State> {

Found a 32 line (219 tokens) duplication in the following files:

  • Starting at line 11738 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12642 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13608 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13828 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13890 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14065 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14244 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14311 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14538 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14980 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17382 of src/bin_support/grammar/generated/antlr_v4_parser.rs
            let __child = self.parse_generated_rule_6_dispatch(0, false).map_err(GeneratedRuleError::into_error);
            self.base.discard_invoking_state(__invoking_marker);
            let __child = __child?;
            self.base.add_parse_child(&mut __ctx, __child);
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_6_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 31 line (216 tokens) duplication in the following files:
* Starting at line 11232 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 11299 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 11672 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12039 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12260 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12367 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12817 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12913 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 14480 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 14922 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15721 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16925 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 18238 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 18662 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 18876 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 19199 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 19428 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
            let __match = self.base.match_token_recovering(-1, 149, atn())?;
            __consumed_eof |= __match.consumed_eof();
            for __child in __match.into_child_iter() { self.base.add_parse_child(&mut __ctx, __child); }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_1_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {

Found a 36 line (216 tokens) duplication in the following files:

  • Starting at line 15651 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16800 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17628 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 19074 of src/bin_support/grammar/generated/antlr_v4_parser.rs
                        }
                        2 => {
                        }
                        _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
                    }
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_39_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 34 line (212 tokens) duplication in the following files:
* Starting at line 15653 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17094 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17630 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 19076 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 19368 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                        }
                        _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
                    }
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_39_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {

Found a 34 line (212 tokens) duplication in the following files:

  • Starting at line 16802 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17094 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 19368 of src/bin_support/grammar/generated/antlr_v4_parser.rs
                        }
                        _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
                    }
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_47_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 34 line (200 tokens) duplication in the following files:
* Starting at line 12523 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15240 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15393 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16488 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                    for __child in __match.into_child_iter() { self.base.add_parse_child(&mut __ctx, __child); }
                }
                2 => {
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_12_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {

Found a 33 line (199 tokens) duplication in the following files:

  • Starting at line 12524 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13760 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14760 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15241 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15394 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16489 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17322 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 18004 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 18811 of src/bin_support/grammar/generated/antlr_v4_parser.rs
                }
                2 => {
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_12_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 32 line (196 tokens) duplication in the following files:
* Starting at line 11419 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15655 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16065 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16176 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16804 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17096 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17632 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 18452 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 19078 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 19370 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                    for __child in __match.into_child_iter() { self.base.add_parse_child(&mut __ctx, __child); }
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_3_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {

Found a 32 line (196 tokens) duplication in the following files:

  • Starting at line 11918 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15655 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16804 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17096 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17632 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 19078 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 19370 of src/bin_support/grammar/generated/antlr_v4_parser.rs
                    for __child in __match.into_child_iter() { self.base.add_parse_child(&mut __ctx, __child); }
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_7_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
```rust

---

Found a 32 line (196 tokens) duplication in the following files:
* Starting at line 12759 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15655 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16804 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17096 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17632 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 19078 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 19370 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                    for __child in __match.into_child_iter() { self.base.add_parse_child(&mut __ctx, __child); }
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule_14_dispatch(&mut self, precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {

Found a 31 line (195 tokens) duplication in the following files:

  • Starting at line 11420 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 11557 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 11919 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12153 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12526 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12760 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13249 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13762 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14004 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14762 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15243 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15396 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15656 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15955 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16066 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16177 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16491 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16805 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17097 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17218 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17324 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17633 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17773 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17902 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 18006 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 18118 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 18453 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 18813 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 19079 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 19371 of src/bin_support/grammar/generated/antlr_v4_parser.rs
                }
                _ => return Err(self.base.no_viable_alternative_error(__decision_start)),
            }
            Ok(())
        })();
        match __result {
            Ok(()) => {
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
            Err(__error) => {
                if let Some(__error) = __sync_error {
                    if allow_fallback {
                        self.base.exit_rule();
                        self.base.rollback_generated_tree(__generated_diagnostic_marker);
                        self.base.record_generated_syntax_error();
                        return Err(GeneratedRuleError::Fatal(__error));
                    }
                    self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                    let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                    return Ok(__tree);
                }
                self.base.recover_generated_rule(&mut __ctx, atn(), __error);
                let __tree = self.base.finish_rule(__ctx, __consumed_eof);
                Ok(__tree)
            }
        }
    }

    #[allow(dead_code)]
    fn parse_ge

_(report truncated; full output in workflow logs)_

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

📊 Source Code Metrics (this PR vs main)

File Cyclomatic Cognitive Functions LLOC MI
src/parser.rs 2169 (main: 2162) 🔴 1423 (main: 1418) 🔴 699 (main: 696) 🔴 4704 (main: 4688) 🔴 0 ⚪
src/bin/antlr4-rust-gen.rs 2383 (main: 2381) 🔴 1486 ⚪ 536 (main: 535) 🔴 4189 (main: 4181) 🔴 0 ⚪

Generated by mehen v1.7.0 — the code quality watcher.

@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.18072% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/parser.rs 89.18% 4 Missing ⚠️

📢 Thoughts on this report? Let us know!

@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown

Claude Code review skipped — usage limit reached.

You've hit your weekly limit · resets Jul 29, 8pm (UTC) Re-run the workflow once the quota resets.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/parser.rs`:
- Around line 7231-7232: Extract the duplicated top-level-entry condition into a
private helper such as is_top_level_entry on the parser, documenting that it
identifies an empty rule-context and pending-invocation stack. Replace the
direct checks in parse_atn_rule_with_precedence_inner and
parse_atn_rule_with_runtime_options_and_precedence with calls to this helper,
preserving the existing listener-notification behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 448f2e01-4564-466c-82cd-747c3a6dd7ca

📥 Commits

Reviewing files that changed from the base of the PR and between 04afe85 and 00a5100.

⛔ Files ignored due to path filters (2)
  • src/bin_support/grammar/generated/antlr_v4_parser.rs is excluded by !**/generated/**
  • src/snapshots/antlr4_runtime__parser__tests__failed_interpreted_parse_notifies_error_listener.snap is excluded by !**/*.snap
📒 Files selected for processing (5)
  • src/bin/antlr4-runtime-testsuite.rs
  • src/bin/antlr4-rust-gen.rs
  • src/parser.rs
  • tests/antlr4_rust_gen_cli.rs
  • third_party/antlr-v4-grammar/self-hosted.sha256

Comment thread src/parser.rs Outdated
@tinovyatkin
tinovyatkin force-pushed the fix/issue-200-error-listeners branch from 00a5100 to 718195d Compare July 27, 2026 09:35

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 718195da85

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/bin/antlr4-rust-gen.rs
@tinovyatkin
tinovyatkin force-pushed the fix/issue-200-error-listeners branch from 718195d to d89c988 Compare July 27, 2026 10:06
@tinovyatkin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d89c9885ae

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/antlr4_rust_gen_cli.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs
@tinovyatkin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Dispatch committed ParserError values through registered error listeners at interpreted and generated public entry boundaries. Distinguish adaptive interpreted fallback errors from generated fatal errors so nested and speculative failures stay silent and recovery cannot notify twice.

At a generated fatal boundary, roll back only partial tree state while retaining prior committed recovery diagnostics and syntax-error counts. Drain retained diagnostics before semantic-hook or parser-abort overrides and before reporting the final parser error, preventing stale diagnostics from leaking into a reused parser.

Add direct-runtime and generated snapshot regressions, update the conformance harness to rely on listener output, and refresh the self-hosted parser artifacts.
@tinovyatkin
tinovyatkin force-pushed the fix/issue-200-error-listeners branch from d89c988 to 774959a Compare July 27, 2026 10:35
@tinovyatkin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@tinovyatkin
tinovyatkin merged commit 332251a into main Jul 27, 2026
14 checks passed
@tinovyatkin
tinovyatkin deleted the fix/issue-200-error-listeners branch July 27, 2026 11:01
@ophiarch ophiarch Bot mentioned this pull request Jul 27, 2026
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.

bug(parser): unrecovered entry-rule errors never reach ErrorListeners (ANTLR always notifies)

1 participant