reader/wgsl: match spec rules for function calls

Function calls should be parsed in `primary_expression`. Renames the
old `postfix_expression` to `singular_expression`, with the recursive
part now becoming `postfix_expression`.

Fixed: tint:170
Change-Id: I1afad794880916db38a25d73447cdaf84abd6584
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49464
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: James Price <jrprice@google.com>
This commit is contained in:
James Price 2021-04-29 15:02:15 +00:00 committed by Commit Bot service account
parent e6307e5100
commit 961dc6fbf5
5 changed files with 69 additions and 66 deletions

View File

@ -675,12 +675,12 @@ if(${TINT_BUILD_TESTS})
reader/wgsl/parser_impl_param_list_test.cc
reader/wgsl/parser_impl_paren_rhs_stmt_test.cc
reader/wgsl/parser_impl_pipeline_stage_test.cc
reader/wgsl/parser_impl_postfix_expression_test.cc
reader/wgsl/parser_impl_primary_expression_test.cc
reader/wgsl/parser_impl_relational_expression_test.cc
reader/wgsl/parser_impl_sampled_texture_type_test.cc
reader/wgsl/parser_impl_sampler_type_test.cc
reader/wgsl/parser_impl_shift_expression_test.cc
reader/wgsl/parser_impl_singular_expression_test.cc
reader/wgsl/parser_impl_statement_test.cc
reader/wgsl/parser_impl_statements_test.cc
reader/wgsl/parser_impl_storage_class_test.cc

View File

