Skip to content

feat: add typed listeners, visitors, and traversal - #165

Merged
tinovyatkin merged 7 commits into
mainfrom
feature/issue-138-typed-traversal
Jul 23, 2026
Merged

feat: add typed listeners, visitors, and traversal#165
tinovyatkin merged 7 commits into
mainfrom
feature/issue-138-typed-traversal

Conversation

@tinovyatkin

@tinovyatkin tinovyatkin commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Closes #138

Summary

  • Generate grammar-typed listeners and tree walkers by default, with opt-in typed visitors through --visitor.
  • Propagate listener-defined errors from every typed callback and expose enter_every_rule / exit_every_rule.
  • Remove the visitor Result: Default constraint in favor of an explicit default_result() contract.
  • Generate Rust-shaped child accessors from grammar cardinality: required children return Result<_, MissingChildError>, optional children return Option<_>, and repeated children return lazy iterators.
  • Preserve grammar labels as named accessors while emitting snake_case _token / _tokens methods instead of Java-style uppercase, indexed, or _all() getters.
  • Separate active parser contexts from stored tree contexts with type state so stored contexts expose a total rule_node().
  • Regenerate the checked-in ANTLRv4 parser and dogfood the fallible typed listener in the grammar frontend CST traversal.

Why

The runtime previously had only untyped traversal in normal generated parsers. Its partial typed surface was confined to the embedded conformance path and reflected Java accessor conventions. This promotes typed traversal to the standard direct-.g4 generator and makes the generated API idiomatic for Rust consumers.

Validation

  • cargo clippy --locked --all-targets --all-features -- -D warnings
  • cargo test --locked --all-targets --all-features (262 runtime tests, 595 generator tests, and 22 CLI tests)
  • tools/grammar-frontend/update-stage0.sh --check (Stage 1 and Stage 2 byte-identical)
  • shasum -a 256 -c third_party/antlr-v4-grammar/self-hosted.sha256
  • Full upstream ANTLR runtime conformance sweep (357 passed, 0 failed, 0 skipped)

Summary by CodeRabbit

  • New Features

    • Added configurable typed listener and visitor generation through command-line options.
    • Added typed tree visitors with result aggregation, early stopping, and deep-tree traversal support.
    • Added cardinality-aware child and token accessors, including optional, required, and iterator-based access.
    • Added public APIs for converting rule nodes and reporting missing children.
    • Improved parser handling of context-specific alternatives.
  • Documentation

    • Added comprehensive guidance for typed listeners, visitors, callbacks, accessors, and generation options.

Copilot AI review requested due to automatic review settings July 23, 2026 00:42
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds typed listener and visitor generation, cardinality-aware context accessors, context alternative-number tracking, typed CST construction, and expanded generated-code tests and documentation.

Changes

Typed runtime and context generation

