Skip to content

Commit 110e0b5

Browse files
committed
Reduce backtracking while parsing for statements
Signed-off-by: Roberto Raggi <[email protected]>
1 parent 043ceb2 commit 110e0b5

File tree

2 files changed

+26
-36
lines changed

2 files changed

+26
-36
lines changed

src/parser/cxx/parser.cc

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4180,73 +4180,64 @@ auto Parser::parse_do_statement(StatementAST*& yyast) -> bool {
41804180
return true;
41814181
}
41824182

4183-
auto Parser::parse_for_range_statement(StatementAST*& yyast) -> bool {
4184-
LookaheadParser lookahead{this};
4185-
4183+
auto Parser::parse_for_statement(StatementAST*& yyast) -> bool {
41864184
SourceLocation forLoc;
41874185
if (!match(TokenKind::T_FOR, forLoc)) return false;
41884186

41894187
ScopeGuard scopeGuard{this};
41904188

41914189
auto parentScope = scope_;
41924190
auto blockSymbol = control_->newBlockSymbol(scope_, forLoc);
4191+
parentScope->addSymbol(blockSymbol);
4192+
41934193
setScope(blockSymbol);
41944194

41954195
SourceLocation lparenLoc;
4196-
if (!match(TokenKind::T_LPAREN, lparenLoc)) return false;
4196+
expect(TokenKind::T_LPAREN, lparenLoc);
41974197

41984198
StatementAST* initializer = nullptr;
41994199
parse_init_statement(initializer);
42004200

42014201
DeclarationAST* rangeDeclaration = nullptr;
4202-
if (!parse_for_range_declaration(rangeDeclaration)) return false;
4203-
42044202
SourceLocation colonLoc;
4205-
if (!match(TokenKind::T_COLON, colonLoc)) return false;
42064203

4207-
lookahead.commit();
4208-
4209-
parentScope->addSymbol(blockSymbol);
4204+
auto lookat_for_range_declaration = [&] {
4205+
LookaheadParser lookahead{this};
42104206

4211-
auto ast = make_node<ForRangeStatementAST>(pool_);
4212-
yyast = ast;
4207+
if (!parse_for_range_declaration(rangeDeclaration)) return false;
42134208

4214-
ast->forLoc = forLoc;
4215-
ast->rangeDeclaration = rangeDeclaration;
4216-
ast->lparenLoc = lparenLoc;
4217-
ast->initializer = initializer;
4218-
ast->colonLoc = colonLoc;
4219-
4220-
parse_for_range_initializer(ast->rangeInitializer);
4209+
if (!match(TokenKind::T_COLON, colonLoc)) return false;
42214210

4222-
expect(TokenKind::T_RPAREN, ast->rparenLoc);
4211+
lookahead.commit();
42234212

4224-
parse_statement(ast->statement);
4213+
return true;
4214+
};
42254215

4226-
return true;
4227-
}
4216+
if (lookat_for_range_declaration()) {
4217+
auto ast = make_node<ForRangeStatementAST>(pool_);
4218+
yyast = ast;
42284219

4229-
auto Parser::parse_for_statement(StatementAST*& yyast) -> bool {
4230-
if (parse_for_range_statement(yyast)) return true;
4220+
ast->forLoc = forLoc;
4221+
ast->rangeDeclaration = rangeDeclaration;
4222+
ast->lparenLoc = lparenLoc;
4223+
ast->initializer = initializer;
4224+
ast->colonLoc = colonLoc;
42314225

4232-
SourceLocation forLoc;
4226+
parse_for_range_initializer(ast->rangeInitializer);
42334227

4234-
if (!match(TokenKind::T_FOR, forLoc)) return false;
4228+
expect(TokenKind::T_RPAREN, ast->rparenLoc);
42354229

4236-
ScopeGuard scopeGuard{this};
4230+
parse_statement(ast->statement);
42374231

4238-
auto blockSymbol = control_->newBlockSymbol(scope_, forLoc);
4239-
scope_->addSymbol(blockSymbol);
4240-
setScope(blockSymbol);
4232+
return true;
4233+
}
42414234

42424235
auto ast = make_node<ForStatementAST>(pool_);
42434236
yyast = ast;
42444237

42454238
ast->forLoc = forLoc;
4246-
4247-
expect(TokenKind::T_LPAREN, ast->lparenLoc);
4248-
4249-
parse_init_statement(ast->initializer);
4239+
ast->lparenLoc = lparenLoc;
4240+
ast->initializer = initializer;
42504241

42514242
if (!match(TokenKind::T_SEMICOLON, ast->semicolonLoc)) {
42524243
parse_condition(ast->condition, ExprContext{});

src/parser/cxx/parser.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,6 @@ class Parser final {
342342
[[nodiscard]] auto parse_switch_statement(StatementAST*& yyast) -> bool;
343343
[[nodiscard]] auto parse_while_statement(StatementAST*& yyast) -> bool;
344344
[[nodiscard]] auto parse_do_statement(StatementAST*& yyast) -> bool;
345-
[[nodiscard]] auto parse_for_range_statement(StatementAST*& yyast) -> bool;
346345
[[nodiscard]] auto parse_for_statement(StatementAST*& yyast) -> bool;
347346
[[nodiscard]] auto parse_for_range_declaration(DeclarationAST*& yyast)
348347
-> bool;

0 commit comments

Comments
 (0)