wsgl parser: Use expect() for parenthesis checks

Keeps error message consistent. Reduces code.

Bug: tint:282
Change-Id: Ie5059599ed538bc589d594d7f16aa3db6774110b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/31727
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index 9634793..ca6274e 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -437,11 +437,8 @@
   if (t.IsLocation()) {
     next();  // consume the peek
 
-    t = next();
-    if (!t.IsParenLeft()) {
-      add_error(t, "missing ( for location decoration");
-      return {};
-    }
+    if (!expect("location decoration", Token::Type::kParenLeft))
+      return nullptr;
 
     t = next();
     if (!t.IsSintLiteral()) {
@@ -450,21 +447,16 @@
     }
     int32_t val = t.to_i32();
 
-    t = next();
-    if (!t.IsParenRight()) {
-      add_error(t, "missing ) for location decoration");
-      return {};
-    }
+    if (!expect("location decoration", Token::Type::kParenRight))
+      return nullptr;
+
     return std::make_unique<ast::LocationDecoration>(val, source);
   }
   if (t.IsBuiltin()) {
     next();  // consume the peek
 
-    t = next();
-    if (!t.IsParenLeft()) {
-      add_error(t, "missing ( for builtin decoration");
-      return {};
-    }
+    if (!expect("builtin decoration", Token::Type::kParenLeft))
+      return nullptr;
 
     t = next();
     if (!t.IsIdentifier() || t.to_str().empty()) {
@@ -478,21 +470,16 @@
       return {};
     }
 
-    t = next();
-    if (!t.IsParenRight()) {
-      add_error(t, "missing ) for builtin decoration");
-      return {};
-    }
+    if (!expect("builtin decoration", Token::Type::kParenRight))
+      return nullptr;
+
     return std::make_unique<ast::BuiltinDecoration>(builtin, source);
   }
   if (t.IsBinding()) {
     next();  // consume the peek
 
-    t = next();
-    if (!t.IsParenLeft()) {
-      add_error(t, "missing ( for binding decoration");
-      return {};
-    }
+    if (!expect("binding decoration", Token::Type::kParenLeft))
+      return nullptr;
 
     t = next();
     if (!t.IsSintLiteral()) {
@@ -501,22 +488,16 @@
     }
     int32_t val = t.to_i32();
 
-    t = next();
-    if (!t.IsParenRight()) {
-      add_error(t, "missing ) for binding decoration");
-      return {};
-    }
+    if (!expect("binding decoration", Token::Type::kParenRight))
+      return nullptr;
 
     return std::make_unique<ast::BindingDecoration>(val, source);
   }
   if (t.IsSet()) {
     next();  // consume the peek
 
-    t = next();
-    if (!t.IsParenLeft()) {
-      add_error(t, "missing ( for set decoration");
-      return {};
-    }
+    if (!expect("set decoration", Token::Type::kParenLeft))
+      return nullptr;
 
     t = next();
     if (!t.IsSintLiteral()) {
@@ -525,11 +506,8 @@
     }
     uint32_t val = t.to_i32();
 
-    t = next();
-    if (!t.IsParenRight()) {
-      add_error(t, "missing ) for set decoration");
-      return {};
-    }
+    if (!expect("set decoration", Token::Type::kParenRight))
+      return nullptr;
 
     return std::make_unique<ast::SetDecoration>(val, source);
   }
@@ -1332,11 +1310,8 @@
       return false;
     }
 
