Skip to content

feat(codegen): support antlr4rust embedded parser surface - #270

Merged
tinovyatkin merged 25 commits into
mainfrom
codex/issue-267-antlr4rust-compat
Aug 2, 2026
Merged

feat(codegen): support antlr4rust embedded parser surface#270
tinovyatkin merged 25 commits into
mainfrom
codex/issue-267-antlr4rust-compat

Conversation

@tinovyatkin

@tinovyatkin tinovyatkin commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • lower the observed antlr4rust recog.input.la / lt, token-view, _localctx, and context-getter surface onto native runtime APIs
  • derive parser/rule/token compatibility metadata structurally, including exact source grammar spelling, imported members, implicit literals, lexical scopes, and cfg-gated symbols
  • keep generic grammar analysis target-agnostic by injecting Rust-aware action-reference filtering only for embedded Rust actions
  • classify embedded Rust with a pinned action-free Perses grammar and recognizer generated by this project's own antlr4-rust-gen; no second Rust parser dependency is added
  • preserve native fallible context accessors while exposing antlr4rust-compatible Option getters through a generated wrapper, including indexed repeated-child getters
  • handle reviewed Rust syntax and resolution edges, including associated types, foreign statics, glob imports, #[macro_use] imports, relative std/core shadows, literal const arguments, impl inner attributes, and no-struct >= comparisons
  • reject unsupported compatibility forms during generation with source-backed diagnostics
  • add reduced C and Java transform fixtures, generated-surface snapshots, and compile-and-run behavioral regressions

Why

The Rust transforms shipped for the C and Java grammars in
antlr/grammars-v4 emit a small antlr4rust parser ABI that the embedded-action
pipeline did not previously understand. Generated crates therefore failed to
compile even though the required behavior already existed in the native token
stream and active-context machinery.

This change treats that surface as grammar-agnostic compatibility lowering.
Rust syntax distinctions needed by alias lowering come from this runtime's own
generated parser rather than flat token guesses or an external Rust parser.
Target-specific $ filtering remains in the embedded Rust layer and is passed
into generic semantic and transform analysis through a callback.

Rebase Note

Current main includes #285, which omits adaptive fallbacks from complete
LL(1) dispatches. Regenerating the pinned Rust recognizer therefore updates the
decision manifest to schema v2 and intentionally removes several thousand lines
of generated fallback code. tools/rust-syntax/update-generated.sh --check
verifies the checked-in output byte-for-byte.

Validation

  • tools/rust-syntax/update-generated.sh --check
  • cargo test --locked --all-features --lib (347 passed)
  • cargo test --locked --all-features --bin antlr4-rust-gen (921 passed)
  • cargo test --locked --all-features --test antlr4_rust_gen_cli antlr4rust_transform_surface_compiles_and_matches_native_behavior -- --nocapture
  • cargo clippy --locked --all-targets --all-features -- -D warnings
  • cargo fmt --all -- --check
  • git diff --check

Closes #267

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The generator lowers supported ANTLR4Rust embedded syntax to native APIs. It emits compatibility facades, token aliases, context accessors, source-aware diagnostics, and Rust syntax analysis. Fixtures and end-to-end tests cover compatibility behavior.

Changes

ANTLR4Rust compatibility lowering

