GUEST: step 4 — lib/guest/pratt.sx operator-table format + lookup

Extracted the data-half of Pratt-style precedence parsing: the operator
table format and lookup. The climbing loop stays per-language because
the two canaries use opposite conventions (lua: higher prec = tighter;
prolog: lower prec = tighter, with xfx/xfy/yfx assoc tags) — forcing
one shared loop adds callback indirection that obscures more than it
shares. The brief's literal ask is "Grammar is a dict, not hardcoded
cond" and that's what gets shared.

Entry shape: (NAME PREC ASSOC). Three accessors: pratt-op-name /
pratt-op-prec / pratt-op-assoc. One traversal: pratt-op-lookup.

Ported lua/parser.sx — replaced 18-clause cond and the
lua-binop-right? hardcoded `or` with a 15-entry lua-op-table, now
queried via pratt-op-lookup. Ported prolog/parser.sx — pl-op-find
(linear walk reimpl) deleted; pl-op-lookup wraps pratt-op-lookup;
pl-token-op simplified to return the entry directly.

Verification:
- lua/test.sh: 185/185 = baseline.
- prolog/conformance.sh: 590/590 = baseline (timestamp-only diff).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-07 17:17:17 +00:00
parent d27622d45e
commit da27958d67
7 changed files with 62 additions and 42 deletions

View File

@@ -104,18 +104,9 @@
(list ":-" 1200 "xfx")
(list "mod" 400 "yfx")))
(define
pl-op-find
(fn
(name table)
(cond
((empty? table) nil)
((= (first (first table)) name) (rest (first table)))
(true (pl-op-find name (rest table))))))
(define pl-op-lookup (fn (name) (pratt-op-lookup pl-op-table name)))
(define pl-op-lookup (fn (name) (pl-op-find name pl-op-table)))
;; Token → (name prec type) for known infix ops, else nil.
;; Token → entry (name prec type) for known infix ops, else nil.
(define
pl-token-op
(fn
@@ -123,14 +114,8 @@
(let
((ty (get t :type)) (vv (get t :value)))
(cond
((and (= ty "punct") (= vv ","))
(let
((info (pl-op-lookup ",")))
(if (nil? info) nil (cons "," info))))
((or (= ty "atom") (= ty "op"))
(let
((info (pl-op-lookup vv)))
(if (nil? info) nil (cons vv info))))
((and (= ty "punct") (= vv ",")) (pl-op-lookup ","))
((or (= ty "atom") (= ty "op")) (pl-op-lookup vv))
(true nil)))))
;; ── Term parser ─────────────────────────────────────────────────────