-    t = next();
-    if (!t.IsParenLeft()) {
-      add_error(t, "missing ( for stride attribute");
+    if (!expect("stride decoration", Token::Type::kParenLeft))
       return false;
-    }
 
     t = next();
     if (!t.IsSintLiteral()) {
@@ -1350,11 +1325,8 @@
     uint32_t stride = static_cast<uint32_t>(t.to_i32());
     decos.push_back(std::make_unique<ast::StrideDecoration>(stride, source));
 
-    t = next();
-    if (!t.IsParenRight()) {
-      add_error(t, "missing ) for stride attribute");
+    if (!expect("stride decoration", Token::Type::kParenRight))
       return false;
-    }
 
     t = peek();
     if (!t.IsComma()) {
@@ -1666,11 +1638,8 @@
 
   next();  // Consume the peek
 
-  t = next();
-  if (!t.IsParenLeft()) {
-    add_error(t, "missing ( for offset");
+  if (!expect("offset decoration", Token::Type::kParenLeft))
     return nullptr;
-  }
 
   t = next();
   if (!t.IsSintLiteral()) {
@@ -1683,11 +1652,8 @@
     return nullptr;
   }
 
-  t = next();
-  if (!t.IsParenRight()) {
-    add_error(t, "missing ) for offset");
+  if (!expect("offset decoration", Token::Type::kParenRight))
     return nullptr;
-  }
 
   return std::make_unique<ast::StructMemberOffsetDecoration>(val, source);
 }
@@ -1788,11 +1754,8 @@
   if (t.IsWorkgroupSize()) {
     next();  // Consume the peek
 
-    t = next();
-    if (!t.IsParenLeft()) {
-      add_error(t, "missing ( for workgroup_size");
+    if (!expect("workgroup_size decoration", Token::Type::kParenLeft))
       return nullptr;
-    }
 
     t = next();
     if (!t.IsSintLiteral()) {
@@ -1839,11 +1802,8 @@
       }
     }
 
-    t = next();
-    if (!t.IsParenRight()) {
-      add_error(t, "missing ) for workgroup_size");
+    if (!expect("workgroup_size decoration", Token::Type::kParenRight))
       return nullptr;
-    }
 
     return std::make_unique<ast::WorkgroupDecoration>(uint32_t(x), uint32_t(y),
                                                       uint32_t(z), source);
@@ -1851,11 +1811,8 @@
   if (t.IsStage()) {
     next();  // Consume the peek
 
-    t = next();
-    if (!t.IsParenLeft()) {
-      add_error(t, "missing ( for stage decoration");
+    if (!expect("stage decoration", Token::Type::kParenLeft))
       return nullptr;
-    }
 
     auto stage = pipeline_stage();
     if (has_error()) {
@@ -1866,11 +1823,9 @@
       return nullptr;
     }
 
-    t = next();
-    if (!t.IsParenRight()) {
-      add_error(t, "missing ) for stage decoration");
+    if (!expect("stage decoration", Token::Type::kParenRight))
       return nullptr;
-    }
+
     return std::make_unique<ast::StageDecoration>(stage, source);
   }
   return nullptr;
@@ -1903,21 +1858,15 @@
   }
   auto name = t.to_str();
 
-  t = next();
-  if (!t.IsParenLeft()) {
-    add_error(t, "missing ( for function declaration");
+  if (!expect("function declaration", Token::Type::kParenLeft))
     return nullptr;
-  }
 
   auto params = param_list();
   if (has_error())
     return nullptr;
 
-  t = next();
-  if (!t.IsParenRight()) {
-    add_error(t, "missing ) for function declaration");
+  if (!expect("function declaration", Token::Type::kParenRight))
     return nullptr;
-  }
 
   t = next();
   if (!t.IsArrow()) {
@@ -2026,12 +1975,8 @@
 // paren_rhs_stmt
 //   : PAREN_LEFT logical_or_expression PAREN_RIGHT
 std::unique_ptr<ast::Expression> ParserImpl::paren_rhs_stmt() {
-  auto t = peek();
-  if (!t.IsParenLeft()) {
-    add_error(t, "expected (");
+  if (!expect("", Token::Type::kParenLeft))
     return nullptr;
-  }
-  next();  // Consume the peek
 
   auto expr = logical_or_expression();
   if (has_error())
@@ -2041,11 +1986,8 @@
     return nullptr;
   }
 
-  t = next();
-  if (!t.IsParenRight()) {
-    add_error(t, "expected )");
+  if (!expect("", Token::Type::kParenRight))
     return nullptr;
-  }
 
   return expr;
 }
@@ -2614,23 +2556,17 @@
   if (!match(Token::Type::kFor))
     return nullptr;
 
-  auto t = next();
-  if (!t.IsParenLeft()) {
-    add_error(t, "missing for loop (");
+  if (!expect("for loop", Token::Type::kParenLeft))
     return nullptr;
-  }
 
   auto header = for_header();
   if (has_error())
     return nullptr;
 
-  t = next();
-  if (!t.IsParenRight()) {
-    add_error(t, "missing for loop )");
+  if (!expect("for loop", Token::Type::kParenRight))
     return nullptr;
-  }
 
-  t = next();
+  auto t = next();
   if (!t.IsBraceLeft()) {
     add_error(t, "missing for loop {");
     return nullptr;
@@ -2826,11 +2762,8 @@
   if (has_error())
     return nullptr;
   if (type != nullptr) {
-    t = next();
-    if (!t.IsParenLeft()) {
-      add_error(t, "missing ( for type constructor");
+    if (!expect("type constructor", Token::Type::kParenLeft))
       return nullptr;
-    }
 
     t = peek();
     ast::ExpressionList params;
@@ -2840,11 +2773,9 @@
         return nullptr;
     }
 
-    t = next();
-    if (!t.IsParenRight()) {
-      add_error(t, "missing ) for type constructor");
+    if (!expect("type constructor", Token::Type::kParenRight))
       return nullptr;
-    }
+
     return std::make_unique<ast::TypeConstructorExpression>(source, type,
                                                             std::move(params));
   }
@@ -3497,11 +3428,8 @@
 
   auto* type = type_decl();
   if (type != nullptr) {
-    t = next();
-    if (!t.IsParenLeft()) {
-      add_error(t, "missing ( for type constructor");
+    if (!expect("type constructor", Token::Type::kParenLeft))
       return nullptr;
-    }
 
     ast::ExpressionList params;
     auto param = const_expr_internal(depth + 1);
@@ -3529,11 +3457,9 @@
       params.push_back(std::move(param));
     }
 
-    t = next();
-    if (!t.IsParenRight()) {
-      add_error(t, "missing ) for type constructor");
+    if (!expect("type constructor", Token::Type::kParenRight))
       return nullptr;
-    }
+
     return std::make_unique<ast::TypeConstructorExpression>(source, type,
                                                             std::move(params));
   }
diff --git a/src/reader/wgsl/parser_impl_const_expr_test.cc b/src/reader/wgsl/parser_impl_const_expr_test.cc
index 55a1552..fa00f32 100644
--- a/src/reader/wgsl/parser_impl_const_expr_test.cc
+++ b/src/reader/wgsl/parser_impl_const_expr_test.cc
@@ -59,7 +59,7 @@
   auto e = p->const_expr();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:17: missing ) for type constructor");
+  EXPECT_EQ(p->error(), "1:17: expected ')' for type constructor");
 }
 
 TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingLeftParen) {
@@ -67,7 +67,7 @@
   auto e = p->const_expr();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:11: missing ( for type constructor");
+  EXPECT_EQ(p->error(), "1:11: expected '(' for type constructor");
 }
 
 TEST_F(ParserImplTest, ConstExpr_TypeDecl_HangingComma) {
@@ -83,7 +83,7 @@
   auto e = p->const_expr();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:14: missing ) for type constructor");
+  EXPECT_EQ(p->error(), "1:14: expected ')' for type constructor");
 }
 
 TEST_F(ParserImplTest, ConstExpr_MissingExpr) {
diff --git a/src/reader/wgsl/parser_impl_error_msg_test.cc b/src/reader/wgsl/parser_impl_error_msg_test.cc
index c73857d..7e0e446 100644
--- a/src/reader/wgsl/parser_impl_error_msg_test.cc
+++ b/src/reader/wgsl/parser_impl_error_msg_test.cc
@@ -155,14 +155,14 @@
 
 TEST_F(ParserImplErrorTest, ConstructorExprMissingLParen) {
   EXPECT("fn f() -> void { x = vec2<u32>1,2); }",
-         "test.wgsl:1:31 error: missing ( for type constructor\n"
+         "test.wgsl:1:31 error: expected '(' for type constructor\n"
          "fn f() -> void { x = vec2<u32>1,2); }\n"
          "                              ^\n");
 }
 
 TEST_F(ParserImplErrorTest, ConstructorExprMissingRParen) {
   EXPECT("fn f() -> void { x = vec2<u32>(1,2; }",
-         "test.wgsl:1:35 error: missing ) for type constructor\n"
+         "test.wgsl:1:35 error: expected ')' for type constructor\n"
          "fn f() -> void { x = vec2<u32>(1,2; }\n"
          "                                  ^\n");
 }
@@ -225,14 +225,14 @@
 
 TEST_F(ParserImplErrorTest, ForLoopMissingLParen) {
   EXPECT("fn f() -> void { for var i : i32 = 0; i < 8; i=i+1) {} }",
-         "test.wgsl:1:22 error: missing for loop (\n"
+         "test.wgsl:1:22 error: expected '(' for for loop\n"
          "fn f() -> void { for var i : i32 = 0; i < 8; i=i+1) {} }\n"
          "                     ^^^\n");
 }
 
 TEST_F(ParserImplErrorTest, ForLoopMissingRParen) {
   EXPECT("fn f() -> void { for (var i : i32 = 0; i < 8; i=i+1 {} }",
-         "test.wgsl:1:53 error: missing for loop )\n"
+         "test.wgsl:1:53 error: expected ')' for for loop\n"
          "fn f() -> void { for (var i : i32 = 0; i < 8; i=i+1 {} }\n"
          "                                                    ^\n");
 }
@@ -267,14 +267,14 @@
 
 TEST_F(ParserImplErrorTest, FunctionDeclDecoStageMissingLParen) {
   EXPECT("[[stage vertex]] fn f() -> void {}",
-         "test.wgsl:1:9 error: missing ( for stage decoration\n"
+         "test.wgsl:1:9 error: expected '(' for stage decoration\n"
          "[[stage vertex]] fn f() -> void {}\n"
          "        ^^^^^^\n");
 }
 
 TEST_F(ParserImplErrorTest, FunctionDeclDecoStageMissingRParen) {
   EXPECT("[[stage(vertex]] fn f() -> void {}",
-         "test.wgsl:1:15 error: missing ) for stage decoration\n"
+         "test.wgsl:1:15 error: expected ')' for stage decoration\n"
          "[[stage(vertex]] fn f() -> void {}\n"
          "              ^^\n");
 }
@@ -296,14 +296,14 @@
 
 TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeMissingLParen) {
   EXPECT("[[workgroup_size 1]] fn f() -> void {}",
-         "test.wgsl:1:18 error: missing ( for workgroup_size\n"
+         "test.wgsl:1:18 error: expected '(' for workgroup_size decoration\n"
          "[[workgroup_size 1]] fn f() -> void {}\n"
          "                 ^\n");
 }
 
 TEST_F(ParserImplErrorTest, FunctionDeclDecoWorkgroupSizeMissingRParen) {
   EXPECT("[[workgroup_size(1]] fn f() -> void {}",
-         "test.wgsl:1:19 error: missing ) for workgroup_size\n"
+         "test.wgsl:1:19 error: expected ')' for workgroup_size decoration\n"
          "[[workgroup_size(1]] fn f() -> void {}\n"
          "                  ^^\n");
 }