Layer / File(s) Summary
Rust analysis and body translation
src/bin_support/embedded.rs, src/bin_support/rust_syntax/mod.rs, src/bin_support/grammar/...
Analyzes Rust syntax, scopes, imports, attributes, macros, and source ownership. Lowers supported compatibility expressions and reports contextual errors.
Generator wiring and token aliases
src/bin/antlr4-rust-gen.rs, src/bin_support/grammar/...
Translates parser and lexer bodies. Tracks compatibility requirements and emits conditional facades and sanitized token aliases.
Context compatibility accessors
src/bin/antlr4-rust-gen.rs
Adds compatibility accessors, live attributes, active-context construction, collision handling, and fallible context rendering.
Compatibility fixtures and validation
tests/antlr4_rust_gen_cli.rs, tests/fixtures/antlr4-rust-gen/antlr4rust-compat/*, README.md
Adds grammar fixtures and tests for aliases, lookahead, token history, attributes, accessors, diagnostics, and native-versus-compatibility behavior.
Rust recognizer and repository support
third_party/rust-grammar/*, tools/rust-syntax/update-generated.sh, third_party/antlr-v4-grammar/*, Cargo.toml
Adds the pinned Rust grammar and licenses, recognizer generation checks, grammar lexer updates, checksum changes, and configuration reformatting without value changes.

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

Sequence Diagram(s)

sequenceDiagram
  participant Grammar
  participant Generator
  participant BodyTranslator
  participant GeneratedParser
  participant TokenStream
  Grammar->>Generator: provide embedded parser body
  Generator->>BodyTranslator: translate body with rule context and aliases
  BodyTranslator-->>Generator: return lowered source and compatibility flags
  Generator->>GeneratedParser: emit facades, aliases, and accessors
  GeneratedParser->>TokenStream: request lookahead or token data
  TokenStream-->>GeneratedParser: return token view or token type
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.28% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive The implementation and tests cover the linked issue, but required generated recognizers and snapshots are excluded by path filters. Review the excluded generated/** and *.snap files to confirm generated outputs and snapshot-based regression evidence.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The changes support compatibility lowering, syntax analysis, generated artifacts, diagnostics, documentation, and regression coverage for the linked issue.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding code generation support for the antlr4rust embedded parser surface.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-267-antlr4rust-compat

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.

@claude

claude Bot commented Jul 31, 2026

Copy link
Copy Markdown

Claude Code is working…

I'll analyze this and get back to you.

View job run

@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown

📊 Source Code Metrics (this PR vs main)

File Cyclomatic Cognitive Functions LLOC MI
src/bin/antlr4-rust-gen.rs 2956 (main: 2795) 🔴 1911 (main: 1795) 🔴 625 (main: 596) 🔴 5197 (main: 4892) 🔴 0 ⚪
src/bin_support/embedded.rs 1308 (main: 500) 🔴 1006 (main: 327) 🔴 195 (main: 66) 🔴 2027 (main: 739) 🔴 0 ⚪
src/bin_support/grammar/semantics.rs 661 (main: 660) 🔴 514 ⚪ 127 (main: 126) 🔴 904 (main: 902) 🔴 0 ⚪
src/bin_support/rust_syntax/mod.rs 430 🆕 212 🆕 124 🆕 723 🆕 0 🆕
src/bin_support/grammar/mutual_recursion.rs 318 (main: 315) 🔴 221 ⚪ 92 (main: 89) 🔴 442 (main: 435) 🔴 0 ⚪
src/bin_support/grammar/transform.rs 352 (main: 348) 🔴 306 (main: 309) 🟢 84 (main: 80) 🔴 625 (main: 619) 🔴 0 ⚪
src/bin_support/grammar/compiler.rs 59 (main: 58) 🔴 20 ⚪ 18 (main: 17) 🔴 82 (main: 81) 🔴 6.57 (main: 7.66) 🔴
src/bin_support/grammar/action.rs 48 (main: 42) 🔴 29 (main: 23) 🔴 15 (main: 13) 🔴 78 (main: 64) 🔴 11.29 (main: 13.57) 🔴
src/bin_support/rust_names.rs 43 (main: 34) 🔴 36 (main: 28) 🔴 10 (main: 8) 🔴 60 (main: 48) 🔴 18.52 (main: 22.56) 🔴
src/bin_support/grammar/mod.rs 1 ⚪ 0 ⚪ 0 ⚪ 0 ⚪ 45.12 (main: 45.89) 🔴

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

@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

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

🤖 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_support/embedded.rs`:
- Around line 3991-4004: Replace the six fragment assertions in the lowered-body
test with an insta snapshot assertion for the complete lowered string,
preserving the existing translate_parser_body setup and expect behavior. Add
#[allow(clippy::disallowed_methods)] to the test or module using the insta
macro, then generate and accept the snapshot with cargo insta test and cargo
insta accept; leave the error-message assertions in
rejects_unknown_antlr4rust_members_before_rust_compilation unchanged.
- Around line 1713-1719: Update required_member_call so its empty-argument
requirement is controlled explicitly rather than by comparing the
display_receiver message string to "_localctx". Prefer moving the argument
validation into local_context_replacement immediately after the as_deref name
check, while keeping display_receiver solely for diagnostic text.
- Around line 1642-1647: Update the `recog` handling around `next_significant`
so a bare `recog` produces the same generation-time diagnostic as other
unsupported `recog` forms instead of returning `Ok(None)` and passing through.
If pass-through is intentionally required for user-defined `@members`
identifiers, document that rationale at this branch and reconcile the behavior
with the `recog.<member>` path.

In `@src/bin/antlr4-rust-gen.rs`:
- Around line 9941-9961: Update translate_parser_body to return the translated
body together with uses_input and uses_local_context, using
LoweredAntlr4RustBody.uses_local_context and the result of
recog_input_replacement rather than scanning emitted text. Propagate these
returned flags to the caller that currently invokes record_antlr4rust_lowering,
remove that text-matching helper, and preserve facade, token-alias, and
compatibility-accessor emission based only on the returned values.
- Around line 11082-11105: Add a `used_methods` parameter (as a mutable
reference) to both `render_antlr4rust_rule_all_accessor` and
`render_antlr4rust_optional_token_accessor` functions. After computing the
method name with `sanitize_identifier`, check if the name already exists in
`used_methods`; if it does, skip the writeln emission; if not, insert the name
into `used_methods` and proceed with writing the method. Update both call sites
(at lines 11337-11344 and 11428-11434) to pass `&mut used_methods` to prevent
duplicate method names in the impl block.
- Around line 12666-12696: The lt method in the __Antlr4RustInput impl block
returns a TokenView with a lifetime inferred to the temporary &self reference
rather than to the actual CommonTokenStream lifetime. Update the impl block
header to explicitly name the 'a lifetime parameter (change from impl<L:
TokenSource> __Antlr4RustInput<'_, L> to impl<'a, L: TokenSource>
__Antlr4RustInput<'a, L>), and then update the return type of the lt method to
return Option<__Antlr4RustTokenView<'a>> instead of
Option<__Antlr4RustTokenView<'_>> so the token view's lifetime is properly tied
to the stream's lifetime rather than the temporary facade reference.

In `@tests/antlr4_rust_gen_cli.rs`:
- Around line 3535-3543: Update the diagnostic normalization in the unsupported
ANTLR4 Rust surface test to replace the temporary root path from temp.path()
with a stable placeholder after replacing the grammar path. Ensure stderr
containing either the grammar path or generated out-dir path is normalized
before diagnostics are added to the snapshot.
🪄 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: 77c1fc18-cc6d-4746-aace-8eeb2c1dd65c

📥 Commits

Reviewing files that changed from the base of the PR and between e426444 and 1b5d805.

⛔ Files ignored due to path filters (5)
  • src/bin_support/grammar/generated/antlr_v4_lexer.rs is excluded by !**/generated/**
  • src/bin_support/grammar/generated/antlr_v4_parser.rs is excluded by !**/generated/**
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_generated_surface.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_semantics_manifest.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__unsupported_antlr4rust_surface_diagnostics.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • src/bin/antlr4-rust-gen.rs
  • src/bin_support/embedded.rs
  • tests/antlr4_rust_gen_cli.rs
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/CCompat.g4
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/JavaCompat.g4
  • third_party/antlr-v4-grammar/self-hosted.sha256

Comment thread src/bin_support/embedded.rs
Comment thread src/bin_support/embedded.rs Outdated
Comment thread src/bin_support/embedded.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs
Comment thread src/bin/antlr4-rust-gen.rs Outdated
Comment thread tests/antlr4_rust_gen_cli.rs

@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: 1b5d8052e5

ℹ️ 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_support/embedded.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs
Comment thread src/bin_support/embedded.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown

Copy/Paste Detection

Found 3154 duplication(s) across 16 changed Rust file(s) (threshold: 100 tokens).

Show duplications

Found a 364 line (1962 tokens) duplication in the following files:

  • Starting at line 170 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 360 of src/bin_support/rust_syntax/generated/rust_parser.rs
    &[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
    &[],
    &[],
    &[],
);

pub fn metadata() -> &'static GrammarMetadata {
    &METADATA
}

pub fn rule_names() -> &'static [&'static str] {
    METADATA.rule_names()
}

fn parser_semantics() -> &'static antlr4_runtime::ParserSemantics {
    static SEMANTICS_CELL: OnceLock<antlr4_runtime::ParserSemantics> = OnceLock::new();
    SEMANTICS_CELL.get_or_init(|| {
        let mut ir = antlr4_runtime::semir::SemIr::new();
        let mut predicates = Vec::new();

        let actions = Vec::new();
        antlr4_runtime::ParserSemantics { ir, predicates, actions }
    })
}


#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs0 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs1 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs2 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs3 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs4 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs5 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs6 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs7 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs8 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs9 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs10 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs11 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs12 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs13 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs14 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs15 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs16 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs17 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs18 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs19 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs20 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs21 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs22 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs23 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs24 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs25 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs26 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs27 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs28 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs29 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs30 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs31 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs32 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs33 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs34 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs35 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs36 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs37 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs38 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs39 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs40 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs41 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs42 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs43 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs44 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs45 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs46 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs47 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs48 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs49 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs50 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs51 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs52 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs53 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs54 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs55 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs56 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs57 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs58 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs59 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs60 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs61 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs62 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs63 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs64 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs65 {
}

#[derive(Clone, Debug, Default)]
#[allow(non_snake_case, dead_code)]
pub struct __RuleAttrs66 {
}



#[allow(dead_code)]
```rust

---

Found a 295 line (1730 tokens) duplication in the following files:
* Starting at line 528 of src/bin_support/grammar/generated/antlr_v4_parser.rs
* Starting at line 1458 of src/bin_support/rust_syntax/generated/rust_parser.rs

```rust
pub struct __RuleAttrs66 {
}



#[allow(dead_code)]
pub struct __GeneratedInput<'a, L: TokenSource>(&'a mut CommonTokenStream<L>);

#[allow(dead_code)]
impl<L: TokenSource> __GeneratedInput<'_, L> {
    pub fn text(&mut self) -> String {
        self.0.text_all()
    }

    pub fn la(&mut self, offset: isize) -> i32 {
        antlr4_runtime::IntStream::la(self.0, offset)
    }

    pub fn lt(&mut self, offset: isize) -> __GeneratedTokenView {
        __GeneratedTokenView {
            text: self
                .0
                .lt(offset)
                .map(|token| token.text_or_empty().to_owned())
                .unwrap_or_default(),
        }
    }
}

#[allow(dead_code)]
pub struct __GeneratedTokenView {
    text: String,
}

#[allow(dead_code)]
impl __GeneratedTokenView {
    pub fn text(&self) -> &str {
        &self.text
    }
}
#[allow(dead_code)]
#[derive(Clone)]
pub struct TerminalNode<'a> {
    __node: RuntimeTerminalNode<'a>,
}

#[allow(dead_code)]
impl<'a> TerminalNode<'a> {
    fn new(node: RuntimeTerminalNode<'a>) -> Self {
        Self { __node: node }
    }

    pub fn symbol(&self) -> antlr4_runtime::TokenView<'a> {
        self.__node.symbol()
    }

    pub fn is_error(&self) -> bool {
        matches!(
            self.__node.node().kind(),
            antlr4_runtime::NodeKind::Error
        )
    }

    pub fn is_missing(&self) -> bool {
        self.symbol().is_synthetic()
    }
}

impl std::fmt::Display for TerminalNode<'_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.__node.text())
    }
}

#[allow(dead_code)]
#[derive(Clone)]
pub struct ErrorNode<'a> {
    __node: RuntimeErrorNode<'a>,
}

#[allow(dead_code)]
impl<'a> ErrorNode<'a> {
    fn new(node: RuntimeErrorNode<'a>) -> Self {
        Self { __node: node }
    }

    pub fn symbol(&self) -> antlr4_runtime::TokenView<'a> {
        self.__node.symbol()
    }

    pub fn is_missing(&self) -> bool {
        self.symbol().is_synthetic()
    }
}

impl std::fmt::Display for ErrorNode<'_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.__node.text())
    }
}

#[allow(dead_code)]
#[derive(Clone, Copy)]
enum __GeneratedRuleContext<'a> {
    Stored(RuleNodeView<'a>),
    Active {
        context: &'a antlr4_runtime::ParserRuleContext,
        storage: &'a antlr4_runtime::ParseTreeStorage,
        tokens: &'a antlr4_runtime::TokenStore,
    },
}

#[doc(hidden)]
#[derive(Clone, Copy, Debug)]
pub struct StoredTreeContext;

#[derive(Clone, Copy, Debug)]
struct __ActiveParserContext;

#[allow(dead_code)]
fn __context_children<'a>(
    source: __GeneratedRuleContext<'a>,
) -> impl Iterator<Item = antlr4_runtime::Node<'a>> + 'a {
    let mut stored = match source {
        __GeneratedRuleContext::Stored(node) => Some(node.children()),
        __GeneratedRuleContext::Active { .. } => None,
    };
    let mut active = match source {
        __GeneratedRuleContext::Stored(_) => None,
        __GeneratedRuleContext::Active {
            context,
            storage,
            tokens,
        } => Some(context.child_nodes(storage, tokens)),
    };
    std::iter::from_fn(move || {
        stored
            .as_mut()
            .and_then(Iterator::next)
            .or_else(|| active.as_mut().and_then(Iterator::next))
    })
}

#[allow(dead_code)]
fn __rule_children<'a>(
    source: __GeneratedRuleContext<'a>,
    rule_index: usize,
) -> impl Iterator<Item = RuleNodeView<'a>> + 'a {
    __context_children(source).filter_map(move |child| {
        let rule = child.as_rule()?;
        (rule.rule_index() == rule_index).then_some(rule)
    })
}

// Keep this triage aligned with runtime `RuleNodeView::terminal_children()` and
// `ParserRuleContext::terminal_children()`.
fn __terminal_children<'a>(
    source: __GeneratedRuleContext<'a>,
) -> impl Iterator<Item = RuntimeTerminalNode<'a>> + 'a {
    __context_children(source).filter_map(|child| match child.kind() {
        antlr4_runtime::NodeKind::Terminal => child.as_terminal(),
        antlr4_runtime::NodeKind::Error => {
            child.as_error().map(antlr4_runtime::ErrorNodeView::terminal)
        }
        antlr4_runtime::NodeKind::Rule => None,
    })
}

#[allow(dead_code)]
fn __token_children<'a>(
    source: __GeneratedRuleContext<'a>,
    token_type: i32,
) -> impl Iterator<Item = RuntimeTerminalNode<'a>> + 'a {
    __terminal_children(source)
        .filter(move |terminal| terminal.symbol().token_type() == token_type)
}

#[allow(dead_code)]
fn __token_children_matching<'a>(
    source: __GeneratedRuleContext<'a>,
    token_types: &'static [i32],
) -> impl Iterator<Item = RuntimeTerminalNode<'a>> + 'a {
    __terminal_children(source)
        .filter(move |terminal| token_types.contains(&terminal.symbol().token_type()))
}

#[allow(dead_code)]
fn __labeled_token_child(
    child: antlr4_runtime::Node<'_>,
) -> Option<RuntimeTerminalNode<'_>> {
    match child.kind() {
        antlr4_runtime::NodeKind::Terminal => child.as_terminal(),
        antlr4_runtime::NodeKind::Error => {
            let terminal = child
                .as_error()
                .map(antlr4_runtime::ErrorNodeView::terminal)?;
            terminal.symbol().is_synthetic().then_some(terminal)
        }
        antlr4_runtime::NodeKind::Rule => None,
    }
}

#[allow(dead_code)]
fn __labeled_token_children<'a>(
    source: __GeneratedRuleContext<'a>,
    token_type: i32,
) -> impl Iterator<Item = RuntimeTerminalNode<'a>> + 'a {
    __context_children(source).filter_map(move |child| {
        let terminal = __labeled_token_child(child)?;
        (terminal.symbol().token_type() == token_type).then_some(terminal)
    })
}

#[allow(dead_code)]
fn __labeled_token_children_matching<'a>(
    source: __GeneratedRuleContext<'a>,
    token_types: &'static [i32],
) -> impl Iterator<Item = RuntimeTerminalNode<'a>> + 'a {
    __context_children(source).filter_map(move |child| {
        let terminal = __labeled_token_child(child)?;
        token_types
            .contains(&terminal.symbol().token_type())
            .then_some(terminal)
    })
}

#[allow(dead_code)]
trait __FromActiveRuleContext<'a>: Sized {
    fn __from_active(
        context: &'a antlr4_runtime::ParserRuleContext,
        live_attrs: Option<&dyn std::any::Any>,
        invocation_states: Vec<isize>,
        storage: &'a antlr4_runtime::ParseTreeStorage,
        tokens: &'a antlr4_runtime::TokenStore,
    ) -> Option<Self>;
}

#[allow(dead_code)]
fn __active_context_view<'a, T: __FromActiveRuleContext<'a>>(
    context: &'a antlr4_runtime::ParserRuleContext,
    invocation_states: Vec<isize>,
    storage: &'a antlr4_runtime::ParseTreeStorage,
    tokens: &'a antlr4_runtime::TokenStore,
) -> Option<T> {
    T::__from_active(context, None, invocation_states, storage, tokens)
}

#[allow(dead_code)]
fn __active_context_view_with_attrs<'a, T: __FromActiveRuleContext<'a>>(
    context: &'a antlr4_runtime::ParserRuleContext,
    live_attrs: &dyn std::any::Any,
    invocation_states: Vec<isize>,
    storage: &'a antlr4_runtime::ParseTreeStorage,
    tokens: &'a antlr4_runtime::TokenStore,
) -> Option<T> {
    T::__from_active(
        context,
        Some(live_attrs),
        invocation_states,
        storage,
        tokens,
    )
}

#[allow(dead_code)]
fn __write_invocation_states(
    f: &mut std::fmt::Formatter<'_>,
    states: impl Iterator<Item = isize>,
) -> std::fmt::Result {
    f.write_str("[")?;
    let mut separator = "";
    for state in states {
        write!(f, "{separator}{state}")?;
        separator = " ";
    }
    f.write_str("]")
}

/// Marker carried by generated contexts whose required-child
/// invariants were checked after a syntax-clean parse.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ValidatedTreeContext {
    __private: (),
}

#[allow(dead_code)]
trait __RecoveryContextState {}

impl __RecoveryContextState for StoredTreeContext {}
impl __RecoveryContextState for __ActiveParserContext {}

/// A completed, syntax-clean parse tree whose generated child cardinalities
/// have been structurally validated.
#[derive(Debug)]
pub struct ANTLRv4ValidatedTree {

Found a 314 line (1653 tokens) duplication in the following files:

  • Starting at line 18280 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 54881 of src/bin_support/rust_syntax/generated/rust_parser.rs
impl<L, H> AntlRv4Parser<L, H>
where
    L: TokenSource,
    H: antlr4_runtime::SemanticHooks,
{
    pub fn with_hooks(input: CommonTokenStream<L>, hooks: H) -> Self {
        let grammar_metadata = metadata();
        let data = grammar_metadata.recognizer_data();
        let mut base = BaseParser::with_semantic_hooks(input, data, hooks);
        base.set_unknown_predicate_policy(antlr4_runtime::UnknownSemanticPolicy::Error);
        Self {
            base,
            simulator: None,
            generated_only: std::env::var_os("ANTLR4_RUST_GENERATED_ONLY").is_some(),
        }
    }

    pub fn metadata() -> &'static GrammarMetadata {
        metadata()
    }

    /// Adds a listener for parser diagnostics.
    pub fn add_error_listener<T>(&mut self, listener: T)
    where
        T: for<'a> antlr4_runtime::ErrorListener<dyn antlr4_runtime::Recognizer + 'a> + Send + 'static,
    {
        self.base.add_error_listener(listener);
    }

    /// Removes every parser error listener, including the default console listener.
    pub fn remove_error_listeners(&mut self) {
        self.base.remove_error_listeners();
    }


    /// Registers a listener for committed rule enter/exit events during
    /// recognition (ANTLR's `addParseListener`). See
    /// [`antlr4_runtime::ParseListener`] for the delivery contract.
    pub fn add_parse_listener<T>(&mut self, listener: T)
    where
        T: antlr4_runtime::ParseListener + 'static,
    {
        self.base.add_parse_listener(listener);
    }

    /// Removes every registered parse listener and returns them, dropping
    /// any sticky abort a removed listener had requested.
    pub fn remove_parse_listeners(&mut self) -> Vec<Box<dyn antlr4_runtime::ParseListener>> {
        self.base.remove_parse_listeners()
    }

    /// Fully resets parser-owned state and rewinds the current token stream.
    pub fn reset(&mut self) {
        self.base.reset();
        if let Some(simulator) = self.simulator.as_mut() {
            simulator.reset();
        }
    }

    /// Replaces the token stream and fully resets parser-owned state.
    pub fn set_token_stream(&mut self, input: CommonTokenStream<L>) {
        self.base.set_token_stream(input);
        if let Some(simulator) = self.simulator.as_mut() {
            simulator.reset();
        }
    }

    #[must_use]
    pub const fn token_stream(&self) -> &CommonTokenStream<L> {
        self.base.token_stream()
    }

    #[must_use]
    pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<L> {
        self.base.token_stream_mut()
    }

    #[must_use]
    pub const fn token_store(&self) -> &antlr4_runtime::TokenStore {
        self.base.token_store()
    }

    #[must_use]
    pub const fn parse_tree_storage(&self) -> &antlr4_runtime::ParseTreeStorage {
        self.base.parse_tree_storage()
    }

    #[must_use]
    pub fn prediction_context_stats(&self) -> antlr4_runtime::PredictionContextStats {
        self.simulator.as_ref().map_or_else(
            antlr4_runtime::PredictionContextStats::default,
            antlr4_runtime::ParserAtnSimulator::prediction_context_stats,
        )
    }

    #[must_use]
    pub fn parser_dfa_stats(&self) -> antlr4_runtime::ParserDfaStats {
        self.simulator.as_ref().map_or_else(
            antlr4_runtime::ParserDfaStats::default,
            antlr4_runtime::ParserAtnSimulator::parser_dfa_stats,
        )
    }

    /// Clears this grammar's learned parser decision DFAs.
    pub fn clear_dfa(&mut self) {
        if let Some(simulator) = self.simulator.as_mut() {
            simulator.clear_dfa();
        } else {
            antlr4_runtime::ParserAtnSimulator::clear_shared_dfa(atn());
        }
    }

    #[must_use]
    pub fn node(&self, id: antlr4_runtime::NodeId) -> antlr4_runtime::Node<'_> {
        self.base.node(id)
    }

    #[must_use]
    pub fn into_token_stream(self) -> CommonTokenStream<L> {
        self.base.into_token_stream()
    }

    #[must_use]
    pub fn into_token_store(self) -> antlr4_runtime::TokenStore {
        self.base.into_token_store()
    }

    #[must_use]
    pub fn into_parsed_file(self, root: antlr4_runtime::NodeId) -> antlr4_runtime::ParsedFile {
        self.base.into_parsed_file(root)
    }

    /// Compiles a tree pattern rooted at parser rule `rule_index`.
    ///
    /// Mirrors ANTLR's `Parser.compileParseTreePattern`. Literal chunks of
    /// `pattern` are lexed with a fresh lexer built by `make_lexer` (pass this
    /// grammar's generated lexer constructor, e.g. `MyGrammarLexer::new`);
    /// `<tag>` placeholders become rule/token references matched over a
    /// rule-bypass ATN. The returned [`antlr4_runtime::ParseTreePattern`] can
    /// then match subtrees.
    ///
    /// Takes `&self` only to mirror ANTLR's instance method; the ATN and
    /// grammar metadata come from this module, so the parser's own state is
    /// untouched. The pattern compiler (and its rule-bypass ATN) is built once
    /// per process and shared by every call.
    ///
    /// # Errors
    ///
    /// Returns a [`antlr4_runtime::ParseTreePatternError`] for a malformed
    /// pattern, an unknown tag, a lexer failure, or a pattern the start rule
    /// does not parse cleanly and fully consume.
    pub fn compile_parse_tree_pattern<PL>(
        &self,
        pattern: &str,
        rule_index: usize,
        mut make_lexer: impl FnMut(antlr4_runtime::InputStream) -> PL,
    ) -> Result<antlr4_runtime::ParseTreePattern, antlr4_runtime::ParseTreePatternError>
    where
        PL: antlr4_runtime::TokenSource,
    {
        // The rule-bypass ATN derivation inside `ParseTreePatternMatcher::new`
        // is O(states + transitions), so — like ANTLR's
        // `Parser.bypassAltsAtnCache` — the matcher is built once per process
        // and shared by every subsequent compile. A failed build is not cached
        // and is retried (and re-reported) on the next call.
        static PATTERN_DATA: OnceLock<RecognizerData> = OnceLock::new();
        static PATTERN_MATCHER: OnceLock<antlr4_runtime::ParseTreePatternMatcher<'static>> =
            OnceLock::new();
        let matcher = match PATTERN_MATCHER.get() {
            Some(matcher) => matcher,
            None => {
                let data = PATTERN_DATA.get_or_init(|| {
                    let grammar_metadata = metadata();
                    grammar_metadata.recognizer_data()
                });
                let matcher = antlr4_runtime::ParseTreePatternMatcher::new(parser_atn(), data)?;
                PATTERN_MATCHER.get_or_init(|| matcher)
            }
        };
        matcher.compile(pattern, rule_index, move |text: &str| {
            antlr4_runtime::lex_pattern_chunk(text, &mut make_lexer)
        })
    }

    #[allow(dead_code)]
    fn simulator(&mut self) -> &mut antlr4_runtime::ParserAtnSimulator<'static> {
        self.simulator
            .get_or_insert_with(|| antlr4_runtime::ParserAtnSimulator::new_shared(atn()))
    }

    #[allow(dead_code)]
    fn generated_only(&self) -> bool {
        self.generated_only
    }

    #[allow(dead_code)]
    fn parse_rule(&mut self, rule_index: usize) -> Result<antlr4_runtime::ParseTree, antlr4_runtime::AntlrError> {
        self.parse_rule_precedence(rule_index, 0)
    }

    #[allow(dead_code)]
    fn parse_rule_precedence(&mut self, rule_index: usize, precedence: i32) -> Result<antlr4_runtime::ParseTree, antlr4_runtime::AntlrError> {
        self.parse_rule_precedence_inner(rule_index, precedence, true)
    }

    #[allow(dead_code)]
    fn parse_rule_precedence_from_generated(&mut self, rule_index: usize, precedence: i32) -> Result<antlr4_runtime::ParseTree, antlr4_runtime::AntlrError> {
        self.parse_rule_precedence_inner(rule_index, precedence, false)
    }

    #[allow(dead_code)]
    fn parse_rule_precedence_inner(&mut self, rule_index: usize, precedence: i32, allow_generated_fallback: bool) -> Result<antlr4_runtime::ParseTree, antlr4_runtime::AntlrError> {
        if allow_generated_fallback {
            // True top-level entry: drop any fail-loud coordinates left by a
            // previous parse so a reused parser starts clean. Mid-parse the hits
            // are preserved so a generated parent can surface a recovered child's
            // fail-loud coordinate at this boundary.
            self.base.reset_unknown_semantic_hits();
            // Likewise drop stale sticky aborts (depth-cap violation,
            // parse-listener abort): entry rules share one parser instance,
            // and the flags must not poison the next parse when the previous
            // one exited through an error path.
            let _ = self.base.take_parse_abort();
        }
        let __rule_start = antlr4_runtime::IntStream::index(self.base.input());
        let __generated_only = self.generated_only();
        let __tree = if let Some(result) = self.parse_generated_rule(rule_index, precedence, allow_generated_fallback) {
            match result {
                Ok(tree) => tree,
                Err(error) => {
                    antlr4_runtime::IntStream::seek(self.base.input(), __rule_start);
                    let __report_error =
                        matches!(&error, GeneratedRuleError::Fatal(_));
                    // A fatal unwind retains recovery diagnostics committed
                    // earlier in this entry. Dispatch them before a semantic
                    // or parser-abort override can return, or they would leak
                    // into the next entry on a reused parser.
                    if allow_generated_fallback && __report_error {
                        self.base.report_generated_parser_diagnostics();
                    }
                    // A generated predicate that consulted an unimplemented hook
                    // (returning None under the Error policy) fails the alternative
                    // and surfaces here as a generic failed-predicate/rule error.
                    // The documented contract is to fail loud with
                    // `AntlrError::Unsupported`, so prefer a recorded semantic error
                    // over the generic one — but only at the top-level entry, mirroring
                    // the post-parse check below: a nested child keeps its hits so the
                    // generated parent surfaces them at that boundary instead.
                    if allow_generated_fallback {
                        if let Some(semantic_error) = self.base.take_unknown_semantic_error() {
                            return Err(semantic_error);
                        }
                        // A sticky abort (depth cap, listener) wins over an
                        // error derived from it (e.g. a sync failure after
                        // recovery absorbed the aborted rule): the caller must
                        // learn the real cause, and draining un-poisons the
                        // instance for the next entry-rule call.
                        if let Some(abort) = self.base.take_parse_abort() {
                            return Err(abort);
                        }
                    }
                    let error = error.into_error();
                    if allow_generated_fallback && __report_error {
                        self.base.report_unrecovered_parser_error(&error);
                    }
                    return Err(error);
                }
            }
        } else if __generated_only {
            return Err(antlr4_runtime::AntlrError::Unsupported(format!("generated parser did not emit rule {}", rule_index)));
        } else {
            self.parse_interpreted_rule_precedence(rule_index, precedence)?
        };
        // Surface unknown-predicate coordinates recorded under the Error policy
        // at the top-level entry. Generated predicate steps evaluate on the
        // committed path and are recovered as rule errors, so a parse that
        // consulted an unimplemented hook predicate must fail with
        // `AntlrError::Unsupported` instead of returning a recovered `Ok` tree.
        if allow_generated_fallback {
            if let Some(error) = self.base.take_unknown_semantic_error() {
                return Err(error);
            }
        }
        if allow_generated_fallback {
            self.base.report_generated_parser_diagnostics();
            if let Some(error) = self.base.take_unknown_semantic_error() {
                return Err(error);
            }
            // A sticky abort (depth-cap violation, listener abort) is not a
            // syntax error: rule-level recovery may have produced a tree
            // anyway, but the parse must still fail (and a reused parser
            // must start clean).
            if let Some(error) = self.base.take_parse_abort() {
                return Err(error);
            }
        }
        Ok(__tree)
    }

    #[allow(dead_code)]
    fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<antlr4_runtime::ParseTree, antlr4_runtime::AntlrError> {
        self.parse_interpreted_rule_precedence(rule_index, 0)
    }

    #[allow(dead_code)]
    fn parse_interpreted_rule_precedence(&mut self, rule_index: usize, precedence: i32) -> Result<antlr4_runtime::ParseTree, antlr4_runtime::AntlrError> {
        if precedence == 0 && false && std::env::var_os("ANTLR4_RUST_ADAPTIVE_DIRECT").is_some() {
            let simulator = self
                .simulator
                .get_or_insert_with(|| antlr4_runtime::ParserAtnSimulator::new_shared(atn()));
            self.base
                .parse_atn_rule_adaptive_or_fallback(atn(), simulator, rule_index)
        } else {
        let (tree, actions) = self.base.parse_atn_rule_with_runtime_options_and_precedence(atn(), rule_index, precedence, antlr4_runtime::ParserRuntimeOptions { track_alt_numbers: false, track_context_alt_numbers: false, predicates: &[], semantics: Some(parser_semantics()), rule_args: &[], member_actions: &[], return_actions: &[], unknown_predicate_policy: antlr4_runtime::UnknownSemanticPolicy::Error , ..antlr4_runtime::ParserRuntimeOptions::default() })?;
```rust

---

Found a 5 line (1075 tokens) duplication in the following files:
* Starting at line 141 of src/bin_support/rust_syntax/generated/rust_lexer.rs
* Starting at line 357 of src/bin_support/rust_syntax/generated/rust_parser.rs

```rust
    &["T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", "T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", "T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "T__39", "T__40", "T__41", "T__42", "T__43", "T__44", "T__45", "T__46", "T__47", "T__48", "T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56", "T__57", "T__58", "T__59", "T__60", "T__61", "T__62", "T__63", "T__64", "T__65", "T__66", "T__67", "T__68", "T__69", "T__70", "T__71", "T__72", "T__73", "T__74", "T__75", "T__76", "T__77", "T__78", "T__79", "T__80", "T__81", "T__82", "T__83", "T__84", "T__85", "T__86", "T__87", "T__88", "T__89", "T__90", "T__91", "T__92", "T__93", "T__94", "T__95", "T__96", "T__97", "T__98", "T__99", "XID_Start", "XID_Continue", "CashMoney", "RawIdentifier", "IDENT", "Lifetime", "Ident", "SIMPLE_ESCAPE", "CHAR", "CharLit", "OTHER_STRING_ELEMENT", "STRING_ELEMENT", "RAW_CHAR", "RAW_STRING_BODY", "StringLit", "C_STRING_CHAR", "C_BYTE_ESCAPE", "C_UNICODE_ESCAPE", "C_UNICODE_HEX_TAIL_5", "C_UNICODE_HEX_TAIL_4", "C_UNICODE_HEX_TAIL_3", "C_UNICODE_HEX_TAIL_2", "C_UNICODE_HEX_TAIL_1", "C_UNICODE_HEX_TAIL_0", "C_STRING_ELEMENT", "C_RAW_CHAR", "C_RAW_STRING_BODY", "CStringLit", "BYTE", "ByteLit", "BYTE_STRING_ELEMENT", "RAW_BYTE_STRING_BODY", "ByteStringLit", "DEC_DIGITS", "BareIntLit", "INT_SUFFIX", "FullIntLit", "EXPONENT", "FLOAT_SUFFIX", "FloatLit", "Whitespace", "LineComment", "BlockComment", "TupleIndex", "Shebang"],
    &[None, Some("\'pub\'"), Some("\'crate\'"), Some("\'(\'"), Some("\')\'"), Some("\'self\'"), Some("\'super\'"), Some("\'in\'"), Some("\'\\\'\'"), Some("\'extern\'"), Some("\';\'"), Some("\'use\'"), Some("\'::\'"), Some("\'{\'"), Some("\'}\'"), Some("\'*\'"), Some("\',\'"), Some("\'as\'"), Some("\'_\'"), Some("\'mod\'"), Some("\'unsafe\'"), Some("\'safe\'"), Some("\'static\'"), Some("\'mut\'"), Some("\':\'"), Some("\'=\'"), Some("\'type\'"), Some("\'default\'"), Some("\'const\'"), Some("\'macro\'"), Some("\'async\'"), Some("\'fn\'"), Some("\'...\'"), Some("\'&\'"), Some("\'impl\'"), Some("\'ref\'"), Some("\'&&\'"), Some("\'->\'"), Some("\'struct\'"), Some("\'enum\'"), Some("\'union\'"), Some("\'auto\'"), Some("\'trait\'"), Some("\'?\'"), Some("\'!\'"), Some("\'for\'"), Some("\'..\'"), Some("\'#\'"), Some("\'[\'"), Some("\']\'"), Some("\'<\'"), Some("\'>\'"), Some("\'Self\'"), Some("\'$crate\'"), Some("\'+\'"), Some("\'raw\'"), Some("\'where\'"), Some("\'dyn\'"), Some("\'true\'"), Some("\'false\'"), Some("\'-\'"), Some("\'|\'"), Some("\'@\'"), Some("\'..=\'"), Some("\'box\'"), Some("\'let\'"), Some("\'else\'"), Some("\'match\'"), Some("\'loop\'"), Some("\'try\'"), Some("\'if\'"), Some("\'while\'"), Some("\'=>\'"), Some("\'move\'"), Some("\'break\'"), Some("\'continue\'"), Some("\'return\'"), Some("\'yield\'"), Some("\'.\'"), Some("\'||\'"), Some("\'|_|\'"), Some("\'/\'"), Some("\'%\'"), Some("\'^\'"), Some("\'==\'"), Some("\'!=\'"), Some("\'<=\'"), Some("\'>=\'"), Some("\'*=\'"), Some("\'/=\'"), Some("\'%=\'"), Some("\'+=\'"), Some("\'-=\'"), Some("\'<<=\'"), Some("\'>>=\'"), Some("\'&=\'"), Some("\'^=\'"), Some("\'|=\'"), Some("\'macro_rules\'"), Some("\'\\\'static\'"), Some("\'\\\'_\'"), Some("\'$\'"), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
    &[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, Some("CashMoney"), Some("RawIdentifier"), Some("Lifetime"), Some("Ident"), Some("CharLit"), Some("StringLit"), Some("CStringLit"), Some("ByteLit"), Some("ByteStringLit"), Some("BareIntLit"), Some("FullIntLit"), Some("FloatLit"), Some("Whitespace"), Some("LineComment"), Some("BlockComment"), Some("TupleIndex"), Some("Shebang")],
    &[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
    &["DEFAULT_TOKEN_CHANNEL", "HIDDEN"],

Found a 76 line (996 tokens) duplication in the following files:

  • Starting at line 18595 of src/bin_support/grammar/generated/antlr_v4_parser.rs
  • Starting at line 55196 of src/bin_support/rust_syntax/generated/rust_parser.rs
        Ok(tree)
        }
    }

    #[allow(dead_code)]
    fn parse_generated_rule(&mut self, rule_index: usize, precedence: i32, allow_fallback: bool) -> Option<Result<antlr4_runtime::ParseTree, GeneratedRuleError>> {
        let _ = precedence;
        let _ = allow_fallback;
        match rule_index {
            0 => Some(self.parse_generated_rule_0_dispatch(precedence, allow_fallback)),
            1 => Some(self.parse_generated_rule_1_dispatch(precedence, allow_fallback)),
            2 => Some(self.parse_generated_rule_2_dispatch(precedence, allow_fallback)),
            3 => Some(self.parse_generated_rule_3_dispatch(precedence, allow_fallback)),
            4 => Some(self.parse_generated_rule_4_dispatch(precedence, allow_fallback)),
            5 => Some(self.parse_generated_rule_5_dispatch(precedence, allow_fallback)),
            6 => Some(self.parse_generated_rule_6_dispatch(precedence, allow_fallback)),
            7 => Some(self.parse_generated_rule_7_dispatch(precedence, allow_fallback)),
            8 => Some(self.parse_generated_rule_8_dispatch(precedence, allow_fallback)),
            9 => Some(self.parse_generated_rule_9_dispatch(precedence, allow_fallback)),
            10 => Some(self.parse_generated_rule_10_dispatch(precedence, allow_fallback)),
            11 => Some(self.parse_generated_rule_11_dispatch(precedence, allow_fallback)),
            12 => Some(self.parse_generated_rule_12_dispatch(precedence, allow_fallback)),
            13 => Some(self.parse_generated_rule_13_dispatch(precedence, allow_fallback)),
            14 => Some(self.parse_generated_rule_14_dispatch(precedence, allow_fallback)),
            15 => Some(self.parse_generated_rule_15_dispatch(precedence, allow_fallback)),
            16 => Some(self.parse_generated_rule_16_dispatch(precedence, allow_fallback)),
            17 => Some(self.parse_generated_rule_17_dispatch(precedence, allow_fallback)),
            18 => Some(self.parse_generated_rule_18_dispatch(precedence, allow_fallback)),
            19 => Some(self.parse_generated_rule_19_dispatch(precedence, allow_fallback)),
            20 => Some(self.parse_generated_rule_20_dispatch(precedence, allow_fallback)),
            21 => Some(self.parse_generated_rule_21_dispatch(precedence, allow_fallback)),
            22 => Some(self.parse_generated_rule_22_dispatch(precedence, allow_fallback)),
            23 => Some(self.parse_generated_rule_23_dispatch(precedence, allow_fallback)),
            24 => Some(self.parse_generated_rule_24_dispatch(precedence, allow_fallback)),
            25 => Some(self.parse_generated_rule_25_dispatch(precedence, allow_fallback)),
            26 => Some(self.parse_generated_rule_26_dispatch(precedence, allow_fallback)),
            27 => Some(self.parse_generated_rule_27_dispatch(precedence, allow_fallback)),
            28 => Some(self.parse_generated_rule_28_dispatch(precedence, allow_fallback)),
            29 => Some(self.parse_generated_rule_29_dispatch(precedence, allow_fallback)),
            30 => Some(self.parse_generated_rule_30_dispatch(precedence, allow_fallback)),
            31 => Some(self.parse_generated_rule_31_dispatch(precedence, allow_fallback)),
            32 => Some(self.parse_generated_rule_32_dispatch(precedence, allow_fallback)),
            33 => Some(self.parse_generated_rule_33_dispatch(precedence, allow_fallback)),
            34 => Some(self.parse_generated_rule_34_dispatch(precedence, allow_fallback)),
            35 => Some(self.parse_generated_rule_35_dispatch(precedence, allow_fallback)),
            36 => Some(self.parse_generated_rule_36_dispatch(precedence, allow_fallback)),
            37 => Some(self.parse_generated_rule_37_dispatch(precedence, allow_fallback)),
            38 => Some(self.parse_generated_rule_38_dispatch(precedence, allow_fallback)),
            39 => Some(self.parse_generated_rule_39_dispatch(precedence, allow_fallback)),
            40 => Some(self.parse_generated_rule_40_dispatch(precedence, allow_fallback)),
            41 => Some(self.parse_generated_rule_41_dispatch(precedence, allow_fallback)),
            42 => Some(self.parse_generated_rule_42_dispatch(precedence, allow_fallback)),
            43 => Some(self.parse_generated_rule_43_dispatch(precedence, allow_fallback)),
            44 => Some(self.parse_generated_rule_44_dispatch(precedence, allow_fallback)),
            45 => Some(self.parse_generated_rule_45_dispatch(precedence, allow_fallback)),
            46 => Some(self.parse_generated_rule_46_dispatch(precedence, allow_fallback)),
            47 => Some(self.parse_generated_rule_47_dispatch(precedence, allow_fallback)),
            48 => Some(self.parse_generated_rule_48_dispatch(precedence, allow_fallback)),
            49 => Some(self.parse_generated_rule_49_dispatch(precedence, allow_fallback)),
            50 => Some(self.parse_generated_rule_50_dispatch(precedence, allow_fallback)),
            51 => Some(self.parse_generated_rule_51_dispatch(precedence, allow_fallback)),
            52 => Some(self.parse_generated_rule_52_dispatch(precedence, allow_fallback)),
            53 => Some(self.parse_generated_rule_53_dispatch(precedence, allow_fallback)),
            54 => Some(self.parse_generated_rule_54_dispatch(precedence, allow_fallback)),
            55 => Some(self.parse_generated_rule_55_dispatch(precedence, allow_fallback)),
            56 => Some(self.parse_generated_rule_56_dispatch(precedence, allow_fallback)),
            57 => Some(self.parse_generated_rule_57_dispatch(precedence, allow_fallback)),
            58 => Some(self.parse_generated_rule_58_dispatch(precedence, allow_fallback)),
            59 => Some(self.parse_generated_rule_59_dispatch(precedence, allow_fallback)),
            60 => Some(self.parse_generated_rule_60_dispatch(precedence, allow_fallback)),
            61 => Some(self.parse_generated_rule_61_dispatch(precedence, allow_fallback)),
            62 => Some(self.parse_generated_rule_62_dispatch(precedence, allow_fallback)),
            63 => Some(self.parse_generated_rule_63_dispatch(precedence, allow_fallback)),
            64 => Some(self.parse_generated_rule_64_dispatch(precedence, allow_fallback)),
            65 => Some(self.parse_generated_rule_65_dispatch(precedence, allow_fallback)),
            66 => Some(self.parse_generated_rule_66_dispatch(precedence, allow_fallback)),
```rust

---

Found a 122 line (949 tokens) duplication in the following files:
* Starting at line 14 of src/bin_support/rust_syntax/generated/rust_lexer.rs
* Starting at line 17 of src/bin_support/rust_syntax/generated/rust_parser.rs

```rust
use std::sync::OnceLock;

pub const EOF: i32 = antlr4_runtime::TOKEN_EOF;
pub const T__0: i32 = 1;
pub const T__1: i32 = 2;
pub const T__2: i32 = 3;
pub const T__3: i32 = 4;
pub const T__4: i32 = 5;
pub const T__5: i32 = 6;
pub const T__6: i32 = 7;
pub const T__7: i32 = 8;
pub const T__8: i32 = 9;
pub const T__9: i32 = 10;
pub const T__10: i32 = 11;
pub const T__11: i32 = 12;
pub const T__12: i32 = 13;
pub const T__13: i32 = 14;
pub const T__14: i32 = 15;
pub const T__15: i32 = 16;
pub const T__16: i32 = 17;
pub const T__17: i32 = 18;
pub const T__18: i32 = 19;
pub const T__19: i32 = 20;
pub const T__20: i32 = 21;
pub const T__21: i32 = 22;
pub const T__22: i32 = 23;
pub const T__23: i32 = 24;
pub const T__24: i32 = 25;
pub const T__25: i32 = 26;
pub const T__26: i32 = 27;
pub const T__27: i32 = 28;
pub const T__28: i32 = 29;
pub const T__29: i32 = 30;
pub const T__30: i32 = 31;
pub const T__31: i32 = 32;
pub const T__32: i32 = 33;
pub const T__33: i32 = 34;
pub const T__34: i32 = 35;
pub const T__35: i32 = 36;
pub const T__36: i32 = 37;
pub const T__37: i32 = 38;
pub const T__38: i32 = 39;
pub const T__39: i32 = 40;
pub const T__40: i32 = 41;
pub const T__41: i32 = 42;
pub const T__42: i32 = 43;
pub const T__43: i32 = 44;
pub const T__44: i32 = 45;
pub const T__45: i32 = 46;
pub const T__46: i32 = 47;
pub const T__47: i32 = 48;
pub const T__48: i32 = 49;
pub const T__49: i32 = 50;
pub const T__50: i32 = 51;
pub const T__51: i32 = 52;
pub const T__52: i32 = 53;
pub const T__53: i32 = 54;
pub const T__54: i32 = 55;
pub const T__55: i32 = 56;
pub const T__56: i32 = 57;
pub const T__57: i32 = 58;
pub const T__58: i32 = 59;
pub const T__59: i32 = 60;
pub const T__60: i32 = 61;
pub const T__61: i32 = 62;
pub const T__62: i32 = 63;
pub const T__63: i32 = 64;
pub const T__64: i32 = 65;
pub const T__65: i32 = 66;
pub const T__66: i32 = 67;
pub const T__67: i32 = 68;
pub const T__68: i32 = 69;
pub const T__69: i32 = 70;
pub const T__70: i32 = 71;
pub const T__71: i32 = 72;
pub const T__72: i32 = 73;
pub const T__73: i32 = 74;
pub const T__74: i32 = 75;
pub const T__75: i32 = 76;
pub const T__76: i32 = 77;
pub const T__77: i32 = 78;
pub const T__78: i32 = 79;
pub const T__79: i32 = 80;
pub const T__80: i32 = 81;
pub const T__81: i32 = 82;
pub const T__82: i32 = 83;
pub const T__83: i32 = 84;
pub const T__84: i32 = 85;
pub const T__85: i32 = 86;
pub const T__86: i32 = 87;
pub const T__87: i32 = 88;
pub const T__88: i32 = 89;
pub const T__89: i32 = 90;
pub const T__90: i32 = 91;
pub const T__91: i32 = 92;
pub const T__92: i32 = 93;
pub const T__93: i32 = 94;
pub const T__94: i32 = 95;
pub const T__95: i32 = 96;
pub const T__96: i32 = 97;
pub const T__97: i32 = 98;
pub const T__98: i32 = 99;
pub const T__99: i32 = 100;
pub const CASH_MONEY: i32 = 101;
pub const RAW_IDENTIFIER: i32 = 102;
pub const LIFETIME: i32 = 103;
pub const IDENT: i32 = 104;
pub const CHAR_LIT: i32 = 105;
pub const STRING_LIT: i32 = 106;
pub const C_STRING_LIT: i32 = 107;
pub const BYTE_LIT: i32 = 108;
pub const BYTE_STRING_LIT: i32 = 109;
pub const BARE_INT_LIT: i32 = 110;
pub const FULL_INT_LIT: i32 = 111;
pub const FLOAT_LIT: i32 = 112;
pub const WHITESPACE: i32 = 113;
pub const LINE_COMMENT: i32 = 114;
pub const BLOCK_COMMENT: i32 = 115;
pub const TUPLE_INDEX: i32 = 116;
pub const SHEBANG: i32 = 117;

pub const CHANNEL_DEFAULT_TOKEN_CHANNEL: i32 = 0;

Found a 5 line (823 tokens) duplication in the following files:

  • Starting at line 103 of src/bin_support/grammar/generated/antlr_v4_lexer.rs
  • Starting at line 167 of src/bin_support/grammar/generated/antlr_v4_parser.rs
    &["DOC_COMMENT", "BLOCK_COMMENT", "LINE_COMMENT", "INT", "STRING_LITERAL", "UNTERMINATED_STRING_LITERAL", "BEGIN_ARGUMENT", "ACTION", "NESTED_ACTION", "ApostropheIdentifier", "OPTIONS", "TOKENS", "CHANNELS", "IMPORT", "FRAGMENT", "LEXER", "PARSER", "GRAMMAR", "PROTECTED", "PUBLIC", "PRIVATE", "RETURNS", "LOCALS", "THROWS", "CATCH", "FINALLY", "MODE", "COLON", "COLONCOLON", "COMMA", "SEMI", "LPAREN", "RPAREN", "RBRACE", "RARROW", "LT", "GT", "ASSIGN", "QUESTION", "STAR", "PLUS_ASSIGN", "PLUS", "OR", "DOLLAR", "RANGE", "DOT", "AT", "POUND", "NOT", "ID", "WS", "NESTED_ARGUMENT", "ARGUMENT_ESCAPE", "ARGUMENT_STRING_LITERAL", "ARGUMENT_CHAR_LITERAL", "END_ARGUMENT", "UNTERMINATED_ARGUMENT", "ARGUMENT_CONTENT", "LEXER_CHAR_SET_BODY", "LEXER_CHAR_SET", "UNTERMINATED_CHAR_SET", "ESC_SEQUENCE", "HexDigit", "UnicodeESC", "DoubleQuoteLiteral", "TripleQuoteLiteral", "BacktickQuoteLiteral", "NameChar", "NameStartChar"],
    &[None, None, None, None, None, None, None, Some("\'=\'"), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, Some("\'[\'"), None, None, None, Some("\'import\'"), Some("\'fragment\'"), Some("\'lexer\'"), Some("\'parser\'"), Some("\'grammar\'"), Some("\'protected\'"), Some("\'public\'"), Some("\'private\'"), Some("\'returns\'"), Some("\'locals\'"), Some("\'throws\'"), Some("\'catch\'"), Some("\'finally\'"), Some("\'mode\'"), Some("\':\'"), Some("\'::\'"), Some("\',\'"), Some("\';\'"), Some("\'(\'"), Some("\')\'"), Some("\'}\'"), Some("\'->\'"), Some("\'<\'"), Some("\'>\'"), Some("\'?\'"), Some("\'*\'"), Some("\'+=\'"), Some("\'+\'"), Some("\'|\'"), Some("\'$\'"), Some("\'..\'"), Some("\'.\'"), Some("\'@\'"), Some("\'#\'"), Some("\'~\'"), None, None, None, None, None],
    &[None, None, None, None, Some("ACTION"), Some("ARG_ACTION"), Some("ARG_OR_CHARSET"), Some("ASSIGN"), Some("LEXER_CHAR_SET"), Some("RULE_REF"), Some("SEMPRED"), Some("STRING_LITERAL"), Some("TOKEN_REF"), Some("UNICODE_ESC"), Some("UNICODE_EXTENDED_ESC"), Some("WS"), Some("ALT"), Some("BLOCK"), Some("CLOSURE"), Some("ELEMENT_OPTIONS"), Some("EPSILON"), Some("LEXER_ACTION_CALL"), Some("LEXER_ALT_ACTION"), Some("OPTIONAL"), Some("POSITIVE_CLOSURE"), Some("RULE"), Some("RULEMODIFIERS"), Some("RULES"), Some("SET"), Some("WILDCARD"), Some("DOC_COMMENT"), Some("BLOCK_COMMENT"), Some("LINE_COMMENT"), Some("INT"), Some("UNTERMINATED_STRING_LITERAL"), Some("BEGIN_ARGUMENT"), Some("OPTIONS"), Some("TOKENS"), Some("CHANNELS"), Some("IMPORT"), Some("FRAGMENT"), Some("LEXER"), Some("PARSER"), Some("GRAMMAR"), Some("PROTECTED"), Some("PUBLIC"), Some("PRIVATE"), Some("RETURNS"), Some("LOCALS"), Some("THROWS"), Some("CATCH"), Some("FINALLY"), Some("MODE"), Some("COLON"), Some("COLONCOLON"), Some("COMMA"), Some("SEMI"), Some("LPAREN"), Some("RPAREN"), Some("RBRACE"), Some("RARROW"), Some("LT"), Some("GT"), Some("QUESTION"), Some("STAR"), Some("PLUS_ASSIGN"), Some("PLUS"), Some("OR"), Some("DOLLAR"), Some("RANGE"), Some("DOT"), Some("AT"), Some("POUND"), Some("NOT"), Some("ID"), Some("END_ARGUMENT"), Some("UNTERMINATED_ARGUMENT"), Some("ARGUMENT_CONTENT"), Some("UNTERMINATED_CHAR_SET")],
    &[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
    &["DEFAULT_TOKEN_CHANNEL", "HIDDEN", "OFF_CHANNEL", "COMMENT"],
```rust

---

Found a 80 line (613 tokens) duplication in the following files:
* Starting at line 14 of src/bin_support/grammar/generated/antlr_v4_lexer.rs
* Starting at line 17 of src/bin_support/grammar/generated/antlr_v4_parser.rs

```rust
use std::sync::OnceLock;

pub const EOF: i32 = antlr4_runtime::TOKEN_EOF;
pub const ACTION: i32 = 4;
pub const ARG_ACTION: i32 = 5;
pub const ARG_OR_CHARSET: i32 = 6;
pub const ASSIGN: i32 = 7;
pub const LEXER_CHAR_SET: i32 = 8;
pub const RULE_REF: i32 = 9;
pub const SEMPRED: i32 = 10;
pub const STRING_LITERAL: i32 = 11;
pub const TOKEN_REF: i32 = 12;
pub const UNICODE_ESC: i32 = 13;
pub const UNICODE_EXTENDED_ESC: i32 = 14;
pub const WS: i32 = 15;
pub const ALT: i32 = 16;
pub const BLOCK: i32 = 17;
pub const CLOSURE: i32 = 18;
pub const ELEMENT_OPTIONS: i32 = 19;
pub const EPSILON: i32 = 20;
pub const LEXER_ACTION_CALL: i32 = 21;
pub const LEXER_ALT_ACTION: i32 = 22;
pub const OPTIONAL: i32 = 23;
pub const POSITIVE_CLOSURE: i32 = 24;
pub const RULE: i32 = 25;
pub const RULEMODIFIERS: i32 = 26;
pub const RULES: i32 = 27;
pub const SET: i32 = 28;
pub const WILDCARD: i32 = 29;
pub const DOC_COMMENT: i32 = 30;
pub const BLOCK_COMMENT: i32 = 31;
pub const LINE_COMMENT: i32 = 32;
pub const INT: i32 = 33;
pub const UNTERMINATED_STRING_LITERAL: i32 = 34;
pub const BEGIN_ARGUMENT: i32 = 35;
pub const OPTIONS: i32 = 36;
pub const TOKENS: i32 = 37;
pub const CHANNELS: i32 = 38;
pub const IMPORT: i32 = 39;
pub const FRAGMENT: i32 = 40;
pub const LEXER: i32 = 41;
pub const PARSER: i32 = 42;
pub const GRAMMAR: i32 = 43;
pub const PROTECTED: i32 = 44;
pub const PUBLIC: i32 = 45;
pub const PRIVATE: i32 = 46;
pub const RETURNS: i32 = 47;
pub const LOCALS: i32 = 48;
pub const THROWS: i32 = 49;
pub const CATCH: i32 = 50;
pub const FINALLY: i32 = 51;
pub const MODE: i32 = 52;
pub const COLON: i32 = 53;
pub const COLONCOLON: i32 = 54;
pub const COMMA: i32 = 55;
pub const SEMI: i32 = 56;
pub const LPAREN: i32 = 57;
pub const RPAREN: i32 = 58;
pub const RBRACE: i32 = 59;
pub const RARROW: i32 = 60;
pub const LT: i32 = 61;
pub const GT: i32 = 62;
pub const QUESTION: i32 = 63;
pub const STAR: i32 = 64;
pub const PLUS_ASSIGN: i32 = 65;
pub const PLUS: i32 = 66;
pub const OR: i32 = 67;
pub const DOLLAR: i32 = 68;
pub const RANGE: i32 = 69;
pub const DOT: i32 = 70;
pub const AT: i32 = 71;
pub const POUND: i32 = 72;
pub const NOT: i32 = 73;
pub const ID: i32 = 74;
pub const END_ARGUMENT: i32 = 75;
pub const UNTERMINATED_ARGUMENT: i32 = 76;
pub const ARGUMENT_CONTENT: i32 = 77;
pub const UNTERMINATED_CHAR_SET: i32 = 78;

pub const CHANNEL_COMMENT: i32 = 3;

Found a 1 line (558 tokens) duplication in the following files:

  • Starting at line 109 of src/bin_support/grammar/generated/antlr_v4_lexer.rs
  • Starting at line 147 of src/bin_support/rust_syntax/generated/rust_lexer.rs
    &[4, 0, 78, 590, 6, -1, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 147, 8, 0, 10, 0, 12, 0, 150, 9, 0, 1, 0, 1, 0, 1, 0, 3, 0, 155, 8, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 163, 8, 1, 10, 1, 12, 1, 166, 9, 1, 1, 1, 1, 1, 1, 1, 3, 1, 171, 8, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 5, 2, 179, 8, 2, 10, 2, 12, 2, 182, 9, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 5, 3, 189, 8, 3, 10, 3, 12, 3, 192, 9, 3, 3, 3, 194, 8, 3, 1, 4, 1, 4, 1, 4, 5, 4, 199, 8, 4, 10, 4, 12, 4, 202, 9, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 5, 5, 209, 8, 5, 10, 5, 12, 5, 212, 9, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 5, 8, 230, 8, 8, 10, 8, 12, 8, 233, 9, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 5, 8, 241, 8, 8, 10, 8, 12, 8, 244, 9, 8, 1, 8, 1, 8, 1, 8, 5, 8, 249, 8, 8, 10, 8, 12, 8, 252, 9, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 260, 8, 9, 1, 9, 1, 9, 5, 9, 264, 8, 9, 10, 9, 12, 9, 267, 9, 9, 3, 9, 269, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 5, 10, 280, 8, 10, 10, 10, 12, 10, 283, 9, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 295, 8, 11, 10, 11, 12, 11, 298, 9, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 5, 12, 312, 8, 12, 10, 12, 12, 12, 315, 9, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 1, 37, 1, 37, 1, 38, 1, 38, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 42, 1, 42, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 1, 49, 1, 49, 5, 49, 472, 8, 49, 10, 49, 12, 49, 475, 9, 49, 1, 50, 4, 50, 478, 8, 50, 11, 50, 12, 50, 479, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 4, 58, 514, 8, 58, 11, 58, 12, 58, 515, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 3, 61, 533, 8, 61, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 3, 63, 542, 8, 63, 3, 63, 544, 8, 63, 3, 63, 546, 8, 63, 3, 63, 548, 8, 63, 1, 64, 1, 64, 1, 64, 5, 64, 553, 8, 64, 10, 64, 12, 64, 556, 9, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 5, 65, 566, 8, 65, 10, 65, 12, 65, 569, 9, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 5, 66, 578, 8, 66, 10, 66, 12, 66, 581, 9, 66, 1, 66, 1, 66, 1, 67, 1, 67, 3, 67, 587, 8, 67, 1, 68, 1, 68, 7, 148, 164, 231, 250, 554, 567, 579, 0, 69, 3, 30, 5, 31, 7, 32, 9, 33, 11, 11, 13, 34, 15, 35, 17, 4, 19, 0, 21, 0, 23, 36, 25, 37, 27, 38, 29, 39, 31, 40, 33, 41, 35, 42, 37, 43, 39, 44, 41, 45, 43, 46, 45, 47, 47, 48, 49, 49, 51, 50, 53, 51, 55, 52, 57, 53, 59, 54, 61, 55, 63, 56, 65, 57, 67, 58, 69, 59, 71, 60, 73, 61, 75, 62, 77, 7, 79, 63, 81, 64, 83, 65, 85, 66, 87, 67, 89, 68, 91, 69, 93, 70, 95, 71, 97, 72, 99, 73, 101, 74, 103, 15, 105, 0, 107, 0, 109, 0, 111, 0, 113, 75, 115, 76, 117, 77, 119, 0, 121, 8, 123, 78, 125, 0, 127, 0, 129, 0, 131, 0, 133, 0, 135, 0, 137, 0, 139, 0, 3, 0, 1, 2, 12, 2, 0, 10, 10, 13, 13, 1, 0, 49, 57, 1, 0, 48, 57, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 5, 0, 34, 34, 39, 39, 92, 92, 96, 96, 123, 123, 4, 0, 9, 10, 12, 13, 32, 32, 65279, 65279, 1, 0, 92, 93, 8, 0, 34, 34, 39, 39, 92, 92, 98, 98, 102, 102, 110, 110, 114, 114, 116, 116, 3, 0, 48, 57, 65, 70, 97, 102, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 5, 0, 48, 57, 95, 95, 183, 183, 768, 879, 8255, 8256, 14, 0, 65, 90, 97, 122, 192, 214, 216, 246, 248, 767, 880, 893, 895, 8191, 8204, 8205, 8304, 8591, 11264, 12271, 12289, 55295, 63744, 64975, 65008, 65278, 65280, 65533, 624, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 1, 105, 1, 0, 0, 0, 1, 107, 1, 0, 0, 0, 1, 109, 1, 0, 0, 0, 1, 111, 1, 0, 0, 0, 1, 113, 1, 0, 0, 0, 1, 115, 1, 0, 0, 0, 1, 117, 1, 0, 0, 0, 2, 

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

@tinovyatkin

Copy link
Copy Markdown
Contributor Author

Addressed the review on head 5c20507de:

  • fixed both token lifetime blockers: lt() returns a view tied to the stream, and get_text() preserves that same lifetime; the generated-project fixture now stores the view across a statement and returns borrowed text from a closure
  • replaced emitted-text scanning with structured input/context/token-alias lowering flags, with an alias-only compile regression
  • kept the <GeneratedParserType>_<TOKEN> prefix intentionally because that is issue codegen: support grammars-v4's observed antlr4rust recog surface #267's compatibility contract; the two pinned split-parser transforms have identical grammar/type prefixes
  • added implicit T__N aliases and compile-checked one in AliasOnly.g4
  • removed the positive out-of-range lt(5) assertion that depended on the runtime's pre-existing non-clamping behavior; negative lookbehind still covers missing-token Option behavior
  • replaced the fragment assertions with an external snapshot and documented automatic embedded-mode compatibility lowering in the README

The final head passes the full workspace suite, exact clippy gate, stage-zero fixed-point check, and runtime conformance (357/357).

@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: 5c20507de3

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@src/bin/antlr4-rust-gen.rs`:
- Around line 9690-9720: In build_embedded_parser_data, add a BTreeMap<SourceId,
Antlr4RustTokenAliasInventory> cache and route each alias-inventory lookup
through it, lazily invoking antlr4rust_token_alias_inventory only on a cache
miss. Reuse the cached inventory for actions, predicates, and rules while
preserving the existing member-symbol filtering and source-specific owner type
resolution.
🪄 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: ec2e8f37-d37c-4826-8f75-a635c326f2b2

📥 Commits

Reviewing files that changed from the base of the PR and between 1b5d805 and 5956e78.

⛔ Files ignored due to path filters (5)
  • src/bin/snapshots/antlr4_rust_gen__tests__antlr4rust_compat_reserved_accessors.snap is excluded by !**/*.snap
  • src/bin_support/snapshots/antlr4_rust_gen__embedded__tests__lowers_only_supported_antlr4rust_code_tokens.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_generated_surface.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_semantics_manifest.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__imported_antlr4rust_alias_owner.snap is excluded by !**/*.snap
📒 Files selected for processing (9)
  • README.md
  • src/bin/antlr4-rust-gen.rs
  • src/bin_support/embedded.rs
  • src/bin_support/grammar/mod.rs
  • tests/antlr4_rust_gen_cli.rs
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/AliasCollision.g4
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/AliasOnly.g4
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/CCompat.g4
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/JavaCompat.g4

Comment thread src/bin/antlr4-rust-gen.rs

@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: 5956e7899e

ℹ️ 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_support/embedded.rs Outdated
Comment thread src/bin_support/embedded.rs
Comment thread src/bin_support/embedded.rs Outdated

@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: 9e95710bca

ℹ️ 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_support/embedded.rs Outdated

@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/bin/antlr4-rust-gen.rs (1)

12591-12623: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Consume live_attrs in attr-less __from_active implementations

__FromActiveRuleContext::__from_active has live_attrs on every generated rule, but generated bodies for rules without locals[...] do not reference it. This emits a Rust unused_variables diagnostic unless downstream projects compile with -D warnings; use an ignored name such as _live_attrs for attr-less contexts, or add a no-op use in that branch.

🤖 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/antlr4-rust-gen.rs` around lines 12591 - 12623, Update the generated
attr-less implementations of __FromActiveRuleContext::__from_active to consume
the live_attrs parameter, preferably by naming it _live_attrs or adding an
equivalent no-op use, while preserving the existing behavior for rules with
locals[...] that use the parameter.
🤖 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/bin/antlr4-rust-gen.rs`:
- Around line 12591-12623: Update the generated attr-less implementations of
__FromActiveRuleContext::__from_active to consume the live_attrs parameter,
preferably by naming it _live_attrs or adding an equivalent no-op use, while
preserving the existing behavior for rules with locals[...] that use the
parameter.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7054431a-3070-4524-b4fb-be41317b5313

📥 Commits

Reviewing files that changed from the base of the PR and between 5956e78 and 9e95710.

⛔ Files ignored due to path filters (6)
  • src/bin_support/grammar/generated/antlr_v4_parser.rs is excluded by !**/generated/**
  • src/bin_support/snapshots/antlr4_rust_gen__embedded__tests__lowers_only_supported_antlr4rust_code_tokens.snap is excluded by !**/*.snap
  • src/bin_support/snapshots/antlr4_rust_gen__embedded__tests__member_module_symbols.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_generated_surface.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_semantics_manifest.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__unsupported_antlr4rust_surface_diagnostics.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • src/bin/antlr4-rust-gen.rs
  • src/bin_support/embedded.rs
  • tests/antlr4_rust_gen_cli.rs
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/AliasCollision.g4
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/JavaCompat.g4
  • third_party/antlr-v4-grammar/self-hosted.sha256

