authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-06-15 18:24:09+02:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-08 11:48:58+02:00
logad0a294ae23252ce5e1494a93e4d8b160b6cd4df
tree9698704f7905377bb4ff27c5d8dd0db093c7f2ff
parente21ced91e30d8bc943ebe0a1f1f6d3bc6821740e
signaturelock-open Commit is signed but in an unrecognized format.

grammar: revert redundant changes

Commit 785fb1be111186525bf288fa3460945404f676eb made many redundant changes to the grammar due to insufficient understanding of PEG semantics. This commit reverts the most obviously redundant of those changes. The unbounded lookahead through e.g. !ExprSuffix still needs to be reverted, but I want to do that in a future commit since that change can't be reasoned about locally.

2 files changed, 24 insertions(+), 127 deletions(-)

doc/langref/grammar.peg+11-11
...@@ -20,19 +20,19 @@ VarDeclProto <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteA...@@ -20,19 +20,19 @@ 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_comptime) !KEYWORD_fn (IDENTIFIER COLON / !(IDENTIFIER COLON))? TypeExpr ByteAlign? (EQUAL Expr)?23ContainerField <- doc_comment? KEYWORD_comptime? !KEYWORD_fn (IDENTIFIER COLON)? TypeExpr ByteAlign? (EQUAL Expr)?
2424
25# *** Block Level ***25# *** Block Level ***
26BlockStatement26BlockStatement
27 <- Statement27 <- Statement
28 / KEYWORD_defer BlockExprStatement28 / KEYWORD_defer BlockExprStatement
29 / KEYWORD_errdefer BlockExprStatement29 / KEYWORD_errdefer BlockExprStatement
30 / !ExprStatement (KEYWORD_comptime !BlockExpr)? VarAssignStatement30 / (KEYWORD_comptime)? VarAssignStatement
3131
32Statement32Statement
33 <- ExprStatement33 <- ExprStatement
34 / KEYWORD_suspend BlockExprStatement34 / KEYWORD_suspend BlockExprStatement
35 / !ExprStatement (KEYWORD_comptime !BlockExpr)? AssignExpr SEMICOLON35 / (KEYWORD_comptime)? AssignExpr SEMICOLON
3636
37ExprStatement37ExprStatement
38 <- IfStatement38 <- IfStatement
...@@ -42,7 +42,7 @@ ExprStatement...@@ -42,7 +42,7 @@ ExprStatement
4242
43IfStatement43IfStatement
44 <- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?44 <- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
45 / IfPrefix !BlockExpr AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )45 / IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
4646
47LabeledStatement <- BlockLabel? (Block / LoopStatement / SwitchExpr)47LabeledStatement <- BlockLabel? (Block / LoopStatement / SwitchExpr)
4848
...@@ -50,11 +50,11 @@ LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)...@@ -50,11 +50,11 @@ LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
5050
51ForStatement51ForStatement
52 <- ForPrefix BlockExpr ( KEYWORD_else Statement / !KEYWORD_else )52 <- ForPrefix BlockExpr ( KEYWORD_else Statement / !KEYWORD_else )
53 / ForPrefix !BlockExpr AssignExpr ( SEMICOLON / KEYWORD_else Statement )53 / ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement )
5454
55WhileStatement55WhileStatement
56 <- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?56 <- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
57 / WhilePrefix !BlockExpr AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )57 / WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
5858
59BlockExprStatement59BlockExprStatement
60 <- BlockExpr60 <- BlockExpr
...@@ -93,10 +93,10 @@ PrefixExpr <- PrefixOp* PrimaryExpr...@@ -93,10 +93,10 @@ PrefixExpr <- PrefixOp* PrimaryExpr
93PrimaryExpr93PrimaryExpr
94 <- AsmExpr94 <- AsmExpr
95 / IfExpr95 / IfExpr
96 / KEYWORD_break (BreakLabel / !BreakLabel) (Expr !ExprSuffix / !SinglePtrTypeStart)96 / KEYWORD_break BreakLabel? (Expr !ExprSuffix / !SinglePtrTypeStart)
97 / KEYWORD_comptime Expr !ExprSuffix97 / KEYWORD_comptime Expr !ExprSuffix
98 / KEYWORD_nosuspend Expr !ExprSuffix98 / KEYWORD_nosuspend Expr !ExprSuffix
99 / KEYWORD_continue (BreakLabel / !BreakLabel) (Expr !ExprSuffix / !SinglePtrTypeStart)99 / KEYWORD_continue BreakLabel? (Expr !ExprSuffix / !SinglePtrTypeStart)
100 / KEYWORD_resume Expr !ExprSuffix100 / KEYWORD_resume Expr !ExprSuffix
101 / KEYWORD_return (Expr !ExprSuffix / !SinglePtrTypeStart)101 / KEYWORD_return (Expr !ExprSuffix / !SinglePtrTypeStart)
102 / BlockLabel? LoopExpr102 / BlockLabel? LoopExpr
...@@ -137,7 +137,7 @@ PrimaryTypeExpr...@@ -137,7 +137,7 @@ PrimaryTypeExpr
137 / FnProto137 / FnProto
138 / GroupedExpr138 / GroupedExpr
139 / LabeledTypeExpr139 / LabeledTypeExpr
140 / IDENTIFIER !(COLON LabelableExpr)140 / IDENTIFIER
141 / IfTypeExpr141 / IfTypeExpr
142 / KEYWORD_comptime TypeExpr !ExprSuffix142 / KEYWORD_comptime TypeExpr !ExprSuffix
143 / KEYWORD_error DOT IDENTIFIER143 / KEYWORD_error DOT IDENTIFIER
...@@ -353,7 +353,7 @@ SinglePtrTypeStart <- ASTERISK...@@ -353,7 +353,7 @@ SinglePtrTypeStart <- ASTERISK
353353
354ManyPtrTypeStart <- LBRACKET ASTERISK (LETTERC / COLON Expr)? RBRACKET354ManyPtrTypeStart <- LBRACKET ASTERISK (LETTERC / COLON Expr)? RBRACKET
355355
356ArrayTypeStart <- LBRACKET Expr !ASTERISK (COLON Expr)? RBRACKET356ArrayTypeStart <- LBRACKET Expr (COLON Expr)? RBRACKET
357357
358# ContainerDecl specific358# ContainerDecl specific
359ContainerDeclAuto <- ContainerDeclType LBRACE ContainerMembers RBRACE359ContainerDeclAuto <- ContainerDeclType LBRACE ContainerMembers RBRACE
...@@ -362,7 +362,7 @@ ContainerDeclType...@@ -362,7 +362,7 @@ ContainerDeclType
362 <- KEYWORD_struct (LPAREN Expr RPAREN)?362 <- KEYWORD_struct (LPAREN Expr RPAREN)?
363 / KEYWORD_opaque363 / KEYWORD_opaque
364 / KEYWORD_enum (LPAREN Expr RPAREN)?364 / KEYWORD_enum (LPAREN Expr RPAREN)?
365 / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / !KEYWORD_enum Expr) RPAREN)?365 / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)?
366366
367# Alignment367# Alignment
368ByteAlign <- KEYWORD_align LPAREN Expr RPAREN368ByteAlign <- KEYWORD_align LPAREN Expr RPAREN
lib/std/zig/parser_generated_oracle.zig+13-116
...@@ -169,19 +169,7 @@ const Parser = struct {...@@ -169,19 +169,7 @@ const Parser = struct {
169 pub fn parseContainerField(p: *Parser) bool {169 pub fn parseContainerField(p: *Parser) bool {
170 return blk_0: {170 return blk_0: {
171 const pos_0 = p.i;171 const pos_0 = p.i;
172 if ((p.parsedoc_comment() or true) and blk_2: {172 if ((p.parsedoc_comment() or true) and (p.parseKEYWORD_comptime() or true) and blk_1: {
173 const pos_2 = p.i;
174 if (p.parseKEYWORD_comptime()) break :blk_2 true;
175 p.i = pos_2;
176 if (blk_3: {
177 const pos_3 = p.i;
178 const match_3 = p.parseKEYWORD_comptime();
179 p.i = pos_3;
180 break :blk_3 !match_3;
181 }) break :blk_2 true;
182 p.i = pos_2;
183 break :blk_2 false;
184 } and blk_1: {
185 const pos_1 = p.i;173 const pos_1 = p.i;
186 const match_1 = p.parseKEYWORD_fn();174 const match_1 = p.parseKEYWORD_fn();
187 p.i = pos_1;175 p.i = pos_1;
...@@ -190,18 +178,6 @@ const Parser = struct {...@@ -190,18 +178,6 @@ const Parser = struct {
190 const pos_3 = p.i;178 const pos_3 = p.i;
191 if (p.parseIDENTIFIER() and p.parseCOLON()) break :blk_3 true;179 if (p.parseIDENTIFIER() and p.parseCOLON()) break :blk_3 true;
192 p.i = pos_3;180 p.i = pos_3;
193 if (blk_4: {
194 const pos_4 = p.i;
195 const match_4 = blk_6: {
196 const pos_6 = p.i;
197 if (p.parseIDENTIFIER() and p.parseCOLON()) break :blk_6 true;
198 p.i = pos_6;
199 break :blk_6 false;
200 };
201 p.i = pos_4;
202 break :blk_4 !match_4;
203 }) break :blk_3 true;
204 p.i = pos_3;
205 break :blk_3 false;181 break :blk_3 false;
206 } or true) and p.parseTypeExpr() and (p.parseByteAlign() or true) and (blk_3: {182 } or true) and p.parseTypeExpr() and (p.parseByteAlign() or true) and (blk_3: {
207 const pos_3 = p.i;183 const pos_3 = p.i;
...@@ -222,19 +198,9 @@ const Parser = struct {...@@ -222,19 +198,9 @@ const Parser = struct {
222 p.i = pos_0;198 p.i = pos_0;
223 if (p.parseKEYWORD_errdefer() and p.parseBlockExprStatement()) break :blk_0 true;199 if (p.parseKEYWORD_errdefer() and p.parseBlockExprStatement()) break :blk_0 true;
224 p.i = pos_0;200 p.i = pos_0;
225 if (blk_1: {201 if ((blk_3: {
226 const pos_1 = p.i;
227 const match_1 = p.parseExprStatement();
228 p.i = pos_1;
229 break :blk_1 !match_1;
230 } and (blk_3: {
231 const pos_3 = p.i;202 const pos_3 = p.i;
232 if (p.parseKEYWORD_comptime() and blk_4: {203 if (p.parseKEYWORD_comptime()) break :blk_3 true;
233 const pos_4 = p.i;
234 const match_4 = p.parseBlockExpr();
235 p.i = pos_4;
236 break :blk_4 !match_4;
237 }) break :blk_3 true;
238 p.i = pos_3;204 p.i = pos_3;
239 break :blk_3 false;205 break :blk_3 false;
240 } or true) and p.parseVarAssignStatement()) break :blk_0 true;206 } or true) and p.parseVarAssignStatement()) break :blk_0 true;
...@@ -249,19 +215,9 @@ const Parser = struct {...@@ -249,19 +215,9 @@ const Parser = struct {
249 p.i = pos_0;215 p.i = pos_0;
250 if (p.parseKEYWORD_suspend() and p.parseBlockExprStatement()) break :blk_0 true;216 if (p.parseKEYWORD_suspend() and p.parseBlockExprStatement()) break :blk_0 true;
251 p.i = pos_0;217 p.i = pos_0;
252 if (blk_1: {218 if ((blk_3: {
253 const pos_1 = p.i;
254 const match_1 = p.parseExprStatement();
255 p.i = pos_1;
256 break :blk_1 !match_1;
257 } and (blk_3: {
258 const pos_3 = p.i;219 const pos_3 = p.i;
259 if (p.parseKEYWORD_comptime() and blk_4: {220 if (p.parseKEYWORD_comptime()) break :blk_3 true;
260 const pos_4 = p.i;
261 const match_4 = p.parseBlockExpr();
262 p.i = pos_4;
263 break :blk_4 !match_4;
264 }) break :blk_3 true;
265 p.i = pos_3;221 p.i = pos_3;
266 break :blk_3 false;222 break :blk_3 false;
267 } or true) and p.parseAssignExpr() and p.parseSEMICOLON()) break :blk_0 true;223 } or true) and p.parseAssignExpr() and p.parseSEMICOLON()) break :blk_0 true;
...@@ -293,12 +249,7 @@ const Parser = struct {...@@ -293,12 +249,7 @@ const Parser = struct {
293 break :blk_3 false;249 break :blk_3 false;
294 } or true)) break :blk_0 true;250 } or true)) break :blk_0 true;
295 p.i = pos_0;251 p.i = pos_0;
296 if (p.parseIfPrefix() and blk_1: {252 if (p.parseIfPrefix() and p.parseAssignExpr() and blk_2: {
297 const pos_1 = p.i;
298 const match_1 = p.parseBlockExpr();
299 p.i = pos_1;
300 break :blk_1 !match_1;
301 } and p.parseAssignExpr() and blk_2: {
302 const pos_2 = p.i;253 const pos_2 = p.i;
303 if (p.parseSEMICOLON()) break :blk_2 true;254 if (p.parseSEMICOLON()) break :blk_2 true;
304 p.i = pos_2;255 p.i = pos_2;
...@@ -359,12 +310,7 @@ const Parser = struct {...@@ -359,12 +310,7 @@ const Parser = struct {
359 break :blk_2 false;310 break :blk_2 false;
360 }) break :blk_0 true;311 }) break :blk_0 true;
361 p.i = pos_0;312 p.i = pos_0;
362 if (p.parseForPrefix() and blk_1: {313 if (p.parseForPrefix() and p.parseAssignExpr() and blk_2: {
363 const pos_1 = p.i;
364 const match_1 = p.parseBlockExpr();
365 p.i = pos_1;
366 break :blk_1 !match_1;
367 } and p.parseAssignExpr() and blk_2: {
368 const pos_2 = p.i;314 const pos_2 = p.i;
369 if (p.parseSEMICOLON()) break :blk_2 true;315 if (p.parseSEMICOLON()) break :blk_2 true;
370 p.i = pos_2;316 p.i = pos_2;
...@@ -386,12 +332,7 @@ const Parser = struct {...@@ -386,12 +332,7 @@ const Parser = struct {
386 break :blk_3 false;332 break :blk_3 false;
387 } or true)) break :blk_0 true;333 } or true)) break :blk_0 true;
388 p.i = pos_0;334 p.i = pos_0;
389 if (p.parseWhilePrefix() and blk_1: {335 if (p.parseWhilePrefix() and p.parseAssignExpr() and blk_2: {
390 const pos_1 = p.i;
391 const match_1 = p.parseBlockExpr();
392 p.i = pos_1;
393 break :blk_1 !match_1;
394 } and p.parseAssignExpr() and blk_2: {
395 const pos_2 = p.i;336 const pos_2 = p.i;
396 if (p.parseSEMICOLON()) break :blk_2 true;337 if (p.parseSEMICOLON()) break :blk_2 true;
397 p.i = pos_2;338 p.i = pos_2;
...@@ -630,19 +571,7 @@ const Parser = struct {...@@ -630,19 +571,7 @@ const Parser = struct {
630 p.i = pos_0;571 p.i = pos_0;
631 if (p.parseIfExpr()) break :blk_0 true;572 if (p.parseIfExpr()) break :blk_0 true;
632 p.i = pos_0;573 p.i = pos_0;
633 if (p.parseKEYWORD_break() and blk_2: {574 if (p.parseKEYWORD_break() and (p.parseBreakLabel() or true) and blk_2: {
634 const pos_2 = p.i;
635 if (p.parseBreakLabel()) break :blk_2 true;
636 p.i = pos_2;
637 if (blk_3: {
638 const pos_3 = p.i;
639 const match_3 = p.parseBreakLabel();
640 p.i = pos_3;
641 break :blk_3 !match_3;
642 }) break :blk_2 true;
643 p.i = pos_2;
644 break :blk_2 false;
645 } and blk_2: {
646 const pos_2 = p.i;575 const pos_2 = p.i;
647 if (p.parseExpr() and blk_3: {576 if (p.parseExpr() and blk_3: {
648 const pos_3 = p.i;577 const pos_3 = p.i;
...@@ -675,19 +604,7 @@ const Parser = struct {...@@ -675,19 +604,7 @@ const Parser = struct {
675 break :blk_1 !match_1;604 break :blk_1 !match_1;
676 }) break :blk_0 true;605 }) break :blk_0 true;
677 p.i = pos_0;606 p.i = pos_0;
678 if (p.parseKEYWORD_continue() and blk_2: {607 if (p.parseKEYWORD_continue() and (p.parseBreakLabel() or true) and blk_2: {
679 const pos_2 = p.i;
680 if (p.parseBreakLabel()) break :blk_2 true;
681 p.i = pos_2;
682 if (blk_3: {
683 const pos_3 = p.i;
684 const match_3 = p.parseBreakLabel();
685 p.i = pos_3;
686 break :blk_3 !match_3;
687 }) break :blk_2 true;
688 p.i = pos_2;
689 break :blk_2 false;
690 } and blk_2: {
691 const pos_2 = p.i;608 const pos_2 = p.i;
692 if (p.parseExpr() and blk_3: {609 if (p.parseExpr() and blk_3: {
693 const pos_3 = p.i;610 const pos_3 = p.i;
...@@ -927,17 +844,7 @@ const Parser = struct {...@@ -927,17 +844,7 @@ const Parser = struct {
927 p.i = pos_0;844 p.i = pos_0;
928 if (p.parseLabeledTypeExpr()) break :blk_0 true;845 if (p.parseLabeledTypeExpr()) break :blk_0 true;
929 p.i = pos_0;846 p.i = pos_0;
930 if (p.parseIDENTIFIER() and blk_1: {847 if (p.parseIDENTIFIER()) break :blk_0 true;
931 const pos_1 = p.i;
932 const match_1 = blk_3: {
933 const pos_3 = p.i;
934 if (p.parseCOLON() and p.parseLabelableExpr()) break :blk_3 true;
935 p.i = pos_3;
936 break :blk_3 false;
937 };
938 p.i = pos_1;
939 break :blk_1 !match_1;
940 }) break :blk_0 true;
941 p.i = pos_0;848 p.i = pos_0;
942 if (p.parseIfTypeExpr()) break :blk_0 true;849 if (p.parseIfTypeExpr()) break :blk_0 true;
943 p.i = pos_0;850 p.i = pos_0;
...@@ -1813,12 +1720,7 @@ const Parser = struct {...@@ -1813,12 +1720,7 @@ const Parser = struct {
1813 pub fn parseArrayTypeStart(p: *Parser) bool {1720 pub fn parseArrayTypeStart(p: *Parser) bool {
1814 return blk_0: {1721 return blk_0: {
1815 const pos_0 = p.i;1722 const pos_0 = p.i;
1816 if (p.parseLBRACKET() and p.parseExpr() and blk_1: {1723 if (p.parseLBRACKET() and p.parseExpr() and (blk_3: {
1817 const pos_1 = p.i;
1818 const match_1 = p.parseASTERISK();
1819 p.i = pos_1;
1820 break :blk_1 !match_1;
1821 } and (blk_3: {
1822 const pos_3 = p.i;1724 const pos_3 = p.i;
1823 if (p.parseCOLON() and p.parseExpr()) break :blk_3 true;1725 if (p.parseCOLON() and p.parseExpr()) break :blk_3 true;
1824 p.i = pos_3;1726 p.i = pos_3;
...@@ -1866,12 +1768,7 @@ const Parser = struct {...@@ -1866,12 +1768,7 @@ const Parser = struct {
1866 break :blk_8 false;1768 break :blk_8 false;
1867 } or true)) break :blk_5 true;1769 } or true)) break :blk_5 true;
1868 p.i = pos_5;1770 p.i = pos_5;
1869 if (blk_6: {1771 if (p.parseExpr()) break :blk_5 true;
1870 const pos_6 = p.i;
1871 const match_6 = p.parseKEYWORD_enum();
1872 p.i = pos_6;
1873 break :blk_6 !match_6;
1874 } and p.parseExpr()) break :blk_5 true;
1875 p.i = pos_5;1772 p.i = pos_5;
1876 break :blk_5 false;1773 break :blk_5 false;
1877 } and p.parseRPAREN()) break :blk_3 true;1774 } and p.parseRPAREN()) break :blk_3 true;