@@ -359,14 +359,14 @@
 
 TEST_F(ParserImplErrorTest, FunctionDeclMissingLParen) {
   EXPECT("fn f) -> void {}",
-         "test.wgsl:1:5 error: missing ( for function declaration\n"
+         "test.wgsl:1:5 error: expected '(' for function declaration\n"
          "fn f) -> void {}\n"
          "    ^\n");
 }
 
 TEST_F(ParserImplErrorTest, FunctionDeclMissingRParen) {
   EXPECT("fn f( -> void {}",
-         "test.wgsl:1:7 error: missing ) for function declaration\n"
+         "test.wgsl:1:7 error: expected ')' for function declaration\n"
          "fn f( -> void {}\n"
          "      ^^\n");
 }
@@ -436,14 +436,14 @@
 
 TEST_F(ParserImplErrorTest, GlobalDeclConstMissingLParen) {
   EXPECT("const i : vec2<i32> = vec2<i32>;",
-         "test.wgsl:1:32 error: missing ( for type constructor\n"
+         "test.wgsl:1:32 error: expected '(' for type constructor\n"
          "const i : vec2<i32> = vec2<i32>;\n"
          "                               ^\n");
 }
 
 TEST_F(ParserImplErrorTest, GlobalDeclConstMissingRParen) {
   EXPECT("const i : vec2<i32> = vec2<i32>(1., 2.;",
-         "test.wgsl:1:39 error: missing ) for type constructor\n"
+         "test.wgsl:1:39 error: expected ')' for type constructor\n"
          "const i : vec2<i32> = vec2<i32>(1., 2.;\n"
          "                                      ^\n");
 }
@@ -491,14 +491,14 @@
 
 TEST_F(ParserImplErrorTest, GlobalDeclConstExprMissingLParen) {
   EXPECT("const i : vec2<i32> = vec2<i32> 1, 2);",
-         "test.wgsl:1:33 error: missing ( for type constructor\n"
+         "test.wgsl:1:33 error: expected '(' for type constructor\n"
          "const i : vec2<i32> = vec2<i32> 1, 2);\n"
          "                                ^\n");
 }
 
 TEST_F(ParserImplErrorTest, GlobalDeclConstExprMissingRParen) {
   EXPECT("const i : vec2<i32> = vec2<i32>(1, 2;",
-         "test.wgsl:1:37 error: missing ) for type constructor\n"
+         "test.wgsl:1:37 error: expected ')' for type constructor\n"
          "const i : vec2<i32> = vec2<i32>(1, 2;\n"
          "                                    ^\n");
 }
