✓
Passing Passing: the compiler rejects this program as expected.
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 }}")
Actual compiler output
error[KORU163]: std/parser: rule `expr` is left-recursive (it can call itself before consuming input) — rewrite right-recursively: put a consuming element (a terminal) first
--> tests/regression/600_STDLIB/641_PARSER/641_003_reject_left_recursion/input.k:15:0Must contain:
left-recursiveFlows
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_ERROR