@tinovyatkin

Copy link
Copy Markdown
Contributor Author

Addressed the Claude review in e412ddc6d:

  • compatibility getter reservation and emission now share Rust-keyword escaping; the type regression emits r#type() and compiles
  • compatibility accessor policy is limited to _localctx roots plus metadata-derived child-context reachability, so unrelated contexts retain native text()
  • turbofish commas are handled as nested call syntax
  • ambiguous legacy getter names now fail generation instead of being silently order-dependent
  • token aliases are emitted only for actual unqualified value references, with body-local bindings suppressed

The CodeRabbit outside-diff live_attrs note was also checked. No code change is needed: every generated module is explicitly wrapped in #[allow(warnings, ...)], and the generated-project regression passes under RUSTFLAGS='-D warnings'; renaming that parameter would only create broad stage-0 churn without changing diagnostics.

Validation on this head: focused unit tests (31 passed), issue CLI tests (3 passed), exact warnings-as-errors generated-project test, clippy, fmt, stage-0 fixed point, runtime conformance (357/357), and current transformed C/Java probes from grammars-v4@e756f2a2 under offline warnings-as-errors checks.

@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_support/embedded.rs`:
- Around line 2022-2036: Update the type-annotation lookup used by the binder
scan to ignore colons that are part of a `::` path separator, matching the
separation logic in `is_pattern_path_or_field`. Ensure `find_top_level_lexeme`
only yields a standalone `:` so qualified pattern paths such as `Shape::Point`
do not truncate the scan before local bindings like `CompatParser_ID`.

In `@src/bin/antlr4-rust-gen.rs`:
- Around line 11221-11228: Update antlr4rust_compat_method_name and the
corresponding rust_function_name logic to distinguish non-rawable Rust keywords
(self, crate, super, and Self) from keywords that support raw identifiers.
Preserve raw-name rendering for rawable keywords, and reject or otherwise handle
non-rawable names so generated accessors never emit invalid r# identifiers.
🪄 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: dd237e80-a11d-4726-b2b9-fddd27e1fb99

📥 Commits

Reviewing files that changed from the base of the PR and between 9e95710 and e412ddc.

⛔ Files ignored due to path filters (5)
  • src/bin/snapshots/antlr4_rust_gen__tests__antlr4rust_compat_accessor_collision.snap is excluded by !**/*.snap
  • src/bin/snapshots/antlr4_rust_gen__tests__antlr4rust_compat_reserved_accessors.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_generated_surface.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_semantics_manifest.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_unrelated_context_surface.snap is excluded by !**/*.snap
📒 Files selected for processing (5)
  • src/bin/antlr4-rust-gen.rs
  • src/bin_support/embedded.rs
  • tests/antlr4_rust_gen_cli.rs
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/AliasCollision.g4
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/JavaCompat.g4

Comment thread src/bin_support/embedded.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs

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

ℹ️ 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_support/embedded.rs Outdated
Comment thread src/bin_support/embedded.rs Outdated
Comment thread src/bin/antlr4-rust-gen.rs Outdated
@tinovyatkin

Copy link
Copy Markdown
Contributor Author

Addressed the latest Claude review on head b71697729:

  • token aliases now live in __antlr4rust_token_aliases; only unshadowed value references are qualified, so an alias used in one body cannot turn another body's same-named binding into a constant pattern
  • @members imports such as use self::... as ... are rewritten through that namespace, including aliases referenced only by the import; user symbol collisions are forwarded with cfg-complemented fallbacks
  • lexer actions and predicates validate parser-only recog / _localctx receivers during generation and report the owning grammar coordinate
  • @init and @after lowering errors now use their semantic body spans and report path, line, and column

The follow-up also documents compatibility accessor renaming and labeled-alternative scope, gates binding analysis behind an alias pre-scan, accepts global grouped use trees, respects lexical scopes, and generates legal names for non-rawable Rust keywords.

Validation on this head: generator unit tests (846/846), compatibility CLI/generated-project tests (3/3, including warnings-as-errors compilation and execution), exact clippy, fmt, stage-zero fixed point, and runtime conformance (357/357).

@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 (1)
src/bin/antlr4-rust-gen.rs (1)

9925-10028: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the duplicated @init/@after error mapping.

The two closures at lines 9932-9961 and 9988-10016 are structurally identical. They differ only in the action name ("init" versus "after") and the diagnostic label. Extract one helper that takes the action name and label, and call it from both sites. This keeps the two diagnostics in sync when the message format changes.

♻️ Proposed helper
fn embedded_rule_action_translation_error(
    data: &CodegenData<'_>,
    semantic_rule: Option<&Rule>,
    action_name: &str,
    kind: &str,
    rule_index: usize,
    rule_name: &str,
    error: &io::Error,
) -> io::Error {
    semantic_rule
        .and_then(|semantic_rule| {
            semantic_rule
                .actions
                .iter()
                .find(|action| action.name == action_name)
        })
        .map_or_else(
            || {
                io::Error::new(
                    error.kind(),
                    format!(
                        "cannot lower embedded @{action_name} body for parser rule \
                         {rule_name} ({rule_index}): {error}"
                    ),
                )
            },
            |action| {
                embedded_named_body_translation_error(
                    data,
                    &action.body_span,
                    kind,
                    rule_index,
                    error,
                )
            },
        )
}
🤖 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/antlr4-rust-gen.rs` around lines 9925 - 10028, Extract the duplicated
translation-error mapping from the `@init` and `@after` branches into a shared
embedded_rule_action_translation_error helper accepting the semantic rule,
action name, diagnostic label, rule index, rule name, and error. Replace both
map_err closures in the parser rule translation flow with calls to this helper,
passing "init"/"parser `@init`" and "after"/"parser `@after`" respectively, while
preserving the existing diagnostics.
🤖 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_support/embedded.rs`:
- Around line 5121-5131: Add a second assertion in the test
`lexer_bodies_reject_parser_only_compatibility_receivers` that invokes
`validate_lexer_body_compatibility_receivers` with an `_localctx` receiver
expression, and verify it produces the same parser-only compatibility diagnostic
as the existing `recog.input` case.
- Around line 434-452: Update member_cfg_predicates to normalize or otherwise
group multi-line attribute text before extracting cfg predicates, so each
#[cfg(...)] is parsed as a complete attribute rather than line-by-line. Preserve
existing handling for single-line attributes and ensure multi-line cfg
attributes produce their predicate instead of being treated as unconditional.

---

Outside diff comments:
In `@src/bin/antlr4-rust-gen.rs`:
- Around line 9925-10028: Extract the duplicated translation-error mapping from
the `@init` and `@after` branches into a shared
embedded_rule_action_translation_error helper accepting the semantic rule,
action name, diagnostic label, rule index, rule name, and error. Replace both
map_err closures in the parser rule translation flow with calls to this helper,
passing "init"/"parser `@init`" and "after"/"parser `@after`" respectively, while
preserving the existing diagnostics.
🪄 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: a00b8567-e353-4700-ab25-b5a216d5861b

📥 Commits

Reviewing files that changed from the base of the PR and between e412ddc and b716977.

⛔ Files ignored due to path filters (8)
  • src/bin/snapshots/antlr4_rust_gen__tests__antlr4rust_compat_reserved_accessors.snap is excluded by !**/*.snap
  • src/bin_support/snapshots/antlr4_rust_gen__embedded__tests__antlr4rust_token_alias_lexical_scopes.snap is excluded by !**/*.snap
  • src/bin_support/snapshots/antlr4_rust_gen__embedded__tests__lowers_only_supported_antlr4rust_code_tokens.snap is excluded by !**/*.snap
  • src/bin_support/snapshots/antlr4_rust_gen__embedded__tests__member_module_symbols.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_generated_surface.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_semantics_manifest.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__imported_antlr4rust_alias_owner.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__unsupported_antlr4rust_surface_diagnostics.snap is excluded by !**/*.snap
📒 Files selected for processing (7)
  • README.md
  • src/bin/antlr4-rust-gen.rs
  • src/bin_support/embedded.rs
  • src/bin_support/rust_names.rs
  • tests/antlr4_rust_gen_cli.rs
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/AliasCollision.g4
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/JavaCompat.g4

Comment thread src/bin_support/embedded.rs
Comment thread src/bin_support/embedded.rs

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

ℹ️ 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_support/embedded.rs Outdated
Comment thread src/bin_support/embedded.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 Outdated

@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: 7772aa3894

ℹ️ 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 Outdated
Comment thread src/bin/antlr4-rust-gen.rs
Comment thread src/bin_support/embedded.rs Outdated
Comment thread src/bin_support/embedded.rs Outdated
Comment thread src/bin_support/embedded.rs
@tinovyatkin
tinovyatkin force-pushed the codex/issue-267-antlr4rust-compat branch from 7772aa3 to 3732b75 Compare August 1, 2026 07:21

@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: 3732b75956

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

Copy link
Copy Markdown
Contributor Author

Addressed all nine findings from the preserved Claude review on head 6b915db6a.

  • Replaced the flat Rust heuristics and temporary parser dependency with the pinned, action-free Perses Rust grammar, generated by this project's own antlr4-rust-gen. Typed parse-tree classification now handles block-tail expressions, leading-pipe or-patterns, nested/curried closure parameters, type positions, and value-vs-type declaration namespaces.
  • Added indexed ctx.rule(i) and ctx.TOKEN(i) compatibility getters, and made the token-view facade Clone + Copy.
  • Moved antlr4rust context getters onto __Antlr4RustContext, so native context methods retain their existing Result<_, MissingChildError> API while compatibility actions still receive the expected Option surface.
  • Cleared pending member attributes after fields and attached compatibility-accessor ambiguity errors to the owning grammar rule coordinate.
  • Preserved exact source grammar spelling for alias owners, including combined grammar XML -> XMLParser_ID.

Regression coverage compile-runs block tails, leading or-patterns, curried closures, declaration namespace collisions, indexed rule/token access, copied token views, native fallible accessors, and exact alias-owner spelling.

Post-amend validation passed the repository clippy/fmt/all-target check hooks, focused antlr4rust and Rust-syntax tests, the generated compatibility crate compile/run test, and byte-for-byte Rust recognizer regeneration.

@tinovyatkin

Copy link
Copy Markdown
Contributor Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

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

🤖 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_support/embedded.rs`:
- Around line 541-571: Align embedded::struct_has_value_constructor with
rust_syntax::struct_has_value_constructor so both classify value-namespace
structs identically. Prefer reusing one classifier; otherwise add shared
snapshot coverage for braced, tuple, unit, generic, and where-clause structs and
update both implementations until they agree, preserving alias-shadowing
behavior in MembersModel::module_symbol_cfgs and
RustSyntax::value_binding_byte_starts.

