authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-03-06 06:49:17+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-06 13:59:46-08:00
logaa7d16aba1f0b3a9e816684618d16cb1d178a6d3
treec4b63cb91da7aecb1abfb3c4c52e7bd3a071efce
parent90ab8ea9e681a4ffac0b4dc500e3ec489014e12f

grammar: remove gratuitous ambiguity

Previously, the following matched both ContainerField alternatives: * [IDENTIFIER] * [IDENTIFIER][COLON][TypeExpr]

3 files changed, 11 insertions(+), 29 deletions(-)

doc/langref.html.in+1-3
...@@ -11990,9 +11990,7 @@ VarDeclProto <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteA...@@ -11990,9 +11990,7 @@ VarDeclProto <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteA
1199011990
11991GlobalVarDecl <- VarDeclProto (EQUAL Expr)? SEMICOLON11991GlobalVarDecl <- VarDeclProto (EQUAL Expr)? SEMICOLON
1199211992
11993ContainerField11993ContainerField <- doc_comment? KEYWORD_comptime? !KEYWORD_fn (IDENTIFIER COLON)? TypeExpr ByteAlign? (EQUAL Expr)?
11994 <- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON TypeExpr)? ByteAlign? (EQUAL Expr)?
11995 / doc_comment? KEYWORD_comptime? (IDENTIFIER COLON)? !KEYWORD_fn TypeExpr ByteAlign? (EQUAL Expr)?
1199611994
11997# *** Block Level ***11995# *** Block Level ***
11998Statement11996Statement
lib/std/zig/Ast.zig+5-10
...@@ -661,7 +661,7 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex {...@@ -661,7 +661,7 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex {
661 .container_field,661 .container_field,
662 => {662 => {
663 const name_token = main_tokens[n];663 const name_token = main_tokens[n];
664 if (token_tags[name_token] != .keyword_comptime and name_token > 0 and token_tags[name_token - 1] == .keyword_comptime) {664 if (name_token > 0 and token_tags[name_token - 1] == .keyword_comptime) {
665 end_offset += 1;665 end_offset += 1;
666 }666 }
667 return name_token - end_offset;667 return name_token - end_offset;
...@@ -2076,13 +2076,11 @@ fn fullContainerFieldComponents(tree: Ast, info: full.ContainerField.Components)...@@ -2076,13 +2076,11 @@ fn fullContainerFieldComponents(tree: Ast, info: full.ContainerField.Components)
2076 .ast = info,2076 .ast = info,
2077 .comptime_token = null,2077 .comptime_token = null,
2078 };2078 };
2079 if (token_tags[info.main_token] == .keyword_comptime) {2079 if (info.main_token > 0 and token_tags[info.main_token - 1] == .keyword_comptime) {
2080 // comptime type = init,2080 // comptime type = init,
2081 // ^2081 // ^ ^
2082 result.comptime_token = info.main_token;
2083 } else if (info.main_token > 0 and token_tags[info.main_token - 1] == .keyword_comptime) {
2084 // comptime name: type = init,2082 // comptime name: type = init,
2085 // ^2083 // ^ ^
2086 result.comptime_token = info.main_token - 1;2084 result.comptime_token = info.main_token - 1;
2087 }2085 }
2088 return result;2086 return result;
...@@ -2580,13 +2578,10 @@ pub const full = struct {...@@ -2580,13 +2578,10 @@ pub const full = struct {
25802578
2581 pub fn convertToNonTupleLike(cf: *ContainerField, nodes: NodeList.Slice) void {2579 pub fn convertToNonTupleLike(cf: *ContainerField, nodes: NodeList.Slice) void {
2582 if (!cf.ast.tuple_like) return;2580 if (!cf.ast.tuple_like) return;
2583 if (cf.ast.type_expr == 0) return;
2584 if (nodes.items(.tag)[cf.ast.type_expr] != .identifier) return;2581 if (nodes.items(.tag)[cf.ast.type_expr] != .identifier) return;
25852582
2586 const ident = nodes.items(.main_token)[cf.ast.type_expr];
2587 cf.ast.tuple_like = false;
2588 cf.ast.main_token = ident;
2589 cf.ast.type_expr = 0;2583 cf.ast.type_expr = 0;
2584 cf.ast.tuple_like = false;
2590 }2585 }
2591 };2586 };
25922587
lib/std/zig/Parse.zig+5-16
...@@ -874,24 +874,13 @@ fn parseGlobalVarDecl(p: *Parse) !Node.Index {...@@ -874,24 +874,13 @@ fn parseGlobalVarDecl(p: *Parse) !Node.Index {
874 return var_decl;874 return var_decl;
875}875}
876876
877/// ContainerField877/// ContainerField <- doc_comment? KEYWORD_comptime? !KEYWORD_fn (IDENTIFIER COLON)? TypeExpr ByteAlign? (EQUAL Expr)?
878/// <- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON TypeExpr)? ByteAlign? (EQUAL Expr)?
879/// / doc_comment? KEYWORD_comptime? (IDENTIFIER COLON)? !KEYWORD_fn TypeExpr ByteAlign? (EQUAL Expr)?
880fn expectContainerField(p: *Parse) !Node.Index {878fn expectContainerField(p: *Parse) !Node.Index {
881 var main_token = p.tok_i;
882 _ = p.eatToken(.keyword_comptime);879 _ = p.eatToken(.keyword_comptime);
883 const tuple_like = p.token_tags[p.tok_i] != .identifier or p.token_tags[p.tok_i + 1] != .colon;880 const main_token = p.tok_i;
884 if (!tuple_like) {881 if (p.token_tags[p.tok_i] == .identifier and p.token_tags[p.tok_i + 1] == .colon) p.tok_i += 2;
885 main_token = p.assertToken(.identifier);882 const type_expr = try p.expectTypeExpr();
886 }883 const align_expr = try p.parseByteAlign();
887
888 var align_expr: Node.Index = 0;
889 var type_expr: Node.Index = 0;
890 if (p.eatToken(.colon) != null or tuple_like) {
891 type_expr = try p.expectTypeExpr();
892 align_expr = try p.parseByteAlign();
893 }
894
895 const value_expr: Node.Index = if (p.eatToken(.equal) == null) 0 else try p.expectExpr();884 const value_expr: Node.Index = if (p.eatToken(.equal) == null) 0 else try p.expectExpr();
896885
897 if (align_expr == 0) {886 if (align_expr == 0) {