Skip to content

feat: unify record access syntax - #25

Merged
Seddryck merged 2 commits into
mainfrom
codex/issue-18-record-access
Aug 12, 2026
Merged

feat: unify record access syntax#25
Seddryck merged 2 commits into
mainfrom
codex/issue-18-record-access

Conversation

@Seddryck

@Seddryck Seddryck commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Summary

  • replace legacy [name] / [0] references with unified record access nodes
  • support current-record .name / .0 and original-input ^.name / ^.0
  • support chained named and positional access for nested records
  • preserve $n / $^n as distinct ordered-element access
  • regenerate parser artifacts and document the syntax

Validation

  • npx tree-sitter test --file-name references.txt (13/13 passed)
  • npx tree-sitter test --file-name compound_values.txt (18/18 passed)
  • issue-specific invalid cases passed; two unrelated existing Windows CRLF expectations report \r instead of \n
  • dotnet test Expressif.Syntax.sln --nologo (37/37 passed on each of .NET 8, .NET 9, and .NET 10)

Close #18

Summary by CodeRabbit

  • New Features

    • Added dot-based record access for named and positional fields, such as .name and .0.
    • Added ^ navigation to access fields from the original input record.
    • Supports chained access for nested records and tuples.
  • Breaking Changes

    • Replaced legacy bracket syntax, including [name] and [0], with dot-based access syntax.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

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

Next review available in: 36 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

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

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

How do review limits work?

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

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

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a21ae8bd-b15b-40c3-8faa-dd7819860b4c

📥 Commits

Reviewing files that changed from the base of the PR and between b9d0a6a and d4944c8.

📒 Files selected for processing (7)
  • grammar.js
  • src/grammar.json
  • src/node-types.json
  • src/parser.c
  • test/corpus/compound_values.txt
  • test/corpus/invalid.txt
  • test/corpus/references.txt
📝 Walkthrough

Walkthrough

The parser replaces [name] and [0] record references with .name and .0. The ^ prefix selects the original immutable input. Grammar rules, node types, generated parser tables, documentation, and corpus fixtures are updated.

Changes

Record Access Syntax

Layer / File(s) Summary
Record access grammar and node contract
grammar.js, src/grammar.json, src/node-types.json
Defines dot-separated named and positional selectors with optional ^ roots. Removes bracket-based reference rules and node types.
Generated parser implementation
src/parser.c
Regenerates symbols, lexer states, field mappings, parse tables, and actions for record access.
Syntax fixtures and documentation
README.md, test/corpus/*.txt
Documents the new syntax and updates valid and invalid parse-tree fixtures.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ExpressionText
  participant src/parser.c
  participant record_access
  participant CorpusFixtures
  ExpressionText->>src/parser.c: Parse .name, .0, ^.name, or ^.0
  src/parser.c->>record_access: Build record_access nodes
  record_access->>CorpusFixtures: Match expected parse trees
Loading

Possibly related PRs

  • Seddryck/Expressif.Syntax#2: Extends the initial expression grammar and updates reference syntax, generated parser artifacts, node types, and corpus tests.
  • Seddryck/Expressif.Syntax#21: Adds related positional-element access syntax and updates the shared value-access grammar and reference fixtures.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: unifying record access syntax.
Linked Issues check ✅ Passed The changes implement unified current and original-input record access, nested selectors, legacy syntax replacement, tests, and documentation updates required by issue #18.
Out of Scope Changes check ✅ Passed The changed grammar, parser artifacts, tests, and documentation directly support the objectives in issue #18.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-18-record-access

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.

@Seddryck
Seddryck marked this pull request as ready for review August 12, 2026 16:47

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
test/corpus/references.txt (1)

177-199: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a fixture for a bare ^ with no selector.

record_access uses repeat1, so ^ alone must not parse as a valid node. No fixture pins that rule. A future change to optional or repeat would pass all current tests.

Add the case to test/corpus/invalid.txt.

🤖 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 `@test/corpus/references.txt` around lines 177 - 199, Add an invalid-parser
fixture for a bare `^` with no selector in test/corpus/invalid.txt, ensuring it
is rejected rather than producing a record_access node. Use the existing invalid
fixture format and keep the record_access selector requirement enforced.
test/corpus/compound_values.txt (1)

32-37: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the root: and field: labels to these expected trees.

These fixtures assert node shape only. They do not assert the field mapping. test/corpus/references.txt uses root: and field: in the equivalent cases.

The field map is the part of src/parser.c most likely to regress after a regeneration. Labelled fixtures catch that regression.

♻️ Proposed fixture update
-        (record_access
-          (original_input)
-          (record_field_selector (named_record_field)))
-        (record_access
-          (original_input)
-          (record_field_selector (positional_record_field)))))))
+        (record_access
+          root: (original_input)
+          field: (record_field_selector (named_record_field)))
+        (record_access
+          root: (original_input)
+          field: (record_field_selector (positional_record_field)))))))
-          (record_access
-            (original_input)
-            (record_field_selector (positional_record_field))))
+          (record_access
+            root: (original_input)
+            field: (record_field_selector (positional_record_field))))

Also applies to: 89-91

🤖 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 `@test/corpus/compound_values.txt` around lines 32 - 37, Update the expected
trees in the compound-values fixtures, including the equivalent cases around the
additional referenced lines, to add root: labels for the original_input nodes
and field: labels for the corresponding record_field_selector nodes. Match the
labeling convention used in references.txt so the fixtures validate field
mapping as well as node shape.
🤖 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 `@grammar.js`:
- Around line 110-113: Update record_access in grammar.js so selector
punctuation and fields use immediate tokens, rejecting whitespace within record
references including after original_input; then regenerate src/grammar.json,
src/node-types.json, and src/parser.c. Add invalid.txt fixtures at lines 349-381
covering `. name`, `.customer . address`, and `^ .name`, documenting the
intended rejection behavior.
- Around line 110-124: Align the record-field naming rules by updating the
relevant unquoted declaration pattern to match named_record_field, including
alphanumeric names such as a1, or explicitly preserve the distinction and
document it with corpus cases covering supported quoted/unquoted forms and
rejected unquoted names. Keep record_access and positional_record_field behavior
unchanged.

---

Nitpick comments:
In `@test/corpus/compound_values.txt`:
- Around line 32-37: Update the expected trees in the compound-values fixtures,
including the equivalent cases around the additional referenced lines, to add
root: labels for the original_input nodes and field: labels for the
corresponding record_field_selector nodes. Match the labeling convention used in
references.txt so the fixtures validate field mapping as well as node shape.

In `@test/corpus/references.txt`:
- Around line 177-199: Add an invalid-parser fixture for a bare `^` with no
selector in test/corpus/invalid.txt, ensuring it is rejected rather than
producing a record_access node. Use the existing invalid fixture format and keep
the record_access selector requirement enforced.
🪄 Autofix

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 455ad608-b613-4aac-9ef7-fe63f736b255

📥 Commits

Reviewing files that changed from the base of the PR and between 80cc630 and b9d0a6a.

📒 Files selected for processing (8)
  • README.md
  • grammar.js
  • src/grammar.json
  • src/node-types.json
  • src/parser.c
  • test/corpus/compound_values.txt
  • test/corpus/invalid.txt
  • test/corpus/references.txt

Comment thread grammar.js
Comment thread grammar.js Outdated
@Seddryck
Seddryck merged commit ec079d0 into main Aug 12, 2026
12 checks passed
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.

Unify field and element access syntax between original input and current value

1 participant