Result: done Pushed: local 233786b3a7527b20fa5c8c6bba56b9a1969e32bd Tests: tests/compiler –both-settings 548/548 ok; it – grammar 95 passed; nikaia-std –lib grammar:: ok; new grammar_same_line and grammar_same_line_own_ws fail on the old binary (winnow-grammar “Undefined rule: ‘same_line’”) and pass now; clippy, cargo fmt, pre-push green; lower-std fixpoint (second lower-std unchanged) Deviation: none Notes: (1) grammar.rs (Rust) changed as (d) orders: parse/parse_bytes hand every parser a ParseContext with a LineBreaks state (grammars without a state are generic over it, their lowering and call sites are unchanged byte for byte); the record itself is Nikaia, runtime/line_breaks.nika, re-exported as nikaia_std::grammar::LineBreaks. (2) PrTrivia keeps its own end/newline logic: parser/mod.rs reads its fields directly, so making it hold a LineBreaks is a change there (stop list); step 4 can fold it in. (3) The own-WS test writes WS as three rules (SPACE | LINE_COMMENT | BLOCK_COMMENT), not the brief’s inline choice, because of the defect under Found, which is not about same_line. (4) A par_fold entry still writes ParseContext::<()> (emit_core_leaves, other agent’s file in flight): same_line in a par_fold grammar does not compile yet. Found: none Filed: #1149 (lowering defect, pre-existing and separate from same_line: a choice whose alternatives yield different values, unbound, fails in rustc (alt needs one output type), over text and bytes alike. Probe: grammar Q { entry rule t -> String = “x” eof -> { “x” } rule WS = (multispace1 | “//” until(line_ending))* -> { } } then Q::t(“x”) -> rustc “Expected … to return Result<(&str, &str), …>, but it returns Result<&str, …>”. Needs an issue (ready): lower each alternative of such a choice so they yield one type, or have the checker refuse it. Needs: none Changelog: Grammars: same_line matches nothing and fails where the whitespace skipped just before it held a line break (ADR-339 D2), over text and Bytes, with the grammar’s own WS or the default. Body: A grammar that writes same_line (and has no rule of that name) is lowered with a state ::nikaia_std::grammar::LineBreaks;, a WS that records each skipped run with its position (the grammar’s own WS renamed NIKAIA_OWN_WS under it, or multispace0 written out), and extern rule __nikaia_same_line over a function after the grammar! block, one per grammar copy. Every other grammar lowers as before. The record is by position, so an alternative that skipped a break and failed does not change what same_line answers before that break (tested). Unlike the Rust parser’s Trivia, which counts only breaks outside comments, a break anywhere in the skipped run counts, inside a block comment too: a /*\n*/ [0] is an index there and not here. The step 4 port must compare on that. Files: crates/nikaia-std/src/grammar.rs crates/nikaia-std/src/runtime/line_breaks.nika crates/nikaia-std/src/runtime/lowered/line_breaks.rs crates/nikaia-std/src/runtime/lowered.rs crates/nikaia-std/src/tools/check_grammar.nika crates/nikaia-std/src/tools/emit_grammar.nika crates/nikaia-std/src/tools/emit_pattern.nika crates/nikaia-std/src/tools/lowered/check_grammar.rs crates/nikaia-std/src/tools/lowered/emit_grammar.rs crates/nikaia-std/src/tools/lowered/emit_pattern.rs tests/compiler/tests/grammar_same_line.nika tests/compiler/tests/grammar_same_line.stdout tests/compiler/tests/grammar_same_line_own_ws.nika tests/compiler/tests/grammar_same_line_own_ws.stdout Commit: Grammar built-in same_line: fails after a skipped line break (ADR-339 D2) Part: #557 Attribution: Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com Claude-Session: https://claude.ai/code/session_01GFeMqxRbtUMiGVyDMxsvEq

This site is open source. Improve this page.