wgsl::ParserImpl: Use sync() for postfix_expr()
postfix_expr() handles `[]` array accessors and call expressions `()`. Have postfix_expr() use sync to parse these: * It will use the end bracket token to attempt to resynchronize the parser on error * It also considers maximum parser recursion depth, avoiding stack overflows Fixed: chromium:1180573 Change-Id: I8c1c62c68e24a564e0e4e7d0de9f5a3fa7032369 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/42222 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
6d612ad478
commit
03eaff3b0a
|
@ -2136,34 +2136,38 @@ Maybe<ast::Expression*> ParserImpl::primary_expression() {
|
||||||
Maybe<ast::Expression*> ParserImpl::postfix_expr(ast::Expression* prefix) {
|
Maybe<ast::Expression*> ParserImpl::postfix_expr(ast::Expression* prefix) {
|
||||||
Source source;
|
Source source;
|
||||||
if (match(Token::Type::kBracketLeft, &source)) {
|
if (match(Token::Type::kBracketLeft, &source)) {
|
||||||
auto param = logical_or_expression();
|
return sync(Token::Type::kBracketRight, [&]() -> Maybe<ast::Expression*> {
|
||||||
if (param.errored)
|
auto param = logical_or_expression();
|
||||||
return Failure::kErrored;
|
if (param.errored)
|
||||||
if (!param.matched)
|
return Failure::kErrored;
|
||||||
return add_error(peek(), "unable to parse expression inside []");
|
if (!param.matched)
|
||||||
|
return add_error(peek(), "unable to parse expression inside []");
|
||||||
|
|
||||||
if (!expect("array accessor", Token::Type::kBracketRight))
|
if (!expect("array accessor", Token::Type::kBracketRight))
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
return postfix_expr(
|
return postfix_expr(
|
||||||
create<ast::ArrayAccessorExpression>(source, prefix, param.value));
|
create<ast::ArrayAccessorExpression>(source, prefix, param.value));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match(Token::Type::kParenLeft, &source)) {
|
if (match(Token::Type::kParenLeft, &source)) {
|
||||||
ast::ExpressionList params;
|
return sync(Token::Type::kParenRight, [&]() -> Maybe<ast::Expression*> {
|
||||||
|
ast::ExpressionList params;
|
||||||
|
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
if (!t.IsParenRight() && !t.IsEof()) {
|
if (!t.IsParenRight() && !t.IsEof()) {
|
||||||
auto list = expect_argument_expression_list();
|
auto list = expect_argument_expression_list();
|
||||||
if (list.errored)
|
if (list.errored)
|
||||||
|
return Failure::kErrored;
|
||||||
|
params = list.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!expect("call expression", Token::Type::kParenRight))
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
params = list.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!expect("call expression", Token::Type::kParenRight))
|
return postfix_expr(create<ast::CallExpression>(source, prefix, params));
|
||||||
return Failure::kErrored;
|
});
|
||||||
|
|
||||||
return postfix_expr(create<ast::CallExpression>(source, prefix, params));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match(Token::Type::kPeriod)) {
|
if (match(Token::Type::kPeriod)) {
|
||||||
|
|
Loading…
Reference in New Issue