authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-03 14:12:25+02:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-08 11:49:00+02:00
log4fa5b59d4470daa595b67e36ceb8290064cbc8a7
tree562bac1444f4159dc825dfd166c31d53c72498fe
parent775dac91494ed602061ce4a28e7da8d64a0bd18a
signaturelock-open Commit is signed but in an unrecognized format.

grammar: fix catch operator whitespace handling

This now matches the behavior of Parse.zig

3 files changed, 21 insertions(+), 3 deletions(-)

doc/langref/grammar.peg+2-1
......@@ -318,12 +318,13 @@ CompareOpTok
318318
319319BitwiseOp <- pre_op_white BitwiseOpTok post_op_white
320320 / !pre_op_white BitwiseOpTok !post_op_white
321 / pre_op_white KEYWORD_catch post_op_white Payload?
322 / !pre_op_white KEYWORD_catch !post_op_white Payload?
321323BitwiseOpTok
322324 <- AMPERSAND ![&]
323325 / CARET
324326 / PIPE
325327 / KEYWORD_orelse
326 / KEYWORD_catch Payload?
327328
328329BitShiftOp <- pre_op_white BitShiftOpTok post_op_white
329330 / !pre_op_white BitShiftOpTok !post_op_white
lib/std/zig/parser_fuzz.zig+5
......@@ -114,6 +114,11 @@ test "volatile const" {
114114 try checkAgainstOracle("*volatile\nconst\n0");
115115}
116116
117// Found using AFL++
118test "catch capture whitespace" {
119 try checkAgainstOracle("test{0 catch |h|0;}");
120}
121
117122fn checkAgainstOracle(source: [:0]const u8) !void {
118123 var fba_buf: [1 << 18]u8 = undefined;
119124 var fba: std.heap.FixedBufferAllocator = .init(&fba_buf);
lib/std/zig/parser_generated_oracle.zig+14-2
......@@ -1665,6 +1665,20 @@ const Parser = struct {
16651665 break :blk_1 !match_1;
16661666 }) break :blk_0 true;
16671667 p.i = pos_0;
1668 if (try p.parsepre_op_white() and try p.parseKEYWORD_catch() and try p.parsepost_op_white() and (try p.parsePayload() or true)) break :blk_0 true;
1669 p.i = pos_0;
1670 if (blk_1: {
1671 const pos_1 = p.i;
1672 const match_1 = try p.parsepre_op_white();
1673 p.i = pos_1;
1674 break :blk_1 !match_1;
1675 } and try p.parseKEYWORD_catch() and blk_1: {
1676 const pos_1 = p.i;
1677 const match_1 = try p.parsepost_op_white();
1678 p.i = pos_1;
1679 break :blk_1 !match_1;
1680 } and (try p.parsePayload() or true)) break :blk_0 true;
1681 p.i = pos_0;
16681682 break :blk_0 false;
16691683 };
16701684 }
......@@ -1691,8 +1705,6 @@ const Parser = struct {
16911705 p.i = pos_0;
16921706 if (try p.parseKEYWORD_orelse()) break :blk_0 true;
16931707 p.i = pos_0;
1694 if (try p.parseKEYWORD_catch() and (try p.parsePayload() or true)) break :blk_0 true;
1695 p.i = pos_0;
16961708 break :blk_0 false;
16971709 };
16981710 }