In `@tests/fixtures/antlr4-rust-gen/antlr4rust-compat/CCompat.g4`:
- Around line 12-20: Update the __eof lookahead in the shown assignment
predicate from recog.input.lt(5) to recog.input.lt(4), matching nativeAssignment
and the EOF position for IDENTIFIER ASSIGN IDENTIFIER EOF; preserve the existing
EOF token validation and predicate behavior.

In `@third_party/rust-grammar/README.md`:
- Around line 29-33: Update the regeneration instructions in the README near the
update-generated.sh command to distinguish verification with --check from
regeneration with --update, and include the explicit --update command for
writing generated files.

In `@tools/rust-syntax/update-generated.sh`:
- Around line 50-62: Update the build-and-run flow in update-generated.sh to
resolve antlr4-rust-gen through Cargo instead of assuming
"$repo_root/target/debug". Preserve the existing build flags and generator
arguments, while ensuring configured target directories from CARGO_TARGET_DIR,
--target-dir, or Cargo config are honored.
🪄 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: e8db7ad8-531e-41e7-abf8-14d768d722af

📥 Commits

Reviewing files that changed from the base of the PR and between e412ddc and 6b915db.

⛔ Files ignored due to path filters (18)
  • src/bin/snapshots/antlr4_rust_gen__tests__antlr4rust_compat_accessor_collision.snap is excluded by !**/*.snap
  • src/bin/snapshots/antlr4_rust_gen__tests__antlr4rust_compat_reserved_accessors.snap is excluded by !**/*.snap
  • src/bin_support/grammar/generated/antlr_v4_lexer.rs is excluded by !**/generated/**
  • src/bin_support/grammar/generated/antlr_v4_parser.rs is excluded by !**/generated/**
  • src/bin_support/rust_syntax/generated/decisions.json is excluded by !**/generated/**
  • src/bin_support/rust_syntax/generated/rust_lexer.rs is excluded by !**/generated/**
  • src/bin_support/rust_syntax/generated/rust_parser.rs is excluded by !**/generated/**
  • src/bin_support/rust_syntax/generated/semantics.json is excluded by !**/generated/**
  • src/bin_support/snapshots/antlr4_rust_gen__embedded__tests__antlr4rust_token_alias_lexical_scopes.snap is excluded by !**/*.snap
  • src/bin_support/snapshots/antlr4_rust_gen__embedded__tests__lowers_only_supported_antlr4rust_code_tokens.snap is excluded by !**/*.snap
  • src/bin_support/snapshots/antlr4_rust_gen__embedded__tests__member_module_symbols.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_alias_owner_spelling.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_alias_type_positions.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_generated_surface.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_compat_semantics_manifest.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__antlr4rust_unrelated_context_surface.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__imported_antlr4rust_alias_owner.snap is excluded by !**/*.snap
  • tests/snapshots/antlr4_rust_gen_cli__unsupported_antlr4rust_surface_diagnostics.snap is excluded by !**/*.snap
📒 Files selected for processing (18)
  • Cargo.toml
  • README.md
  • src/bin/antlr4-rust-gen.rs
  • src/bin_support/embedded.rs
  • src/bin_support/grammar/mod.rs
  • src/bin_support/rust_names.rs
  • src/bin_support/rust_syntax/mod.rs
  • tests/antlr4_rust_gen_cli.rs
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/AliasCollision.g4
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/AliasOnly.g4
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/CCompat.g4
  • tests/fixtures/antlr4-rust-gen/antlr4rust-compat/JavaCompat.g4
  • third_party/antlr-v4-grammar/self-hosted.sha256
  • third_party/rust-grammar/LICENSE-APACHE
  • third_party/rust-grammar/LICENSE-MIT
  • third_party/rust-grammar/README.md
  • third_party/rust-grammar/Rust.g4
  • tools/rust-syntax/update-generated.sh

Comment thread src/bin_support/embedded.rs Outdated
Comment thread tests/fixtures/antlr4-rust-gen/antlr4rust-compat/CCompat.g4
Comment thread third_party/rust-grammar/README.md Outdated
Comment thread tools/rust-syntax/update-generated.sh Outdated

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

ℹ️ 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_support/embedded.rs
Comment thread src/bin_support/embedded.rs Outdated
Comment thread src/bin_support/rust_syntax/mod.rs
Comment thread src/bin_support/rust_syntax/mod.rs
Comment thread third_party/rust-grammar/Rust.g4 Outdated
Parse @members use trees by their actual bindings so renamed imports do not suppress metadata-derived aliases, and cache alias inventories per grammar source. Validate la/lt arity during lowering instead of deferring failures to generated Rust compilation.

Pass each rule's live attributes into active compatibility context views. This preserves @init and in-rule mutations before contexts are sealed while native views retain their stored-attribute fallback.

Refresh the self-hosted frontend and expand generated-project coverage for each regression.
Escape legacy accessor names with the same Rust-keyword policy used for native methods, and reserve the escaped spelling before allocating native helpers. Limit compatibility accessors to contexts reached from rules that materialize _localctx, preserving the native context API elsewhere.

Track only referenced token aliases while suppressing body-local bindings, reject ambiguous legacy getter names during generation, and recognize commas inside turbofish arguments. Add compile-and-run and snapshot coverage for each review case.
Route metadata-derived token aliases through a generated namespace and rewrite only unshadowed value references. Forward member collisions through user symbols, preserve cfg activation, and translate member-only imports. This prevents cross-body constant-pattern collisions while respecting lexical bindings and grouped use trees.

Reject parser-only compatibility receivers in lexer bodies and attach source coordinates to @init and @after failures. Generate legal names for non-rawable Rust keywords, and document context-accessor compatibility limits.

Add compile-and-run regressions for cross-body aliases, member imports, cfg-disabled symbols, nested scopes, global grouped uses, lexer diagnostics, and reserved keyword rules.
Make compatibility alias lowering follow member imports, cfg conditions, allocated namespaces, and lexical Rust binding scopes without rewriting user declarations. Materialize typed local-context views at each use and clamp positive LT requests to EOF so generated semantics match ANTLR behavior.

Add compile-and-run coverage for member methods, direct imports, match/control-flow/function bindings, struct fields, same-body attributes, imported combined grammars, and source-backed diagnostics.
Preserve source provenance on each parser member field and item so imported grammars lower metadata aliases against their own generated owner. Apply the same lowering to field initializers.

Track braced struct names as type-only while tuple and unit constructors continue to reserve value aliases. Extend conditional-let bindings through the remaining let-chain condition and generated rule body.

Compile and execute regressions for imported members, member field initializers, namespace collisions, and let-chain bindings.
Distinguish inequality and control-flow body delimiters from macro and struct paths when qualifying metadata token aliases. Stop match-arm binding scans at a block body's own closing brace so comma-less arms do not hide later bindings.

Compile and execute regressions for != aliases, if/while/match heads, and block-bodied match arms without trailing commas.
Preserve alias-shaped identifiers in Rust type positions and derive compatibility owners from the exact source grammar spelling. Vendor the pinned action-free Perses Rust grammar and classify embedded bodies with a recognizer generated by antlr4-rust-gen itself, avoiding a second parser dependency while correctly handling block tails, leading or-patterns, curried closures, and declaration namespaces.

Keep antlr4rust context getters on a compatibility wrapper so native Result-returning accessors remain unchanged. Add indexed child and token getters, source-located ambiguity errors, Copy token views, correct member-attribute ownership, checked-in recognizer regeneration, and compile-checked regressions for the reviewed cases.

Scope const-generic token-shaped bindings through enclosing impl and type items, lower token aliases in member-field const expressions, and allocate the compatibility context wrapper against member symbols. Compile-run the reviewed generic, field-type, and wrapper-collision cases in the generated compatibility crate.

Allocate input-facade and token-view names against member symbols, preserve identifier tokens in arbitrary macros, protect lifetime and loop-label identifiers, and derive function-parameter scopes from parsed function bodies. Cover each reviewed collision and lexical-scope case in typed analysis and the generated compatibility crate.

Fail closed when the generated Rust recognizer reports lexer or parser recovery, preserving source-aware diagnostics instead of rewriting unclassified identifiers. Extend the action-free grammar for let-else statements, reserve compatibility method names when allocating common context accessors, and snapshot the reviewed generated surfaces.

Preserve nested attributes on member fields in declarations and initializers, and attach owning grammar paths to member-field and member-item lowering diagnostics.

Use parsed Rust structure to distinguish const-generic expressions, member method declarations, locally shadowed standard macros, and attribute token trees. Tokenize Unicode identifiers with the runtime ICU XID properties so compatibility suffixes are never rewritten inside larger identifiers.

Honor cfg-gated action-local imports without rewriting their declarations, keep associated constants declaration-only, and extend the generated Rust recognizer for stable inline const blocks. Regenerate the checked-in artifacts and compile-run all three reviewed edge cases.

Restrict member-field initializer attributes to computed cfg predicates so field-only attributes remain on declarations, and reuse the ICU XID tables during lexical scans. Add snapshot and generated-crate regressions for the fresh review findings.
Resolve imported implicit-token aliases through each combined source grammar's literal order while retaining merged numbering for the root owner.

Preserve ANTLR invalid-token semantics for nonpositive lookahead misses, parse stable precise-capture bounds, and keep matches! pattern bindings out of compatibility alias lowering. Add compile-and-run regressions for every path.
Resolve compatibility aliases used only by implicit format captures without changing the format field, while preserving local bindings and opaque macro token trees.

Normalize raw and Unicode member symbols through the Rust lexer, skip prefixed block expressions when finding control-flow bodies, propagate matches! pattern analysis failures, and share implicit-literal ordering with combined grammar splitting.

Recognize stable normal and raw C string literals in the vendored action-free Rust grammar, regenerate the parser, and cover each review case with compile-and-run regressions.
Recognize qualified standard macros and Edition 2024 unsafe extern blocks in the generated Rust syntax analyzer, and keep match-arm bindings scoped across turbofish commas.

Render imported compatibility aliases with a Rust namespace-aware value fallback so type-only imports coexist with token constants while real value imports still win. Regenerate the Rust recognizer and add compile-and-run regressions for each reviewed case.
Preserve formatting captures, macro metavariables, opaque macro aliases, match bindings, and cfg-gated local aliases across compatibility lowering. Extend the self-hosted ANTLR and Rust grammars for apostrophe identifiers, raw lifetimes, safe foreign items, and C-string lexical rules, then regenerate the checked-in recognizers and broaden the compile-and-run fixture.
Use the self-generated Rust CST to recognize imported macro shadowing and to restrict opaque token-alias fallbacks to expression positions. Preserve bare token constants in conditional-let patterns while keeping explicit and nested bindings lexical.

Also deduplicate cfg fallbacks, handle nested block comments and Rust lexical edge cases, and add snapshot plus compile-and-run regressions for the reviewed compatibility surfaces.
Recognize raw macro identifiers and preserve standard format capture lowering when a same-named imported macro is cfg-disabled.

Model cfg-gated lexical bindings, item imports, and function parameters separately so token alias fallbacks remain valid at each Rust scope without turning later let bindings into constant patterns. Cover all four review cases in unit snapshots and the generated compile-and-run fixture.
Balance Rust raw strings while scanning macro_rules definitions, accept associated-type bounds and non-leading let chains in the generated Rust syntax frontend, and preserve compatibility aliases across cfg-gated pattern bindings and relative module paths. Regenerate the vendored recognizer and cover each behavior in the compile-and-run fixture.
Preserve generated token aliases when cfg removes block value items, const generics, closure parameters, or individual pattern bindings. Make opaque type and pattern macro invocations import the aliases their expansions need while excluding their arguments from local binding discovery.

Teach the vendored action-free Rust grammar and action scanner about chained tuple fields, pub(self), and Unicode XID macro_rules names, then regenerate the checked-in recognizer. Extend the generated compile-and-run fixture and snapshots across all reviewed cases, and replace the now-valid tuple-field negative fixture with genuinely invalid Rust.
Skip Rust comments while recognizing macro_rules headers so metavariables remain target syntax. Classify opaque macro invocations by their generated CST ancestry and place compatibility imports at valid module, statement, or associated-item scopes without wrapping item macros as expressions. Model raw references as separate &, raw, and const/mut tokens and regenerate the vendored Rust recognizer.
Honor cfg-disabled bindings in match arms by wrapping the match expression with conditional token-alias fallbacks. Keep recog and _localctx opaque inside macro and attribute token trees, including bodies with no token aliases. Accept Rust discard assignments in the vendored action-free grammar and regenerate its recognizer.
Keep the self-generated Rust syntax frontend from rejecting valid embedded bodies by correcting recursive raw references, exponent underscores, one-sided ranges, attributed higher-ranked lifetimes, const defaults, contextual safe identifiers, Unicode escapes, repeated match attributes, restricted visibility, and empty generic or where lists.

Replace Java UTF-16 identifier tables with scalar XID properties, recognize trailing-dot floats at parser level so range tokenization stays intact, regenerate the checked-in recognizer, and add analyzer plus generated compile-and-run regressions.
Honor cfg-disabled compatibility bindings in for-loop and matches! patterns, including qualified standard macro paths. Decode ordinary Rust string escapes before discovering implicit format captures while preserving raw literal contents.

Accept reviewed foreign-item, variadic, struct-field, and numeric tuple-pattern forms in the vendored action-free Rust grammar, regenerate its recognizer, and cover the behavior with analyzer, lowering, and generated compile/run regressions.
Inject action-reference parsing through semantic and transform analysis so Rust macro_rules! metavariables are filtered only for embedded Rust actions, keeping generic grammar compilation target-agnostic.

Extend the vendored action-free Rust grammar and typed syntax analysis for literal const arguments, impl inner attributes, and locally shadowed relative std/core macro paths. Regenerate the recognizer and cover the generated compatibility behavior.
Classify associated type declarations and foreign static bindings, treat glob imports as potential token-alias shadows, and propagate macro_use definitions into their importing scopes. Accept the atomic >= token in no-struct comparisons and regenerate the dogfooded Rust recognizer on the current complete-LL(1) generator.

Exercise each case in typed analysis snapshots and in the generated compile, link, and runtime fixture.
@tinovyatkin
tinovyatkin force-pushed the codex/issue-267-antlr4rust-compat branch from 24b43e0 to 77d7599 Compare August 2, 2026 13:07

@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: 77d75995dd

ℹ️ 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_support/embedded.rs
Comment thread src/bin_support/rust_syntax/mod.rs
Comment thread src/bin_support/embedded.rs
Comment thread src/bin_support/embedded.rs
@tinovyatkin

Copy link
Copy Markdown
Contributor Author

Final scope verification on 77d75995:

  • grammars-v4@e756f2a2 contains exactly two relevant Rust transforms: c/Rust/transformGrammar.py and java/java/Rust/transformGrammar.py.
  • Re-ran both complete transformed grammars through the current antlr4-rust-gen --actions embedded pipeline.
  • Both generated crates pass offline cargo check with RUSTFLAGS='-D warnings'.
  • The C check includes the untouched 651-line c/Rust/c_parser_base.rs support module.
  • The checked-in, self-generated ANTLR Rust recognizer also parses that complete support file with zero lexer or parser errors.

This confirms #267's compatibility target: the Rust bodies embedded by both real transforms lower and compile successfully. The standalone support module is not rewritten by #267; its discovery/staging, preprocessing, driver lifecycle, and end-to-end C integration remain correctly scoped to #265.

@tinovyatkin

Copy link
Copy Markdown
Contributor Author

@codex review

Please evaluate the exact head against #267's verified observed compatibility contract. The four latest findings were explicitly dispositioned in their threads because they concern synthetic general-Rust namespace collisions absent from both pinned transforms; both complete transformed grammars and the actual C support module compile successfully on this head.

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: 77d75995dd

ℹ️ 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 merged commit f85c971 into main Aug 2, 2026
33 of 34 checks passed
@tinovyatkin
tinovyatkin deleted the codex/issue-267-antlr4rust-compat branch August 2, 2026 13:39
@ophiarch ophiarch Bot mentioned this pull request Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

codegen: support grammars-v4's observed antlr4rust recog surface

1 participant