@ -2196,7 +2196,7 @@ Maybe<ast::BlockStatement*> ParserImpl::continuing_stmt() {
}
// primary_expression
// : IDENT
// : IDENT argument_expression_list?
// | type_decl PAREN_LEFT argument_expression_list* PAREN_RIGHT
// | const_literal
// | paren_rhs_stmt
@ -2235,8 +2235,30 @@ Maybe<ast::Expression*> ParserImpl::primary_expression() {
if (t.IsIdentifier() && !get_constructed(t.to_str())) {
next();
return create<ast::IdentifierExpression>(
auto* ident = create<ast::IdentifierExpression>(
t.source(), builder_.Symbols().Register(t.to_str()));
if (match(Token::Type::kParenLeft, &source)) {
return sync(Token::Type::kParenRight, [&]() -> Maybe<ast::Expression*> {
ast::ExpressionList params;
auto t2 = peek();
if (!t2.IsParenRight() && !t2.IsEof()) {
auto list = expect_argument_expression_list();
if (list.errored)
return Failure::kErrored;
params = list.value;
}
if (!expect("call expression", Token::Type::kParenRight))
return Failure::kErrored;
return create<ast::CallExpression>(source, ident, params);
});
}
return ident;
}
auto type = type_decl();
@ -2267,12 +2289,12 @@ Maybe<ast::Expression*> ParserImpl::primary_expression() {
return Failure::kNoMatch;
}
// postfix_expr
// postfix_expression
// :
// | BRACE_LEFT logical_or_expression BRACE_RIGHT postfix_expr
// | PAREN_LEFT argument_expression_list* PAREN_RIGHT postfix_expr
// | PERIOD IDENTIFIER postfix_expr
Maybe<ast::Expression*> ParserImpl::postfix_expr(ast::Expression* prefix) {
Maybe<ast::Expression*> ParserImpl::postfix_expression(
ast::Expression* prefix) {
Source source;
if (match(Token::Type::kBracketLeft, &source)) {
return sync(Token::Type::kBracketRight, [&]() -> Maybe<ast::Expression*> {
@ -2285,36 +2307,17 @@ Maybe<ast::Expression*> ParserImpl::postfix_expr(ast::Expression* prefix) {
if (!expect("array accessor", Token::Type::kBracketRight))
return Failure::kErrored;
return postfix_expr(
return postfix_expression(
create<ast::ArrayAccessorExpression>(source, prefix, param.value));
});
}
if (match(Token::Type::kParenLeft, &source)) {
return sync(Token::Type::kParenRight, [&]() -> Maybe<ast::Expression*> {
ast::ExpressionList params;
auto t = peek();
if (!t.IsParenRight() && !t.IsEof()) {
auto list = expect_argument_expression_list();
if (list.errored)
return Failure::kErrored;
params = list.value;
}
if (!expect("call expression", Token::Type::kParenRight))
return Failure::kErrored;
return postfix_expr(create<ast::CallExpression>(source, prefix, params));
});
}
if (match(Token::Type::kPeriod)) {
auto ident = expect_ident("member accessor");
if (ident.errored)
return Failure::kErrored;
return postfix_expr(create<ast::MemberAccessorExpression>(
return postfix_expression(create<ast::MemberAccessorExpression>(
ident.source, prefix,
create<ast::IdentifierExpression>(
ident.source, builder_.Symbols().Register(ident.value))));
@ -2323,16 +2326,16 @@ Maybe<ast::Expression*> ParserImpl::postfix_expr(ast::Expression* prefix) {
return prefix;
}
// postfix_expression
// singular_expression
// : primary_expression postfix_expr
Maybe<ast::Expression*> ParserImpl::postfix_expression() {
Maybe<ast::Expression*> ParserImpl::singular_expression() {
auto prefix = primary_expression();
if (prefix.errored)
return Failure::kErrored;
if (!prefix.matched)
return Failure::kNoMatch;
return postfix_expr(prefix.value);
return postfix_expression(prefix.value);
}
// argument_expression_list
@ -2361,7 +2364,7 @@ Expect<ast::ExpressionList> ParserImpl::expect_argument_expression_list() {
}
// unary_expression
// : postfix_expression
// : singular_expression
// | MINUS unary_expression
// | BANG unary_expression
Maybe<ast::Expression*> ParserImpl::unary_expression() {
@ -2385,7 +2388,7 @@ Maybe<ast::Expression*> ParserImpl::unary_expression() {
return create<ast::UnaryOpExpression>(source, op, expr.value);
}
return postfix_expression();
return singular_expression();
}
// multiplicative_expr

View File

@ -557,10 +557,10 @@ class ParserImpl {
/// Parses the recursive portion of the postfix_expression
/// @param prefix the left side of the expression
/// @returns the parsed expression or nullptr
Maybe<ast::Expression*> postfix_expr(ast::Expression* prefix);
/// Parses a `postfix_expression` grammar elment
Maybe<ast::Expression*> postfix_expression(ast::Expression* prefix);
/// Parses a `singular_expression` grammar elment
/// @returns the parsed expression or nullptr
Maybe<ast::Expression*> postfix_expression();
Maybe<ast::Expression*> singular_expression();
/// Parses a `unary_expression` grammar element
/// @returns the parsed expression or nullptr
Maybe<ast::Expression*> unary_expression();

View File

@ -19,9 +19,9 @@ namespace reader {
namespace wgsl {
namespace {
TEST_F(ParserImplTest, PostfixExpression_Array_ConstantIndex) {
TEST_F(ParserImplTest, SingularExpression_Array_ConstantIndex) {
auto p = parser("a[1]");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@ -41,9 +41,9 @@ TEST_F(ParserImplTest, PostfixExpression_Array_ConstantIndex) {
EXPECT_EQ(c->literal()->As<ast::SintLiteral>()->value(), 1);
}
TEST_F(ParserImplTest, PostfixExpression_Array_ExpressionIndex) {
TEST_F(ParserImplTest, SingularExpression_Array_ExpressionIndex) {
auto p = parser("a[1 + b / 4]");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@ -59,9 +59,9 @@ TEST_F(ParserImplTest, PostfixExpression_Array_ExpressionIndex) {
ASSERT_TRUE(ary->idx_expr()->Is<ast::BinaryExpression>());
}
TEST_F(ParserImplTest, PostfixExpression_Array_MissingIndex) {
TEST_F(ParserImplTest, SingularExpression_Array_MissingIndex) {
auto p = parser("a[]");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@ -69,9 +69,9 @@ TEST_F(ParserImplTest, PostfixExpression_Array_MissingIndex) {
EXPECT_EQ(p->error(), "1:3: unable to parse expression inside []");
}
TEST_F(ParserImplTest, PostfixExpression_Array_MissingRightBrace) {
TEST_F(ParserImplTest, SingularExpression_Array_MissingRightBrace) {
auto p = parser("a[1");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@ -79,9 +79,9 @@ TEST_F(ParserImplTest, PostfixExpression_Array_MissingRightBrace) {
EXPECT_EQ(p->error(), "1:4: expected ']' for array accessor");
}
TEST_F(ParserImplTest, PostfixExpression_Array_InvalidIndex) {
TEST_F(ParserImplTest, SingularExpression_Array_InvalidIndex) {
auto p = parser("a[if(a() {})]");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@ -89,9 +89,9 @@ TEST_F(ParserImplTest, PostfixExpression_Array_InvalidIndex) {
EXPECT_EQ(p->error(), "1:3: unable to parse expression inside []");
}
TEST_F(ParserImplTest, PostfixExpression_Call_Empty) {
TEST_F(ParserImplTest, SingularExpression_Call_Empty) {
auto p = parser("a()");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@ -107,9 +107,9 @@ TEST_F(ParserImplTest, PostfixExpression_Call_Empty) {
EXPECT_EQ(c->params().size(), 0u);
}
TEST_F(ParserImplTest, PostfixExpression_Call_WithArgs) {
TEST_F(ParserImplTest, SingularExpression_Call_WithArgs) {
auto p = parser("test(1, b, 2 + 3 / b)");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@ -128,9 +128,9 @@ TEST_F(ParserImplTest, PostfixExpression_Call_WithArgs) {
EXPECT_TRUE(c->params()[2]->Is<ast::BinaryExpression>());
}
TEST_F(ParserImplTest, PostfixExpression_Call_InvalidArg) {
TEST_F(ParserImplTest, SingularExpression_Call_InvalidArg) {
auto p = parser("a(if(a) {})");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@ -138,9 +138,9 @@ TEST_F(ParserImplTest, PostfixExpression_Call_InvalidArg) {
EXPECT_EQ(p->error(), "1:3: unable to parse argument expression");
}
TEST_F(ParserImplTest, PostfixExpression_Call_HangingComma) {
TEST_F(ParserImplTest, SingularExpression_Call_HangingComma) {
auto p = parser("a(b, )");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@ -148,9 +148,9 @@ TEST_F(ParserImplTest, PostfixExpression_Call_HangingComma) {
EXPECT_EQ(p->error(), "1:6: unable to parse argument expression after comma");
}
TEST_F(ParserImplTest, PostfixExpression_Call_MissingRightParen) {
TEST_F(ParserImplTest, SingularExpression_Call_MissingRightParen) {
auto p = parser("a(");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@ -158,9 +158,9 @@ TEST_F(ParserImplTest, PostfixExpression_Call_MissingRightParen) {
EXPECT_EQ(p->error(), "1:3: expected ')' for call expression");
}
TEST_F(ParserImplTest, PostfixExpression_MemberAccessor) {
TEST_F(ParserImplTest, SingularExpression_MemberAccessor) {
auto p = parser("a.b");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@ -177,9 +177,9 @@ TEST_F(ParserImplTest, PostfixExpression_MemberAccessor) {
p->builder().Symbols().Get("b"));
}
TEST_F(ParserImplTest, PostfixExpression_MemberAccesssor_InvalidIdent) {
TEST_F(ParserImplTest, SingularExpression_MemberAccesssor_InvalidIdent) {
auto p = parser("a.if");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@ -187,9 +187,9 @@ TEST_F(ParserImplTest, PostfixExpression_MemberAccesssor_InvalidIdent) {
EXPECT_EQ(p->error(), "1:3: expected identifier for member accessor");
}
TEST_F(ParserImplTest, PostfixExpression_MemberAccessor_MissingIdent) {
TEST_F(ParserImplTest, SingularExpression_MemberAccessor_MissingIdent) {
auto p = parser("a.");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr);
@ -197,9 +197,9 @@ TEST_F(ParserImplTest, PostfixExpression_MemberAccessor_MissingIdent) {
EXPECT_EQ(p->error(), "1:3: expected identifier for member accessor");
}
TEST_F(ParserImplTest, PostfixExpression_NonMatch_returnLHS) {
TEST_F(ParserImplTest, SingularExpression_NonMatch_returnLHS) {
auto p = parser("a b");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
@ -207,9 +207,9 @@ TEST_F(ParserImplTest, PostfixExpression_NonMatch_returnLHS) {
ASSERT_TRUE(e->Is<ast::IdentifierExpression>());
}
TEST_F(ParserImplTest, PostfixExpression_Array_NestedArrayAccessor) {
TEST_F(ParserImplTest, SingularExpression_Array_NestedArrayAccessor) {
auto p = parser("a[b[c]]");
auto e = p->postfix_expression();
auto e = p->singular_expression();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();

View File

@ -438,12 +438,12 @@ tint_unittests_source_set("tint_unittests_wgsl_reader_src") {
"../src/reader/wgsl/parser_impl_param_list_test.cc",
"../src/reader/wgsl/parser_impl_paren_rhs_stmt_test.cc",
"../src/reader/wgsl/parser_impl_pipeline_stage_test.cc",
"../src/reader/wgsl/parser_impl_postfix_expression_test.cc",
"../src/reader/wgsl/parser_impl_primary_expression_test.cc",
"../src/reader/wgsl/parser_impl_relational_expression_test.cc",
"../src/reader/wgsl/parser_impl_sampled_texture_type_test.cc",
"../src/reader/wgsl/parser_impl_sampler_type_test.cc",
"../src/reader/wgsl/parser_impl_shift_expression_test.cc",
"../src/reader/wgsl/parser_impl_singular_expression_test.cc",
"../src/reader/wgsl/parser_impl_statement_test.cc",
"../src/reader/wgsl/parser_impl_statements_test.cc",
"../src/reader/wgsl/parser_impl_storage_class_test.cc",