@@ -638,14 +638,14 @@
 
 TEST_F(ParserImplErrorTest, GlobalDeclStructMemberOffsetMissingLParen) {
   EXPECT("struct S { [[offset 1)]] i : i32 };",
-         "test.wgsl:1:21 error: missing ( for offset\n"
+         "test.wgsl:1:21 error: expected '(' for offset decoration\n"
          "struct S { [[offset 1)]] i : i32 };\n"
          "                    ^\n");
 }
 
 TEST_F(ParserImplErrorTest, GlobalDeclStructMemberOffsetMissingRParen) {
   EXPECT("struct S { [[offset(1]] i : i32 };",
-         "test.wgsl:1:22 error: missing ) for offset\n"
+         "test.wgsl:1:22 error: expected ')' for offset decoration\n"
          "struct S { [[offset(1]] i : i32 };\n"
          "                     ^^\n");
 }
@@ -736,14 +736,14 @@
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarArrayDecoStrideMissingLParen) {
   EXPECT("var i : [[stride 1)]] array<i32>;",
-         "test.wgsl:1:18 error: missing ( for stride attribute\n"
+         "test.wgsl:1:18 error: expected '(' for stride decoration\n"
          "var i : [[stride 1)]] array<i32>;\n"
          "                 ^\n");
 }
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarArrayDecoStrideMissingRParen) {
   EXPECT("var i : [[stride(1]] array<i32>;",
-         "test.wgsl:1:19 error: missing ) for stride attribute\n"
+         "test.wgsl:1:19 error: expected ')' for stride decoration\n"
          "var i : [[stride(1]] array<i32>;\n"
          "                  ^^\n");
 }
@@ -813,14 +813,14 @@
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarDecoLocationMissingLParen) {
   EXPECT("[[location 1]] var i : i32;",
-         "test.wgsl:1:12 error: missing ( for location decoration\n"
+         "test.wgsl:1:12 error: expected '(' for location decoration\n"
          "[[location 1]] var i : i32;\n"
          "           ^\n");
 }
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarDecoLocationMissingRParen) {
   EXPECT("[[location (1]] var i : i32;",
-         "test.wgsl:1:14 error: missing ) for location decoration\n"
+         "test.wgsl:1:14 error: expected ')' for location decoration\n"
          "[[location (1]] var i : i32;\n"
          "             ^^\n");
 }
@@ -834,14 +834,14 @@
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinMissingLParen) {
   EXPECT("[[builtin position]] var i : i32;",
-         "test.wgsl:1:11 error: missing ( for builtin decoration\n"
+         "test.wgsl:1:11 error: expected '(' for builtin decoration\n"
          "[[builtin position]] var i : i32;\n"
          "          ^^^^^^^^\n");
 }
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBuiltinMissingRParen) {
   EXPECT("[[builtin(position]] var i : i32;",
-         "test.wgsl:1:19 error: missing ) for builtin decoration\n"
+         "test.wgsl:1:19 error: expected ')' for builtin decoration\n"
          "[[builtin(position]] var i : i32;\n"
          "                  ^^\n");
 }
@@ -862,14 +862,14 @@
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingMissingLParen) {
   EXPECT("[[binding 1]] var i : i32;",
-         "test.wgsl:1:11 error: missing ( for binding decoration\n"
+         "test.wgsl:1:11 error: expected '(' for binding decoration\n"
          "[[binding 1]] var i : i32;\n"
          "          ^\n");
 }
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarDecoBindingMissingRParen) {
   EXPECT("[[binding(1]] var i : i32;",
-         "test.wgsl:1:12 error: missing ) for binding decoration\n"
+         "test.wgsl:1:12 error: expected ')' for binding decoration\n"
          "[[binding(1]] var i : i32;\n"
          "           ^^\n");
 }
@@ -883,14 +883,14 @@
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarDecoSetMissingLParen) {
   EXPECT("[[set 1]] var i : i32;",
-         "test.wgsl:1:7 error: missing ( for set decoration\n"
+         "test.wgsl:1:7 error: expected '(' for set decoration\n"
          "[[set 1]] var i : i32;\n"
          "      ^\n");
 }
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarDecoSetMissingRParen) {
   EXPECT("[[set(1]] var i : i32;",
-         "test.wgsl:1:8 error: missing ) for set decoration\n"
+         "test.wgsl:1:8 error: expected ')' for set decoration\n"
          "[[set(1]] var i : i32;\n"
          "       ^^\n");
 }