Layer / File(s) Summary
Parse-tree storage, context alternatives, and visitor runtime
src/tree.rs, src/lib.rs
Parse-tree storage tracks context alternative numbers; public rule-node conversion and missing-child APIs are added; ParseTreeVisitor becomes a value-returning, aggregating traversal API.
Parser runtime context alternative tracking
src/parser.rs
Runtime options, recognition boundaries, folding, and tree materialization preserve context alternative numbers independently from ordinary alternative numbers.
Embedded cardinality and iterator accessors
src/bin_support/embedded.rs
Child cardinality and accessor stability are modeled, and embedded action references use lazy _children() and token iterators.
Generator flags and typed context emission
src/bin/antlr4-rust-gen.rs
Listener and visitor CLI flags flow through rendering; structural analysis emits cardinality-aware context views, alternative dispatch, and optional listener/visitor bridges.
Typed grammar frontend CST construction
src/bin_support/grammar/frontend.rs
CST construction uses a typed ANTLRv4 listener with rule-order and tree-structure validation.
Conformance templates and documentation
.conformance-review/*, README.md
Generated listener callbacks become fallible, child access uses cardinality-aware iterators and getters, and listener, visitor, walker, and downcast contracts are documented.
Generated-code validation and fixtures
tests/antlr4_rust_gen_cli.rs, tests/fixtures/antlr4-rust-gen/*, third_party/antlr-v4-grammar/self-hosted.sha256
Tests execute generated typed parser behavior, verify generation flags, add visitor and accessor fixtures, update grammar cases, and refresh the generated-parser checksum.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Generator
  participant GeneratedParser
  participant ParseTree
  participant Walker
  CLI->>Generator: pass listener and visitor options
  Generator->>GeneratedParser: emit typed contexts and traversal APIs
  GeneratedParser->>ParseTree: record context alternative numbers
  GeneratedParser->>Walker: provide generated parse tree
  Walker->>GeneratedParser: invoke fallible listener callbacks
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR adds opt-in --visitor generation and the supporting typed traversal APIs requested by #138.
Out of Scope Changes check ✅ Passed The remaining changes appear to support the visitor/listener/traversal overhaul rather than introduce unrelated scope.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding typed listeners, visitors, and traversal.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/issue-138-typed-traversal

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.

@tinovyatkin

Copy link
Copy Markdown
Contributor Author

@codex review

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@tinovyatkin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 23, 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.

@claude

claude Bot commented Jul 23, 2026

Copy link
Copy Markdown

Claude encountered an error —— View job


I'll analyze this and get back to you.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

Copy/Paste Detection

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

Show duplications

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

  • Starting at line 13437 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14436 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.restore_generated_diagnostics(__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 14742 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16824 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.restore_generated_diagnostics(__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 13690 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15499 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.restore_generated_diagnostics(__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 15013 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17095 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.restore_generated_diagnostics(__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 15837 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16584 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.restore_generated_diagnostics(__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 15630 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15747 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.restore_generated_diagnostics(__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 11328 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 11422 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12373 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12577 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12771 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13165 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13848 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14253 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.restore_generated_diagnostics(__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 12014 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12870 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15216 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15838 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16585 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.restore_generated_diagnostics(__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 10015 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 10551 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 11527 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12222 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13957 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15124 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15631 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15748 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15940 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.restore_generated_diagnostics(__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 11328 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17240 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.restore_generated_diagnostics(__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 9891 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 10342 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 11099 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14057 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14156 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16252 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.restore_generated_diagnostics(__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 10995 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12073 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12123 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12484 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.restore_generated_diagnostics(__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 12274 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12429 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.restore_generated_diagnostics(__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 32 line (219 tokens) duplication in the following files:
* Starting at line 10176 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 10996 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 11878 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12074 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12124 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12275 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12430 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12485 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12676 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 13070 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15268 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
            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.restore_generated_diagnostics(__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> {

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

  • Starting at line 9730 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 9785 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 10122 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 10453 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 10650 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 10745 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 11147 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 11231 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 12630 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13024 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13751 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14859 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16052 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16452 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16642 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16941 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17146 of src/bin_support/grammar/generated/antlr_v4_parser.rs
            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.restore_generated_diagnostics(__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> {
```rust

---

Found a 36 line (216 tokens) duplication in the following files:
* Starting at line 13693 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 14746 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15502 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16828 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                        }
                        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.restore_generated_diagnostics(__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 13695 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15016 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15504 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16830 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17098 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.restore_generated_diagnostics(__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 14748 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15016 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17098 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.restore_generated_diagnostics(__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 34 line (200 tokens) duplication in the following files:

  • Starting at line 10889 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13306 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13447 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14446 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); }
                }
                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.restore_generated_diagnostics(__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 33 line (199 tokens) duplication in the following files:
* Starting at line 10890 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12018 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12874 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 13307 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 13448 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 14447 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15220 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15842 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16589 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                }
                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.restore_generated_diagnostics(__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 32 line (196 tokens) duplication in the following files:

  • Starting at line 9893 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13697 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14059 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14158 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14750 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15018 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15506 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16254 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16832 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17100 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.restore_generated_diagnostics(__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 32 line (196 tokens) duplication in the following files:
* Starting at line 10344 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 13697 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 14750 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15018 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15506 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16832 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17100 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.restore_generated_diagnostics(__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> {

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

  • Starting at line 11101 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 13697 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 14750 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15018 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 15506 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 16832 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 17100 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.restore_generated_diagnostics(__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> {
```rust

---

Found a 31 line (195 tokens) duplication in the following files:
* Starting at line 9894 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 10019 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 10345 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 10555 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 10892 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 11102 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 11531 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12020 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12226 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 12876 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 13309 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 13450 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 13698 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 13961 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 14060 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 14159 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 14449 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 14751 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15019 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15128 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15222 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15507 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15635 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15752 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15844 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 15944 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16255 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16591 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 16833 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 17101 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
                }
                _ => 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.restore_generated_diagnostics(__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 22 line (179 tokens) duplication in the following files:

  • Starting at line 783 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 913 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 1035 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 1155 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 1284 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 1407 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 1529 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 1655 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 1778 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 1891 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 2012 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 2133 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 2244 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 2376 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 2495 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 2605 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 2724 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 2850 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 2958 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 3072 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 3235 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 3348 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 3470 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 3586 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 3700 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 3816 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 3933 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 4049 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 4171 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 4279 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 4383 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 4493 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 4604 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 4724 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 4862 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 4972 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 5083 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 5197 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 5305 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 5434 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 5556 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 5673 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 5798 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 5912 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 6026 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 6137 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 6250 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 6389 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 6512 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 6646 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 6766 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 6881 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 6991 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 7108 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 7242 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 7366 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 7481 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 7601 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 7724 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 7853 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 7989 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 8109 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 8222 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 8341 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 8464 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 8593 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 8697 of src/bin_support/grammar/generated/antlr_v4_parser.rs
impl<'a> GrammarSpecContext<'a> {
    fn __from_node(node: RuleNodeView<'a>) -> Self {
        let invocation_states = node.invocation_states().collect();
        Self::__from_node_with_invocation_states(node, invocation_states)
    }

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

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

    fn __from_node_with_invocation_states(node: RuleNodeView<'a>, invocation_states: Vec<isize>) -> Self {
        let __default = __RuleAttrs0:

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

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

📊 Source Code Metrics (this PR vs main)

File Cyclomatic Cognitive Functions LLOC MI
src/parser.rs 2066 (main: 2062) 🔴 1367 (main: 1363) 🔴 644 ⚪ 4480 (main: 4474) 🔴 0 ⚪
src/bin/antlr4-rust-gen.rs 2221 (main: 2012) 🔴 1407 (main: 1283) 🔴 491 (main: 455) 🔴 3933 (main: 3634) 🔴 0 ⚪
src/tree.rs 330 (main: 273) 🔴 89 (main: 75) 🔴 174 (main: 138) 🔴 455 (main: 351) 🔴 0 ⚪
src/bin_support/grammar/frontend.rs 216 (main: 197) 🔴 90 (main: 79) 🔴 63 (main: 56) 🔴 280 (main: 254) 🔴 0 ⚪
src/bin_support/embedded.rs 162 (main: 151) 🔴 104 (main: 98) 🔴 36 (main: 32) 🔴 242 (main: 221) 🔴 0 ⚪
src/lib.rs 4 ⚪ 3 ⚪ 1 ⚪ 7 ⚪ 34.60 (main: 34.79) 🔴

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

@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: 6a321be728

ℹ️ 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/parser.rs
Comment thread src/bin/antlr4-rust-gen.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs

@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: 2

🤖 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/bin/antlr4-rust-gen.rs`:
- Around line 7565-7571: Seed used_listener_methods with "every_rule" alongside
the existing visitor-method seeds. Ensure the listener collision check in the
rule callback generation treats normalized names matching the fixed
enter_every_rule and exit_every_rule methods as already used, while preserving
the existing used_visitor_methods initialization.

In `@src/tree.rs`:
- Around line 1301-1363: The ParseTreeVisitor traversal can overflow the native
stack on deeply nested trees because visit_children recursively calls visit for
each child. Update visit_children (and its traversal path through
visit_rule/visit) to use the project’s existing stacker-based growth mechanism,
matching recognize_state_fast_checked, while preserving visitor callbacks, child
aggregation, and early termination 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

Run ID: 3eca1f4b-e621-4f10-b53c-a335377e4c0d

📥 Commits

Reviewing files that changed from the base of the PR and between 22a36d6 and 6a321be.

⛔ Files ignored due to path filters (3)
  • src/bin/snapshots/antlr4_rust_gen__tests__context_surface_name_collision.snap is excluded by !**/*.snap
  • src/bin/snapshots/antlr4_rust_gen__tests__left_recursive_label_alternatives.snap is excluded by !**/*.snap
  • src/bin_support/grammar/generated/antlr_v4_parser.rs is excluded by !**/generated/**
📒 Files selected for processing (14)
  • .conformance-review/Rust.test.stg
  • .conformance-review/Rust.test.stg.design-notes.md
  • .conformance-review/rust-test-stg-honest-reference-gap.md
  • README.md
  • src/bin/antlr4-rust-gen.rs
  • src/bin_support/embedded.rs
  • src/bin_support/grammar/frontend.rs
  • src/lib.rs
  • src/parser.rs
  • src/tree.rs
  • tests/antlr4_rust_gen_cli.rs
  • tests/fixtures/antlr4-rust-gen/combined-contexts/Shapes.g4
  • tests/fixtures/antlr4-rust-gen/typed-tree-walkers/Calculator.g4
  • third_party/antlr-v4-grammar/self-hosted.sha256

Comment thread src/bin/antlr4-rust-gen.rs Outdated
Comment thread src/tree.rs
Copilot AI review requested due to automatic review settings July 23, 2026 01:13

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@tinovyatkin

Copy link
Copy Markdown
Contributor Author

@codex review

@tinovyatkin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 23, 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: 605b6933cf

ℹ️ 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
Comment thread src/bin/antlr4-rust-gen.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs Outdated
Copilot AI review requested due to automatic review settings July 23, 2026 01:30

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@tinovyatkin

Copy link
Copy Markdown
Contributor Author

Fixed the runtime-testsuite regressions in a3edd1e7c: literal labels now retain terminal/block action semantics while still carrying token metadata for the typed accessor surface.

Validated on the final head:

  • cargo test --locked --all-targets --all-features (262 runtime, 594 generator, 22 CLI tests)
  • cargo clippy --locked --all-targets --all-features -- -D warnings
  • tools/grammar-frontend/update-stage0.sh --check (Stage 1/Stage 2 byte-identical)
  • upstream ANTLR runtime testsuite: 357 passed, 0 failed, 0 skipped

@codex review
@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== PR diff summary ==='
git diff --stat origin/main...HEAD || git diff --stat HEAD~1...HEAD
echo
echo '=== Changed Rust and grammar files ==='
git diff --name-only origin/main...HEAD 2>/dev/null || git diff --name-only HEAD~1...HEAD
echo
echo '=== Recent commits ==='
git log --oneline -12
echo
echo '=== Outline: high-impact implementation files ==='
for f in src/bin/antlr4-rust-gen.rs src/bin_support/embedded.rs src/bin_support/grammar/frontend.rs src/parser.rs src/tree.rs tests/antlr4_rust_gen_cli.rs; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    ast-grep outline "$f" --items all --view expanded | head -250
  fi
done
echo
echo '=== Fix commit diff ==='
git show --format=fuller --find-renames --find-copies --stat a3edd1e7c
git show --format= --find-renames --find-copies --unified=80 a3edd1e7c -- \
  src/bin/antlr4-rust-gen.rs \
  src/bin_support/embedded.rs \
  tests/antlr4_rust_gen_cli.rs \
  tests/fixtures/antlr4-rust-gen

Length of output: 14581


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Fix commit metadata and changed paths ==='
git show --format=fuller --summary a3edd1e7c
git diff-tree --no-commit-id --name-only -r a3edd1e7c

echo
echo '=== Fix commit patch ==='
git show --format= --find-renames --find-copies --unified=100 a3edd1e7c -- \
  src/bin/antlr4-rust-gen.rs \
  src/bin_support/embedded.rs \
  tests/antlr4_rust_gen_cli.rs \
  tests/fixtures/antlr4-rust-gen

echo
echo '=== Literal-label and terminal-action symbols (definitions and uses) ==='
rg -n -C 5 -i \
  'literal label|literal_label|token metadata|terminal.*action|action.*terminal|ElementRef|stable_accessor|structural_terminal' \
  src/bin/antlr4-rust-gen.rs src/bin_support/embedded.rs tests/antlr4_rust_gen_cli.rs \
  -g '*.rs'

echo
echo '=== Targeted test functions ==='
ast-grep outline tests/antlr4_rust_gen_cli.rs --items all --type function --match 'label|action|typed|context|generated' --view expanded

Length of output: 48733


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Element-reference translation and is_block branches ==='
sed -n '330,650p' src/bin_support/embedded.rs
echo
echo '=== Label accessor selection/emission ==='
sed -n '7960,8225p' src/bin/antlr4-rust-gen.rs
echo
echo '=== Calculator grammar fixture ==='
cat -n tests/fixtures/antlr4-rust-gen/typed-tree-walkers/Calculator.g4
echo
echo '=== Typed-walker CLI integration test ==='
sed -n '330,690p' tests/antlr4_rust_gen_cli.rs
echo
echo '=== ParseTreeVisitor and walker public implementations ==='
rg -n -C 12 'trait ParseTreeVisitor|fn visit\(|fn visit_children|trait .*Listener|walk_with_invocation_states|pub fn walk' src/tree.rs src/bin/antlr4-rust-gen.rs
echo
echo '=== Frontend typed builder callbacks and invocation ==='
rg -n -C 10 'struct TypedCstBuilder|impl.*ANTLRv4Listener|enter_every_rule|exit_every_rule|walk_with_invocation_states|copy_cst' src/bin_support/grammar/frontend.rs

Length of output: 52571


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Complete token-reference branch after the is_block branch ==='
sed -n '555,750p' src/bin_support/embedded.rs

echo
echo '=== All embedded-action references to labels in grammar fixtures and generator tests ==='
rg -n -C 8 '\$[A-Za-z_][A-Za-z0-9_]*(\.(text|start|stop|ctx))?' \
  tests src \
  -g '*.g4' -g '*.rs'

echo
echo '=== Structural-action rendering and execution tests ==='
rg -n -C 12 \
  'embedded.*action|action.*embedded|action_parser_data|translate_body|translate_element_read|parser_action_hook' \
  src/bin/antlr4-rust-gen.rs src/bin_support/embedded.rs tests \
  -g '*.rs'

echo
echo '=== Grammar model terminal/action types ==='
rg -n -C 8 'enum Terminal|enum ElementKind|struct Element|ActionSite' \
  src/bin_support/grammar \
  -g '*.rs'

Length of output: 201313


@tinovyatkin I found one correctness issue in the literal-label regression fix.

src/bin/antlr4-rust-gen.rs — Line 2483
Marking Terminal::Literal as is_block fixes lookup failure by routing it through the block-label branch, but that branch in src/bin_support/embedded.rs always selects the context’s last terminal child. Consequently, a literal label used in an embedded action after another terminal is read incorrectly:

r : first='+' INT { consume($first.text); } ;

$first.text is translated using terminal_children(...).last(), so it yields the INT text instead of "+".

Please keep the special last-terminal behavior limited to labeled token blocks/sets. For literal labels, use their retained token_types plus the resolved occurrence when translating $label, $label.text, $label.start, and $label.stop. A regression test should include a labeled literal followed by a distinct terminal and an embedded action that reads the literal label.

✅ 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.

Copilot AI review requested due to automatic review settings July 23, 2026 01:39

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@tinovyatkin

Copy link
Copy Markdown
Contributor Author

All three follow-up typed-accessor findings are addressed and resolved in 6d54ca4a7:

  • wildcard labels retain the full non-EOF token domain;
  • set ranges resolve and expand through vocabulary token types;
  • bare literals map back to canonical symbolic Rust token accessors.

Final-head validation:

  • cargo test --locked --all-targets --all-features (262 runtime, 595 generator, 22 CLI tests)
  • cargo clippy --locked --all-targets --all-features -- -D warnings
  • tools/grammar-frontend/update-stage0.sh --check (byte-identical fixed point)
  • upstream ANTLR runtime testsuite: 357 passed, 0 failed, 0 skipped

@codex review
@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Follow-up commit ==='
git show --format=fuller --summary 6d54ca4a7
echo
git show --format= --find-renames --find-copies --unified=100 6d54ca4a7 -- \
  src/bin/antlr4-rust-gen.rs \
  src/bin_support/embedded.rs \
  tests/antlr4_rust_gen_cli.rs \
  tests/fixtures/antlr4-rust-gen

echo
echo '=== Changed paths in PR ==='
git diff --name-only origin/main...HEAD

echo
echo '=== Generator and embedded outlines ==='
ast-grep outline src/bin/antlr4-rust-gen.rs --items all --type function,struct,enum --match 'token|Token|literal|Literal|wildcard|Wildcard|set|Set|accessor|Accessor|ElementRef' --view expanded
ast-grep outline src/bin_support/embedded.rs --items all --type function,struct,enum --match 'token|Token|literal|Literal|wildcard|Wildcard|set|Set|ElementRef|translate' --view expanded

echo
echo '=== Targeted symbols and tests ==='
rg -n -C 10 -i \
  'wildcard|bare literal|literal label|set range|token_types|token domain|canonical symbolic|symbolic.*accessor|accessor.*token|terminal_children' \
  src/bin/antlr4-rust-gen.rs src/bin_support/embedded.rs tests \
  -g '*.rs' -g '*.g4'

Length of output: 206260


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Embedded label resolution and translation ==='
sed -n '340,720p' src/bin_support/embedded.rs

echo
echo '=== Typed label accessor selection and rendering ==='
sed -n '8030,8335p' src/bin/antlr4-rust-gen.rs

echo
echo '=== Embedded-action grammar fixtures and tests ==='
rg -n -C 12 -P '\{[^}]*\$[A-Za-z_][A-Za-z0-9_]*(?:\.(?:text|start|stop|ctx))?' \
  tests src \
  -g '*.g4' -g '*.rs'

echo
echo '=== Literal-label assertions and action rendering tests ==='
rg -n -C 12 -P 'literal_labels_keep_terminal_action_semantics|translate_element_read|terminal_children\(.*last|labeledTokens|literalTokens' \
  src/bin/antlr4-rust-gen.rs src/bin_support/embedded.rs tests \
  -g '*.rs' -g '*.g4'

echo
echo '=== Current final-head commit ==='
git rev-parse HEAD
git merge-base --is-ancestor 6d54ca4a7 HEAD && echo '6d54ca4a7 is an ancestor of HEAD'

Length of output: 185286


@tinovyatkin I verified the wildcard, range, and canonical literal-accessor changes in 6d54ca4a7. One embedded-action correctness issue remains:

src/bin_support/embedded.rs — Line 589
Terminal::Literal is still modeled with is_block: true in src/bin/antlr4-rust-gen.rs (Line 2483). Consequently, translating $label, $label.text, $label.start, or $label.stop takes the is_block branch here and unconditionally selects terminal_children(...).last(), ignoring the literal’s retained token_types and resolved occurrence.

For example:

r : first='+' INT { consume($first.text); } ;

translates $first.text to the INT text, not "+". The current literal_labels_keep_terminal_action_semantics test only checks that the literal is classified as a block; it does not exercise an embedded action. Please route labeled literals through occurrence-aware token-type lookup (while retaining the last-terminal behavior for actual labeled token blocks/sets) and add a regression that reads a literal label after another terminal.

✅ 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.

@coderabbitai

coderabbitai Bot commented Jul 23, 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

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 6d54ca4a7a

ℹ️ 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".

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/bin_support/embedded.rs (2)

965-971: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the lazy-iterator regression assertion reject eager collection.

Counting the exact substring .collect() does not detect .collect::<Vec<_>>(); the previous eager implementation could still pass these tests. Assert that the translated expressions do not contain .collect::<Vec<_>>() (for both rule and token labels), or assert the complete expected translation.

Proposed test fix
         assert_eq!(rules.matches(".collect()").count(), 1, "{rules}");
         assert!(rules.contains("__ctx.child_rule_trees("), "{rules}");
+        assert!(!rules.contains(".collect::<Vec<_>>()"), "{rules}");

         assert_eq!(tokens.matches(".collect()").count(), 1, "{tokens}");
         assert!(tokens.contains("__ctx.child_tokens("), "{tokens}");
+        assert!(!tokens.contains(".collect::<Vec<_>>()"), "{tokens}");
🤖 Prompt for 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.

In `@src/bin_support/embedded.rs` around lines 965 - 971, Update the regression
assertions in the translate_body tests for both the rule and token expressions
to explicitly reject eager `.collect::<Vec<_>>()` output, while retaining the
existing checks for the expected child_rule_trees and child_tokens calls.

412-418: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve or explicitly reject the legacy _all() syntax.

The parser still recognizes $ctx.<rule>_all(), but translate_ctx_member no longer translates that form. Existing grammars can therefore pass suffix parsing and then fail to generate valid code. Keep _all() as an alias for child_rules(...), or reject it with a clear migration error and add a regression test.

Also applies to: 528-542

🤖 Prompt for 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.

In `@src/bin_support/embedded.rs` around lines 412 - 418, Update
translate_ctx_member and the related suffix-parsing path to handle the legacy
$ctx.<rule>_all() form consistently: either translate it as the child_rules(...)
alias like _children(), or explicitly reject it with a clear migration error.
Add a regression test covering the chosen behavior, ensuring parsing cannot
succeed while code generation fails.
🤖 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/bin/antlr4-rust-gen.rs`:
- Around line 2573-2596: The structural_set_token_types function currently
ignores SetElement::Range values, causing range tokens to be absent from normal
sets and incorrectly included in inverted sets. Decode Range.start and
Range.stop using the existing vocabulary/literal conversion helpers, expand the
inclusive token-type span, and add those token types to members before applying
the inverted filtering or collecting the set.

In `@src/tree.rs`:
- Around line 1753-1782: Update visitor_grows_the_stack_for_deep_rule_trees to
execute the deep-tree construction and traversal inside a dedicated thread
configured with an explicit 256 KiB stack, matching the stack-growth tests in
parser.rs. Preserve the existing depth, Visitor implementation, and assertion
while propagating any thread failure so the test deterministically exercises
stack growth.

---

Outside diff comments:
In `@src/bin_support/embedded.rs`:
- Around line 965-971: Update the regression assertions in the translate_body
tests for both the rule and token expressions to explicitly reject eager
`.collect::<Vec<_>>()` output, while retaining the existing checks for the
expected child_rule_trees and child_tokens calls.
- Around line 412-418: Update translate_ctx_member and the related
suffix-parsing path to handle the legacy $ctx.<rule>_all() form consistently:
either translate it as the child_rules(...) alias like _children(), or
explicitly reject it with a clear migration error. Add a regression test
covering the chosen behavior, ensuring parsing cannot succeed while code
generation fails.
🪄 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: f3bf6f30-e858-468c-ba08-e9a7c8169194

📥 Commits

Reviewing files that changed from the base of the PR and between 6a321be and 605b693.

⛔ Files ignored due to path filters (3)
  • src/bin/snapshots/antlr4_rust_gen__tests__context_surface_name_collision.snap is excluded by !**/*.snap
  • src/bin/snapshots/antlr4_rust_gen__tests__left_recursive_label_alternatives.snap is excluded by !**/*.snap
  • src/bin_support/grammar/generated/antlr_v4_parser.rs is excluded by !**/generated/**
📒 Files selected for processing (8)
  • src/bin/antlr4-rust-gen.rs
  • src/bin_support/embedded.rs
  • src/parser.rs
  • src/tree.rs
  • tests/antlr4_rust_gen_cli.rs
  • tests/fixtures/antlr4-rust-gen/context-name-collision/T.g4
  • tests/fixtures/antlr4-rust-gen/typed-tree-walkers/Calculator.g4
  • third_party/antlr-v4-grammar/self-hosted.sha256

Comment thread src/bin/antlr4-rust-gen.rs
Comment thread src/tree.rs
Copilot AI review requested due to automatic review settings July 23, 2026 01:55

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@tinovyatkin

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: c5f06f8b77

ℹ️ 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".

@tinovyatkin
tinovyatkin marked this pull request as ready for review July 23, 2026 05:39
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@tinovyatkin tinovyatkin changed the title [codex] Add typed listeners, visitors, and traversal feat: add typed listeners, visitors, and traversal Jul 23, 2026
@tinovyatkin
tinovyatkin merged commit c240714 into main Jul 23, 2026
15 of 18 checks passed
@tinovyatkin
tinovyatkin deleted the feature/issue-138-typed-traversal branch July 23, 2026 05:45
@ophiarch ophiarch Bot mentioned this pull request Jul 23, 2026

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/tree.rs (1)

297-321: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider documenting the sparse-vector invariant.

The lazy backfill-on-first-nonzero pattern here is correct but subtle: it silently relies on context_alt_numbers staying either empty or exactly 1:1 with node count for every subsequent push_node call. A short comment stating this invariant would help future maintainers avoid accidentally breaking it (e.g., by adding a new early-return path that skips one of the two branches).

♻️ Suggested comment
+        // Sparse encoding: stays empty while every context_alt_number is 0.
+        // Once a nonzero value is recorded, this vector is padded to be 1:1
+        // with node count for all subsequent pushes.
         if record.context_alt_number == 0 {
🤖 Prompt for 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.

In `@src/tree.rs` around lines 297 - 321, Add a concise comment in push_node
documenting that context_alt_numbers is either empty or remains one-to-one with
the node count after its first nonzero value, and that both branches must
preserve this invariant on every push.
🤖 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.

Outside diff comments:
In `@src/tree.rs`:
- Around line 297-321: Add a concise comment in push_node documenting that
context_alt_numbers is either empty or remains one-to-one with the node count
after its first nonzero value, and that both branches must preserve this
invariant on every push.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 05cc1093-7cf8-40a4-8ac2-969790e01814

📥 Commits

Reviewing files that changed from the base of the PR and between 605b693 and c5f06f8.

📒 Files selected for processing (4)
  • src/bin/antlr4-rust-gen.rs
  • src/tree.rs
  • tests/antlr4_rust_gen_cli.rs
  • tests/fixtures/antlr4-rust-gen/typed-tree-walkers/Calculator.g4

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.

ANTLR visitors

2 participants