From aa7d16aba1f0b3a9e816684618d16cb1d178a6d3 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 6 Mar 2024 06:49:17 +0100 Subject: [PATCH] grammar: remove gratuitous ambiguity Previously, the following matched both ContainerField alternatives: * [IDENTIFIER] * [IDENTIFIER][COLON][TypeExpr] --- doc/langref.html.in | 4 +--- lib/std/zig/Ast.zig | 15 +++++---------- lib/std/zig/Parse.zig | 21 +++++---------------- 3 files changed, 11 insertions(+), 29 deletions(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index 0ebc1a3c21..c1be451622 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -11990,9 +11990,7 @@ VarDeclProto <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteA GlobalVarDecl <- VarDeclProto (EQUAL Expr)? SEMICOLON -ContainerField - <- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON TypeExpr)? ByteAlign? (EQUAL Expr)? - / doc_comment? KEYWORD_comptime? (IDENTIFIER COLON)? !KEYWORD_fn TypeExpr ByteAlign? (EQUAL Expr)? +ContainerField <- doc_comment? KEYWORD_comptime? !KEYWORD_fn (IDENTIFIER COLON)? TypeExpr ByteAlign? (EQUAL Expr)? # *** Block Level *** Statement diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig index 6f4afbbe4f..6d994a569a 100644 --- a/lib/std/zig/Ast.zig +++ b/lib/std/zig/Ast.zig @@ -661,7 +661,7 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { .container_field, => { const name_token = main_tokens[n]; - if (token_tags[name_token] != .keyword_comptime and name_token > 0 and token_tags[name_token - 1] == .keyword_comptime) { + if (name_token > 0 and token_tags[name_token - 1] == .keyword_comptime) { end_offset += 1; } return name_token - end_offset; @@ -2076,13 +2076,11 @@ fn fullContainerFieldComponents(tree: Ast, info: full.ContainerField.Components) .ast = info, .comptime_token = null, }; - if (token_tags[info.main_token] == .keyword_comptime) { + if (info.main_token > 0 and token_tags[info.main_token - 1] == .keyword_comptime) { // comptime type = init, - // ^ - result.comptime_token = info.main_token; - } else if (info.main_token > 0 and token_tags[info.main_token - 1] == .keyword_comptime) { + // ^ ^ // comptime name: type = init, - // ^ + // ^ ^ result.comptime_token = info.main_token - 1; } return result; @@ -2580,13 +2578,10 @@ pub const full = struct { pub fn convertToNonTupleLike(cf: *ContainerField, nodes: NodeList.Slice) void { if (!cf.ast.tuple_like) return; - if (cf.ast.type_expr == 0) return; if (nodes.items(.tag)[cf.ast.type_expr] != .identifier) return; - const ident = nodes.items(.main_token)[cf.ast.type_expr]; - cf.ast.tuple_like = false; - cf.ast.main_token = ident; cf.ast.type_expr = 0; + cf.ast.tuple_like = false; } }; diff --git a/lib/std/zig/Parse.zig b/lib/std/zig/Parse.zig index 3c007ea1ac..369e2ef125 100644 --- a/lib/std/zig/Parse.zig +++ b/lib/std/zig/Parse.zig @@ -874,24 +874,13 @@ fn parseGlobalVarDecl(p: *Parse) !Node.Index { return var_decl; } -/// ContainerField -/// <- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON TypeExpr)? ByteAlign? (EQUAL Expr)? -/// / doc_comment? KEYWORD_comptime? (IDENTIFIER COLON)? !KEYWORD_fn TypeExpr ByteAlign? (EQUAL Expr)? +/// ContainerField <- doc_comment? KEYWORD_comptime? !KEYWORD_fn (IDENTIFIER COLON)? TypeExpr ByteAlign? (EQUAL Expr)? fn expectContainerField(p: *Parse) !Node.Index { - var main_token = p.tok_i; _ = p.eatToken(.keyword_comptime); - const tuple_like = p.token_tags[p.tok_i] != .identifier or p.token_tags[p.tok_i + 1] != .colon; - if (!tuple_like) { - main_token = p.assertToken(.identifier); - } - - var align_expr: Node.Index = 0; - var type_expr: Node.Index = 0; - if (p.eatToken(.colon) != null or tuple_like) { - type_expr = try p.expectTypeExpr(); - align_expr = try p.parseByteAlign(); - } - + const main_token = p.tok_i; + if (p.token_tags[p.tok_i] == .identifier and p.token_tags[p.tok_i + 1] == .colon) p.tok_i += 2; + const type_expr = try p.expectTypeExpr(); + const align_expr = try p.parseByteAlign(); const value_expr: Node.Index = if (p.eatToken(.equal) == null) 0 else try p.expectExpr(); if (align_expr == 0) {