Repository navigation
chore(language): a where comparison is one grammar rule over the expression grammar's arithmetic - #565
Merged
Conversation
Documentation build overview
19 files changed ·
|
FBumann
added this pull request to stack #560
September 19, 2026 17:35
FBumann
removed this pull request from stack #560
September 19, 2026 18:10
FBumann
added this pull request to stack #574
September 19, 2026 18:10
FBumann
removed this pull request from stack #574
September 19, 2026 18:12
FBumann
added this pull request to stack #575
September 19, 2026 18:12
FBumann
removed this pull request from stack #575
September 20, 2026 20:34
FBumann
added this pull request to stack #583
September 20, 2026 20:35
…ession grammar's arithmetic The where grammar's three comparison rules — a name against a literal, two relation columns, and position() against an integer — are one rule, side <op> side, where a side is the expression grammar's ARITHMETIC. What a side is, resolution decides with the schema in hand, and it hands back the same typed nodes with the same messages. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EEeM2YoAk4Xr2uWB5qwMsH
…als it points at Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EEeM2YoAk4Xr2uWB5qwMsH
…ather than Any `explicit-any` is an error on `src/math_spec` since #572, and that PR took only the fold's return type from #567, leaving `_nested` on this branch with a signature whose `Any` no longer even imports. `_ParsedWhere` is the union the measurement walks, which is #567's own answer for this file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V2SFmoxEF3SnaPKp7HbZTk
FBumann
force-pushed
the
claude/expression-parser-language-split-kdqegz
branch
from
September 20, 2026 20:51
352a4e6 to
18c3f69
Compare
FBumann
removed this pull request from stack #583
September 20, 2026 20:53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
The following content was generated by AI.
Stacked on #562. The where grammar has one comparison rule,
side <op> side, and a side is the expression grammar's own arithmetic. Resolution reads the two sides with the schema in hand and hands back the same typed nodes with the same messages. This is the half that #469 then lands on as one more branch in that dispatch.What this changes
position()against an integer, are one:(column | ARITHMETIC) <op> (quoted | column | ARITHMETIC), whereARITHMETICis the expression grammar's arithmetic half, now exposed.grouped_by,grouped_within,columns, the signed-number and integer regexes,_position_comparisonand_Quotedare gone.UnresolvedComparisonNode(left, op, right)carries the two sides bare.position(...)arrives as theFunctionCallNodean expression would carry it in, the waydual(...)does. A relation column is aColumnNodeand a quoted label aQuotedNode, since neither has a spelling in an expression.UnresolvedPositionNodeis gone._comparisonreads the sides: aposition()call on the left goes to_position, which reads the dimension,by=andwithin=off the call node; a name or column against a literal or a second column is the plain form the dtype rules are written for, held in a private_Plainand read by the code that read the old node. Every typed node, every message and every test that writes a where string is unchanged.What moved from the grammar into resolution
Two shapes the grammar refused as
Failed to parse where stringare parsed now and refused in resolution, each with a message that names the rewrite. Both are covered inTestAWhereSideIsReadInResolution.c > 2 * k,2 < c,sum(c, over=g) >= k). This refusal is transient: the follow-up PR replaces it with feat(language): a where may compare arithmetic over parameters #469's arithmetic path.position()call not of its shape (position(g, h),position(g, edge=1),position(g, by=[a, b])), or compared against something other than an integer (position(g) == 1.5,position(g) == c).Two inputs change outcome, both because a where side is now read by the expression grammar's literal rules:
c < infloads as a comparison against infinity. Before,infwas read as the bare word'inf'and refused as "comparing it to the string 'inf'".position(g) == 1.0loads as position 1. Before, the integer regex refused it at parse.Rebased onto main at
bda1fc5Merged, not replayed: the hard rule here is never to force-push.
maincamein at the bottom of the stack (#494) and was carried up through every branch
between, so this one's base is current.
Clean at this level: no conflict, and the suite passes unchanged.
Gates
pixi.shis refused by this environment's egress proxy, so the gates ran from auvenvironment on Python 3.12. That is a departure from the "everything runs in a pixi environment" default.pytest -n autoruff check,ruff formatpyrefly checktypos,reuse lintmkdocs build --strictdocs.python.orginventory dropped for the run, which the proxy refuses with a 403compile-texpython -m tools.schemaandpython -m tests.typesetting.goldenwere re-run after the change: neither the schema nor any golden.outfile moved.Coverage moved
test_position_converts_a_dimension_to_where_a_row_sitsasserted the fields ofUnresolvedPositionNode; it istest_position_is_a_call_on_the_left_hand_side, asserting the call node and the literal on the right, with awithin=[a, b]case added.test_a_quoted_right_hand_side_is_a_labelasserted.valueand.quoted; it asserts theQuotedNodeorNameNodeon the right.test_a_position_is_not_confused_with_a_nameargued from the order of the alternation, which no longer exists; the case it protected is intest_position_is_a_call_on_the_left_hand_side.test_a_relation_column_is_named_with_a_dot,test_a_side_is_any_arithmetic_to_the_grammar,test_a_bracketed_predicate_is_still_a_predicate,test_a_where_side_is_held_to_the_depth_an_expression_is, and the two tests inTestAWhereSideIsReadInResolution.Line count
src/is +197 / −115. The grammar module is 8 lines shorter and the resolver 83 longer: the two refusals above are about 30 of those,_position_shape,_side_nameand_Plainthe rest. This PR trades three grammar rules and a grammar-side node for a dispatch in resolution; it does not claim to be a cleanup on its own, and the follow-up removes the transient refusal.🤖 Generated with Claude Code
https://claude.ai/code/session_01EEeM2YoAk4Xr2uWB5qwMsH
Generated by Claude Code
Generated by Claude Code