@@ -1009,14 +1009,14 @@
 
 TEST_F(ParserImplErrorTest, IfStmtMissingLParen) {
   EXPECT("fn f() -> void { if true) {} }",
-         "test.wgsl:1:21 error: expected (\n"
+         "test.wgsl:1:21 error: expected '('\n"
          "fn f() -> void { if true) {} }\n"
          "                    ^^^^\n");
 }
 
 TEST_F(ParserImplErrorTest, IfStmtMissingRParen) {
   EXPECT("fn f() -> void { if (true {} }",
-         "test.wgsl:1:27 error: expected )\n"
+         "test.wgsl:1:27 error: expected ')'\n"
          "fn f() -> void { if (true {} }\n"
          "                          ^\n");
 }
diff --git a/src/reader/wgsl/parser_impl_for_stmt_test.cc b/src/reader/wgsl/parser_impl_for_stmt_test.cc
index bbd036b..6fffc65 100644
--- a/src/reader/wgsl/parser_impl_for_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_for_stmt_test.cc
@@ -168,7 +168,7 @@
 // Test a for loop with missing left parenthesis is invalid.
 TEST_F(ForStmtErrorTest, MissingLeftParen) {
   std::string for_str = "for { }";
-  std::string error_str = "1:5: missing for loop (";
+  std::string error_str = "1:5: expected '(' for for loop";
 
   TestForWithError(for_str, error_str);
 }
@@ -192,7 +192,7 @@
 // Test a for loop with missing right parenthesis is invalid.
 TEST_F(ForStmtErrorTest, MissingRightParen) {
   std::string for_str = "for (;; {}";
-  std::string error_str = "1:9: missing for loop )";
+  std::string error_str = "1:9: expected ')' for for loop";
 
   TestForWithError(for_str, error_str);
 }
@@ -233,7 +233,7 @@
 // Test a for loop with an invalid break condition.
 TEST_F(ForStmtErrorTest, InvalidBreakConditionAsExpression) {
   std::string for_str = "for (; (0 == 1; ) { }";
-  std::string error_str = "1:15: expected )";
+  std::string error_str = "1:15: expected ')'";
 
   TestForWithError(for_str, error_str);
 }
@@ -259,7 +259,7 @@
 // assignment_stmt | func_call_stmt.
 TEST_F(ForStmtErrorTest, InvalidContinuingMatch) {
   std::string for_str = "for (;; var i: i32 = 0) { }";
-  std::string error_str = "1:9: missing for loop )";
+  std::string error_str = "1:9: expected ')' for for loop";
 
   TestForWithError(for_str, error_str);
 }
diff --git a/src/reader/wgsl/parser_impl_function_decoration_test.cc b/src/reader/wgsl/parser_impl_function_decoration_test.cc
index d8661a3..5e8ae5b 100644
--- a/src/reader/wgsl/parser_impl_function_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_function_decoration_test.cc
@@ -76,7 +76,7 @@
   auto deco = p->function_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:23: missing ) for workgroup_size");
+  EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size decoration");
 }
 
 TEST_F(ParserImplTest, FunctionDecoration_Workgroup_Invalid_X_Value) {
@@ -108,7 +108,7 @@
   auto deco = p->function_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:16: missing ( for workgroup_size");
+  EXPECT_EQ(p->error(), "1:16: expected '(' for workgroup_size decoration");
 }
 
 TEST_F(ParserImplTest, FunctionDecoration_Workgroup_MissingRightParam) {
@@ -116,7 +116,7 @@
   auto deco = p->function_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:23: missing ) for workgroup_size");
+  EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size decoration");
 }
 
 TEST_F(ParserImplTest, FunctionDecoration_Workgroup_MissingValues) {
@@ -140,7 +140,7 @@
   auto deco = p->function_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:18: missing ) for workgroup_size");
+  EXPECT_EQ(p->error(), "1:18: expected ')' for workgroup_size decoration");
 }
 
 TEST_F(ParserImplTest, FunctionDecoration_Workgroup_Missing_Y_Value) {
@@ -156,7 +156,7 @@
   auto deco = p->function_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:21: missing ) for workgroup_size");
+  EXPECT_EQ(p->error(), "1:21: expected ')' for workgroup_size decoration");
 }
 
 TEST_F(ParserImplTest, FunctionDecoration_Workgroup_Missing_Z_Value) {
@@ -221,7 +221,7 @@
   auto deco = p->function_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:7: missing ( for stage decoration");
+  EXPECT_EQ(p->error(), "1:7: expected '(' for stage decoration");
 }
 
 TEST_F(ParserImplTest, FunctionDecoration_Stage_MissingRightParen) {
@@ -229,7 +229,7 @@
   auto deco = p->function_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:14: missing ) for stage decoration");
+  EXPECT_EQ(p->error(), "1:14: expected ')' for stage decoration");
 }
 
 }  // namespace
