Commit d15b664
feat(parser): trailing-comma in fn params and expr lists (Refs gitbot-fleet#148) (#370)
## Summary
Adds optional-trailing-comma support to comma-separated parameter and
expression lists in the AffineScript grammar — required by the
sustainabot hand-port (gitbot-fleet#148) and conventional in every
Rust-like language in the estate.
Two new right-recursive rules in \`parser.mly\`:
* \`param_list_trailing_comma\` — replaces \`separated_list(COMMA,
param)\` at four call sites (\`extern_fn_decl\`, \`fn_decl\`,
\`effect_op_decl\`, \`fn_sig\`).
* \`expr_list_trailing_comma\` — replaces \`separated_list(COMMA,
expr)\` at two call sites (\`expr_postfix\` for fn-application args,
\`expr_primary\` for array literals).
## Why right-recursive rather than \`separated_list(...) COMMA?\`
The hand-rolled form lets the trailing COMMA be absorbed inside the
recursion. After each item, the LR(1) choice on COMMA is unambiguous:
shift into the recursive tail, whose body may be empty when the closing
token follows. The mixfix \`separated_list(...) COMMA?\` form introduces
an LR conflict on the final COMMA which Menhir would have to break by
precedence, and we'd rather not pay that cost for a syntactic
convenience.
## Conflict-cost
Conflict-neutral. Parser builds with **21 shift/reduce + 1
reduce/reduce**, identical to the pre-patch baseline (verified by
inspecting \`_build/default/lib/parser.conflicts\`).
## Test plan
- [x] \`dune build\` green
- [x] Conflict count unchanged: 21 S/R + 1 R/R
- [ ] CI green
- [ ] Smoke: \`fn f(a: Int, b: Int,) -> Int { a + b }\` parses
- [ ] Smoke: \`let xs = [1, 2, 3,];\` parses
- [ ] Smoke: \`f(a, b,)\` parses as a call
## Companion PRs (gitbot-fleet#148 spine)
This is PR 1 of 5 in the parser+lexer cleanup spine driven by the
sustainabot hand-port. Each PR is independent and can be reviewed/merged
in any order:
1. **this PR** — trailing-comma in fn params + expr lists
2. fn-type with effect arrow in type position
3. builtin/lowercase qualified paths + TOTAL field name
4. lexer \`_\`-prefix idents
5. (hypatia) Levenshtein perf fix
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 80f7f7c commit d15b664
1 file changed
Lines changed: 52 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
194 | 194 | | |
195 | 195 | | |
196 | 196 | | |
197 | | - | |
| 197 | + | |
198 | 198 | | |
199 | 199 | | |
200 | 200 | | |
| |||
226 | 226 | | |
227 | 227 | | |
228 | 228 | | |
229 | | - | |
| 229 | + | |
230 | 230 | | |
231 | 231 | | |
232 | 232 | | |
| |||
382 | 382 | | |
383 | 383 | | |
384 | 384 | | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
385 | 415 | | |
386 | 416 | | |
387 | 417 | | |
| |||
593 | 623 | | |
594 | 624 | | |
595 | 625 | | |
596 | | - | |
| 626 | + | |
597 | 627 | | |
598 | 628 | | |
599 | 629 | | |
| |||
659 | 689 | | |
660 | 690 | | |
661 | 691 | | |
662 | | - | |
| 692 | + | |
663 | 693 | | |
664 | 694 | | |
665 | 695 | | |
| |||
796 | 826 | | |
797 | 827 | | |
798 | 828 | | |
799 | | - | |
| 829 | + | |
800 | 830 | | |
801 | 831 | | |
802 | 832 | | |
| |||
849 | 879 | | |
850 | 880 | | |
851 | 881 | | |
852 | | - | |
| 882 | + | |
853 | 883 | | |
854 | 884 | | |
855 | 885 | | |
| |||
899 | 929 | | |
900 | 930 | | |
901 | 931 | | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
902 | 948 | | |
903 | 949 | | |
904 | 950 | | |
| |||
0 commit comments