Skip to content

Commit af579d2

Browse files
committed
Reduce backtracking when parsing fold expressions
1 parent 53b8c38 commit af579d2

File tree

1 file changed

+36
-30
lines changed

1 file changed

+36
-30
lines changed

src/parser/cxx/parser.cc

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -687,37 +687,25 @@ auto Parser::parse_completion(SourceLocation& loc) -> bool {
687687

688688
auto Parser::parse_primary_expression(ExpressionAST*& yyast,
689689
const ExprContext& ctx) -> bool {
690-
UnqualifiedIdAST* name = nullptr;
691-
692-
if (parse_builtin_call_expression(yyast, ctx)) {
693-
return true;
694-
} else if (parse_builtin_offsetof_expression(yyast, ctx)) {
695-
return true;
696-
} else if (parse_this_expression(yyast)) {
697-
return true;
698-
} else if (parse_literal(yyast)) {
699-
return true;
700-
} else if (parse_lambda_expression(yyast)) {
701-
return true;
702-
} else if (parse_requires_expression(yyast)) {
703-
return true;
704-
} else if (lookat(TokenKind::T_LPAREN, TokenKind::T_RPAREN)) {
705-
return false;
706-
} else if (parse_fold_expression(yyast, ctx)) {
707-
return true;
708-
} else if (parse_nested_expession(yyast, ctx)) {
709-
return true;
710-
} else if (IdExpressionAST* idExpression = nullptr; parse_id_expression(
711-
idExpression, ctx.inRequiresClause
712-
? IdExpressionContext::kRequiresClause
713-
: IdExpressionContext::kExpression)) {
690+
if (parse_builtin_call_expression(yyast, ctx)) return true;
691+
if (parse_builtin_offsetof_expression(yyast, ctx)) return true;
692+
if (parse_this_expression(yyast)) return true;
693+
if (parse_literal(yyast)) return true;
694+
if (parse_lambda_expression(yyast)) return true;
695+
if (parse_requires_expression(yyast)) return true;
696+
if (lookat(TokenKind::T_LPAREN, TokenKind::T_RPAREN)) return false;
697+
if (parse_fold_expression(yyast, ctx)) return true;
698+
if (parse_nested_expession(yyast, ctx)) return true;
699+
if (IdExpressionAST* idExpression = nullptr; parse_id_expression(
700+
idExpression, ctx.inRequiresClause
701+
? IdExpressionContext::kRequiresClause
702+
: IdExpressionContext::kExpression)) {
714703
yyast = idExpression;
715704
return true;
716-
} else if (parse_splicer_expression(yyast, ctx)) {
717-
return true;
718-
} else {
719-
return false;
720705
}
706+
707+
if (parse_splicer_expression(yyast, ctx)) return true;
708+
return false;
721709
}
722710

723711
auto Parser::parse_splicer(SplicerAST*& yyast) -> bool {
@@ -1491,25 +1479,43 @@ auto Parser::parse_nested_expession(ExpressionAST*& yyast,
14911479

14921480
auto Parser::parse_fold_expression(ExpressionAST*& yyast,
14931481
const ExprContext& ctx) -> bool {
1482+
if (!lookat(TokenKind::T_LPAREN)) return false;
1483+
14941484
if (parse_left_fold_expression(yyast, ctx)) return true;
14951485

14961486
SourceLocation lparenLoc;
14971487
ExpressionAST* expression = nullptr;
14981488
SourceLocation opLoc;
14991489
TokenKind op = TokenKind::T_EOF_SYMBOL;
15001490
SourceLocation ellipsisLoc;
1491+
bool isNestedExpression = false;
15011492

1502-
auto lookat_fold_expression = [&] {
1493+
auto lookat_fold_or_nested_expression = [&] {
15031494
LookaheadParser lookahead{this};
15041495
if (!match(TokenKind::T_LPAREN, lparenLoc)) return false;
15051496
if (!parse_cast_expression(expression, ctx)) return false;
1497+
if (lookat(TokenKind::T_RPAREN)) {
1498+
isNestedExpression = true;
1499+
lookahead.commit();
1500+
return true;
1501+
}
15061502
if (!parse_fold_operator(opLoc, op)) return false;
15071503
if (!match(TokenKind::T_DOT_DOT_DOT, ellipsisLoc)) return false;
15081504
lookahead.commit();
15091505
return true;
15101506
};
15111507

1512-
if (!lookat_fold_expression()) return false;
1508+
if (!lookat_fold_or_nested_expression()) return false;
1509+
1510+
if (isNestedExpression) {
1511+
auto ast = make_node<NestedExpressionAST>(pool_);
1512+
yyast = ast;
1513+
ast->lparenLoc = lparenLoc;
1514+
ast->expression = expression;
1515+
expect(TokenKind::T_RPAREN, ast->rparenLoc);
1516+
check(ast);
1517+
return true;
1518+
}
15131519

15141520
if (SourceLocation rparenLoc; match(TokenKind::T_RPAREN, rparenLoc)) {
15151521
auto ast = make_node<RightFoldExpressionAST>(pool_);

0 commit comments

Comments
 (0)