diff --git a/src/reader/wgsl/parser_impl_function_header_test.cc b/src/reader/wgsl/parser_impl_function_header_test.cc
index df0eabf..469dafe 100644
--- a/src/reader/wgsl/parser_impl_function_header_test.cc
+++ b/src/reader/wgsl/parser_impl_function_header_test.cc
@@ -57,7 +57,7 @@
   auto f = p->function_header();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(f, nullptr);
-  EXPECT_EQ(p->error(), "1:8: missing ( for function declaration");
+  EXPECT_EQ(p->error(), "1:8: expected '(' for function declaration");
 }
 
 TEST_F(ParserImplTest, FunctionHeader_InvalidParamList) {
@@ -73,7 +73,7 @@
   auto f = p->function_header();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(f, nullptr);
-  EXPECT_EQ(p->error(), "1:10: missing ) for function declaration");
+  EXPECT_EQ(p->error(), "1:10: expected ')' for function declaration");
 }
 
 TEST_F(ParserImplTest, FunctionHeader_MissingArrow) {
diff --git a/src/reader/wgsl/parser_impl_if_stmt_test.cc b/src/reader/wgsl/parser_impl_if_stmt_test.cc
index 2898c87..63cba71 100644
--- a/src/reader/wgsl/parser_impl_if_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_if_stmt_test.cc
@@ -62,7 +62,7 @@
   auto e = p->if_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:7: expected )");
+  EXPECT_EQ(p->error(), "1:7: expected ')'");
 }
 
 TEST_F(ParserImplTest, IfStmt_MissingCondition) {
@@ -70,7 +70,7 @@
   auto e = p->if_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:4: expected (");
+  EXPECT_EQ(p->error(), "1:4: expected '('");
 }
 
 TEST_F(ParserImplTest, IfStmt_InvalidBody) {
diff --git a/src/reader/wgsl/parser_impl_paren_rhs_stmt_test.cc b/src/reader/wgsl/parser_impl_paren_rhs_stmt_test.cc
index 0610446..75ec3ea 100644
--- a/src/reader/wgsl/parser_impl_paren_rhs_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_paren_rhs_stmt_test.cc
@@ -34,7 +34,7 @@
   auto e = p->paren_rhs_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:1: expected (");
+  EXPECT_EQ(p->error(), "1:1: expected '('");
 }
 
 TEST_F(ParserImplTest, ParenRhsStmt_MissingRightParen) {
@@ -42,7 +42,7 @@
   auto e = p->paren_rhs_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:6: expected )");
+  EXPECT_EQ(p->error(), "1:6: expected ')'");
 }
 
 TEST_F(ParserImplTest, ParenRhsStmt_InvalidExpression) {
diff --git a/src/reader/wgsl/parser_impl_primary_expression_test.cc b/src/reader/wgsl/parser_impl_primary_expression_test.cc
index 4560dbe..41c218c 100644
--- a/src/reader/wgsl/parser_impl_primary_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_primary_expression_test.cc
@@ -103,7 +103,7 @@
   auto e = p->primary_expression();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:11: missing ( for type constructor");
+  EXPECT_EQ(p->error(), "1:11: expected '(' for type constructor");
 }
 
 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_MissingRightParen) {
@@ -111,7 +111,7 @@
   auto e = p->primary_expression();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:25: missing ) for type constructor");
+  EXPECT_EQ(p->error(), "1:25: expected ')' for type constructor");
 }
 
 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_InvalidValue) {
@@ -147,7 +147,7 @@
   auto e = p->primary_expression();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:8: expected )");
+  EXPECT_EQ(p->error(), "1:8: expected ')'");
 }
 
 TEST_F(ParserImplTest, PrimaryExpression_ParenExpr_MissingExpr) {
@@ -229,7 +229,7 @@
   auto e = p->primary_expression();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:13: expected (");
+  EXPECT_EQ(p->error(), "1:13: expected '('");
 }
 
 TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingRightParen) {
@@ -237,7 +237,7 @@
   auto e = p->primary_expression();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:15: expected )");
+  EXPECT_EQ(p->error(), "1:15: expected ')'");
 }
 
 TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingExpression) {
diff --git a/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc b/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc
index c01be53..a6d2ff7 100644
--- a/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_member_decoration_test.cc
@@ -38,7 +38,7 @@
   auto deco = p->struct_member_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:8: missing ( for offset");
+  EXPECT_EQ(p->error(), "1:8: expected '(' for offset decoration");
 }
 
 TEST_F(ParserImplTest, StructMemberDecoration_Offset_MissingRightParen) {
@@ -46,7 +46,7 @@
   auto deco = p->struct_member_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:9: missing ) for offset");
+  EXPECT_EQ(p->error(), "1:9: expected ')' for offset decoration");
 }
 
 TEST_F(ParserImplTest, StructMemberDecoration_Offset_MissingValue) {
diff --git a/src/reader/wgsl/parser_impl_switch_stmt_test.cc b/src/reader/wgsl/parser_impl_switch_stmt_test.cc
index 3d3a515..c3f99d6 100644
--- a/src/reader/wgsl/parser_impl_switch_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_switch_stmt_test.cc
@@ -68,7 +68,7 @@
   auto e = p->switch_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:9: expected )");
