From 652d40a3d1e954b560e2ad441cb653a8b5620380 Mon Sep 17 00:00:00 2001 From: Vasyl Teliman Date: Tue, 16 Feb 2021 14:53:49 +0000 Subject: [PATCH] wgsl-reader: Add support for nested array accessors Bug: tint:501 Change-Id: I23f4e73696f48d29b3f9d63997fa1c5004cf4d34 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/41622 Reviewed-by: dan sinclair Commit-Queue: dan sinclair --- src/reader/wgsl/parser_impl.cc | 11 +++++++ .../parser_impl_postfix_expression_test.cc | 31 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc index 415688e535..708157b105 100644 --- a/src/reader/wgsl/parser_impl.cc +++ b/src/reader/wgsl/parser_impl.cc @@ -3055,6 +3055,17 @@ bool ParserImpl::expect(const std::string& use, Token::Type tok) { return true; } + // Handle the case when `]` is expected but the actual token is `]]`. + // For example, in `arr1[arr2[0]]`. + if (tok == Token::Type::kBracketRight && t.IsAttrRight()) { + next(); + auto source = t.source(); + source.range.begin.column++; + token_queue_.push_front({Token::Type::kBracketRight, source}); + synchronized_ = true; + return true; + } + std::stringstream err; err << "expected '" << Token::TypeToName(tok) << "'"; if (!use.empty()) { diff --git a/src/reader/wgsl/parser_impl_postfix_expression_test.cc b/src/reader/wgsl/parser_impl_postfix_expression_test.cc index 43ed375aaf..6bf2531680 100644 --- a/src/reader/wgsl/parser_impl_postfix_expression_test.cc +++ b/src/reader/wgsl/parser_impl_postfix_expression_test.cc @@ -217,6 +217,37 @@ TEST_F(ParserImplTest, PostfixExpression_NonMatch_returnLHS) { ASSERT_TRUE(e->Is()); } +TEST_F(ParserImplTest, PostfixExpression_Array_NestedArrayAccessor) { + auto p = parser("a[b[c]]"); + auto e = p->postfix_expression(); + EXPECT_TRUE(e.matched); + EXPECT_FALSE(e.errored); + EXPECT_FALSE(p->has_error()) << p->error(); + ASSERT_NE(e.value, nullptr); + + const auto* outer_accessor = e->As(); + ASSERT_TRUE(outer_accessor); + + const auto* outer_array = + outer_accessor->array()->As(); + ASSERT_TRUE(outer_array); + EXPECT_EQ(outer_array->symbol(), p->builder().Symbols().Get("a")); + + const auto* inner_accessor = + outer_accessor->idx_expr()->As(); + ASSERT_TRUE(inner_accessor); + + const auto* inner_array = + inner_accessor->array()->As(); + ASSERT_TRUE(inner_array); + EXPECT_EQ(inner_array->symbol(), p->builder().Symbols().Get("b")); + + const auto* index_expr = + inner_accessor->idx_expr()->As(); + ASSERT_TRUE(index_expr); + EXPECT_EQ(index_expr->symbol(), p->builder().Symbols().Get("c")); +} + } // namespace } // namespace wgsl } // namespace reader