✓
Passing This code compiles and runs correctly.
Code
// Pins the left-recursion wall: a rule that can reach itself before consuming
// any input would recurse forever at runtime, so the parse transform rejects
// it at COMPILE TIME, by name, with the rewrite in the message (put a
// consuming element first). `expr -> expr ...` is the canonical offender;
// packrat/left-recursion support, if it ever lands, arrives under this same
// surface and flips this pin deliberately.
import std/parser
import std/io
std/parser:grammar(math)
! expr e |> std/parser:match(e)
| expr x -> x
| `[0-9]+` n -> n
std/parser:parse("1", grammar: math)
| expr v |> std/io:print.ln("v={{ v:s }}")
| parse-error { line, col, expected, found } |> std/io:print.ln("err {{ line:d }}:{{ col:d }} {{ expected:s }} {{ found:s }}")
Must contain:
left-recursiveError Verification
Actual Compiler Output
🎯 Compiler coordination: Passes: 17 (flow-based: frontend, analysis, emission)
Error: output_emitted.zig:34:16: error: std/parser: rule `expr` is left-recursive (it can call itself before consuming input) — rewrite right-recursively: put a consuming element (a terminal) first
comptime { @compileError("std/parser: rule `expr` is left-recursive (it can call itself before consuming input) — rewrite right-recursively: put a consuming element (a terminal) first"); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
main_module: output_emitted.zig:29:25
main: output_emitted.zig:477:5
4 reference(s) hidden; use '-freference-trace=6' to see all referencesFlows
flow ~grammar click a branch to expand · @labels scroll to their anchor
grammar (expr: math)
flow ~parse click a branch to expand · @labels scroll to their anchor
parse (expr: "1", grammar: math)
Test Configuration
MUST_FAIL