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:
parent
e6307e5100
commit
961dc6fbf5
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue