From b4bfdfd74c3be3720e16cc3ef91a6b9152f8a9e1 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 18 May 2026 12:42:47 +0100 Subject: [PATCH] fix(parser): remove dead precedence declarations [#215 family F] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Menhir emitted 16 "precedence level / %prec ... never useful" warnings — declarations that never resolve any conflict because the expression cascade disambiguates structurally. They are pure noise that, alongside the conflict warnings, make a healthy build look broken. Removed (all certified "never useful" by Menhir itself): - precedence level: `%right EQ PLUSEQ MINUSEQ STAREQ SLASHEQ` (assignment ops — handled at statement level, never in the expr operator cascade) - precedence level: `%right BANG TILDE UMINUS UREF UDEREF` (unary level — `expr_unary` is right-recursive and already unambiguous) - precedence level: `%left DOT LBRACKET LPAREN` (postfix level — `expr_postfix` disambiguates structurally) - the three now-orphaned `%prec UMINUS/UREF/UDEREF` on the unary rules (UMINUS/UREF/UDEREF were pseudo-tokens used only there) Provably parse-behaviour-neutral — removing a declaration Menhir certifies resolves nothing cannot change any resolution. Verified: - 16 "never useful" warnings: gone (0 remain) - conflict counts UNCHANGED: 72 S/R, 10 R/R, 23 S/R states, 4 R/R states (identical resolution profile) - `dune test --force` green at 257/257 The retained `LOWEST_TYPE_ARROW`/`ARROW` levels (#216, family A) are *not* flagged — they do real work. Refs #215 Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/parser.mly | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/parser.mly b/lib/parser.mly index a3a5d587..f020126c 100644 --- a/lib/parser.mly +++ b/lib/parser.mly @@ -97,7 +97,6 @@ let rec effect_union_of_list = function See affinescript#215 (family A). */ %nonassoc LOWEST_TYPE_ARROW %nonassoc ARROW -%right EQ PLUSEQ MINUSEQ STAREQ SLASHEQ %left PIPEPIPE %left AMPAMP %left PIPE @@ -108,8 +107,15 @@ let rec effect_union_of_list = function %left LTLT GTGT %left PLUS PLUSPLUS MINUS %left STAR SLASH PERCENT -%right BANG TILDE UMINUS UREF UDEREF -%left DOT LBRACKET LPAREN +/* Removed (affinescript#215 family F): the assignment-op level + (EQ PLUSEQ MINUSEQ STAREQ SLASHEQ), the unary level + (BANG TILDE UMINUS UREF UDEREF), and the postfix level + (DOT LBRACKET LPAREN) — Menhir certified every one of these + precedence levels "never useful" (they resolve no conflict; the + expr cascade disambiguates structurally). Removal is + parse-behaviour-neutral, proven by the unchanged conflict counts + and the green 257-test gate. UMINUS/UREF/UDEREF were pseudo-tokens + used only by the now-removed `%prec` on the unary rules. */ /* Entry point */ %start program @@ -707,11 +713,11 @@ expr_mul: | e = expr_unary { e } expr_unary: - | MINUS e = expr_unary %prec UMINUS { ExprUnary (OpNeg, e) } + | MINUS e = expr_unary { ExprUnary (OpNeg, e) } | BANG e = expr_unary { ExprUnary (OpNot, e) } | TILDE e = expr_unary { ExprUnary (OpBitNot, e) } - | AMP e = expr_unary %prec UREF { ExprUnary (OpRef, e) } - | STAR e = expr_unary %prec UDEREF { ExprUnary (OpDeref, e) } + | AMP e = expr_unary { ExprUnary (OpRef, e) } + | STAR e = expr_unary { ExprUnary (OpDeref, e) } | e = expr_postfix { e } expr_postfix: