authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-06-16 10:21:47+02:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-08 11:48:59+02:00
loge488959c1f0504dc3b2aae19d79211e725916c76
treeeff14397567a93603eccb28d26994c4e7d295114
parent068d4837807570550e44db99d92b25544a50cad8
signaturelock-open Commit is signed but in an unrecognized format.

grammar: remove negative lookahead causing inconsistency

It is not clear why this lookahead was added in the first place, but it does not reflect the behavior of the Parse.zig implementation as demonstrated with the new test case.

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

doc/langref/grammar.peg+1-1
...@@ -20,7 +20,7 @@ VarDeclProto <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteA...@@ -20,7 +20,7 @@ VarDeclProto <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteA
2020
21GlobalVarDecl <- VarDeclProto (EQUAL Expr)? SEMICOLON21GlobalVarDecl <- VarDeclProto (EQUAL Expr)? SEMICOLON
2222
23ContainerField <- doc_comment? KEYWORD_comptime? !KEYWORD_fn (IDENTIFIER COLON)? TypeExpr ByteAlign? (EQUAL Expr)?23ContainerField <- doc_comment? KEYWORD_comptime? (IDENTIFIER COLON)? TypeExpr ByteAlign? (EQUAL Expr)?
2424
25# *** Block Level ***25# *** Block Level ***
26BlockStatement26BlockStatement
lib/std/zig/parser_fuzz.zig+5
...@@ -63,6 +63,11 @@ test "expression nesting" {...@@ -63,6 +63,11 @@ test "expression nesting" {
63 try checkAgainstOracle("test{*comptime 0 == 0;}");63 try checkAgainstOracle("test{*comptime 0 == 0;}");
64}64}
6565
66// Found using AFL++
67test "comptime fn" {
68 try checkAgainstOracle("comptime fn()0");
69}
70
66fn checkAgainstOracle(source: [:0]const u8) !void {71fn checkAgainstOracle(source: [:0]const u8) !void {
67 var fba_buf: [1 << 18]u8 = undefined;72 var fba_buf: [1 << 18]u8 = undefined;
68 var fba: std.heap.FixedBufferAllocator = .init(&fba_buf);73 var fba: std.heap.FixedBufferAllocator = .init(&fba_buf);
lib/std/zig/parser_generated_oracle.zig+1-6
...@@ -164,12 +164,7 @@ const Parser = struct {...@@ -164,12 +164,7 @@ const Parser = struct {
164 pub fn parseContainerField(p: *Parser) bool {164 pub fn parseContainerField(p: *Parser) bool {
165 return blk_0: {165 return blk_0: {
166 const pos_0 = p.i;166 const pos_0 = p.i;
167 if ((p.parsedoc_comment() or true) and (p.parseKEYWORD_comptime() or true) and blk_1: {167 if ((p.parsedoc_comment() or true) and (p.parseKEYWORD_comptime() or true) and (blk_3: {
168 const pos_1 = p.i;
169 const match_1 = p.parseKEYWORD_fn();
170 p.i = pos_1;
171 break :blk_1 !match_1;
172 } and (blk_3: {
173 const pos_3 = p.i;168 const pos_3 = p.i;
174 if (p.parseIDENTIFIER() and p.parseCOLON()) break :blk_3 true;169 if (p.parseIDENTIFIER() and p.parseCOLON()) break :blk_3 true;
175 p.i = pos_3;170 p.i = pos_3;