+  EXPECT_EQ(p->error(), "1:9: expected ')'");
 }
 
 TEST_F(ParserImplTest, SwitchStmt_MissingExpression) {
@@ -76,7 +76,7 @@
   auto e = p->switch_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:8: expected (");
+  EXPECT_EQ(p->error(), "1:8: expected '('");
 }
 
 TEST_F(ParserImplTest, SwitchStmt_MissingBracketLeft) {
diff --git a/src/reader/wgsl/parser_impl_type_decl_test.cc b/src/reader/wgsl/parser_impl_type_decl_test.cc
index 7ad9e56..55e9cd3 100644
--- a/src/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_type_decl_test.cc
@@ -408,7 +408,7 @@
   auto* t = p->type_decl();
   ASSERT_EQ(t, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:10: missing ( for stride attribute");
+  EXPECT_EQ(p->error(), "1:10: expected '(' for stride decoration");
 }
 
 TEST_F(ParserImplTest, TypeDecl_Array_Stride_MissingRightParen) {
@@ -416,7 +416,7 @@
   auto* t = p->type_decl();
   ASSERT_EQ(t, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:11: missing ) for stride attribute");
+  EXPECT_EQ(p->error(), "1:11: expected ')' for stride decoration");
 }
 
 TEST_F(ParserImplTest, TypeDecl_Array_Stride_MissingValue) {
diff --git a/src/reader/wgsl/parser_impl_variable_decoration_test.cc b/src/reader/wgsl/parser_impl_variable_decoration_test.cc
index d2c7755..68736e8 100644
--- a/src/reader/wgsl/parser_impl_variable_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_variable_decoration_test.cc
@@ -41,7 +41,7 @@
   auto deco = p->variable_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:10: missing ( for location decoration");
+  EXPECT_EQ(p->error(), "1:10: expected '(' for location decoration");
 }
 
 TEST_F(ParserImplTest, VariableDecoration_Location_MissingRightParen) {
@@ -49,7 +49,7 @@
   auto deco = p->variable_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:11: missing ) for location decoration");
+  EXPECT_EQ(p->error(), "1:11: expected ')' for location decoration");
 }
 
 TEST_F(ParserImplTest, VariableDecoration_Location_MissingValue) {
@@ -111,7 +111,7 @@
   auto deco = p->variable_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:9: missing ( for builtin decoration");
+  EXPECT_EQ(p->error(), "1:9: expected '(' for builtin decoration");
 }
 
 TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingRightParen) {
@@ -119,7 +119,7 @@
   auto deco = p->variable_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:17: missing ) for builtin decoration");
+  EXPECT_EQ(p->error(), "1:17: expected ')' for builtin decoration");
 }
 
 TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingValue) {
@@ -162,7 +162,7 @@
   auto deco = p->variable_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:9: missing ( for binding decoration");
+  EXPECT_EQ(p->error(), "1:9: expected '(' for binding decoration");
 }
 
 TEST_F(ParserImplTest, VariableDecoration_Binding_MissingRightParen) {
@@ -170,7 +170,7 @@
   auto deco = p->variable_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:10: missing ) for binding decoration");
+  EXPECT_EQ(p->error(), "1:10: expected ')' for binding decoration");
 }
 
 TEST_F(ParserImplTest, VariableDecoration_Binding_MissingValue) {
@@ -205,7 +205,7 @@
   auto deco = p->variable_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:5: missing ( for set decoration");
+  EXPECT_EQ(p->error(), "1:5: expected '(' for set decoration");
 }
 
 TEST_F(ParserImplTest, VariableDecoration_Set_MissingRightParen) {
@@ -213,7 +213,7 @@
   auto deco = p->variable_decoration();
   ASSERT_EQ(deco, nullptr);
   ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(), "1:6: missing ) for set decoration");
+  EXPECT_EQ(p->error(), "1:6: expected ')' for set decoration");
 }
 
 TEST_F(ParserImplTest, VariableDecoration_Set_MissingValue) {