From 8280be1c36a5df2ef728a286078de2d69639e971 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 16 Apr 2021 16:21:41 -0700 Subject: [PATCH] Factor statement parsing out of code block parsing. --- parser/parser_impl.cpp | 57 ++++++++++++++++++------------------------ parser/parser_impl.h | 3 +++ 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/parser/parser_impl.cpp b/parser/parser_impl.cpp index c2bd043408ae..f099e98fdd42 100644 --- a/parser/parser_impl.cpp +++ b/parser/parser_impl.cpp @@ -327,40 +327,16 @@ auto ParseTree::Parser::ParseCodeBlock() -> Node { bool has_errors = false; // Loop over all the different possibly nested elements in the code block. - for (;;) { - switch (tokens.GetKind(*position)) { - case TokenKind::VarKeyword(): - ParseVariableDeclaration(); - continue; - - default: - // A statement with no introducer token can only be an expression - // statement. - if (ParseExpressionStatement()) { - continue; - } - - // We detected and diagnosed an error of some kind. We can trivially - // skip to the actual close curly brace from here. - // FIXME: It would be better to skip to the next semicolon, or the next - // token at the start of a line with the same indent as this one. - SkipTo(tokens.GetMatchedClosingToken(open_curly)); - has_errors = true; - // Now fall through to the close curly brace handling code. - LLVM_FALLTHROUGH; - - case TokenKind::CloseCurlyBrace(): - break; - - case TokenKind::OpenCurlyBrace(): - // FIXME: We should consider avoiding recursion here with some side - // stack. - ParseCodeBlock(); - continue; + while (tokens.GetKind(*position) != TokenKind::CloseCurlyBrace()) { + if (!ParseStatement()) { + // We detected and diagnosed an error of some kind. We can trivially skip + // to the actual close curly brace from here. + // FIXME: It would be better to skip to the next semicolon, or the next + // token at the start of a line with the same indent as this one. + SkipTo(tokens.GetMatchedClosingToken(open_curly)); + has_errors = true; + break; } - - // We only continue looping with `continue` above. - break; } // We always reach here having set our position in the token stream to the @@ -736,4 +712,19 @@ auto ParseTree::Parser::ParseExpressionStatement() -> llvm::Optional { return llvm::None; } +auto ParseTree::Parser::ParseStatement() -> llvm::Optional { + switch (tokens.GetKind(*position)) { + case TokenKind::VarKeyword(): + return ParseVariableDeclaration(); + + case TokenKind::OpenCurlyBrace(): + return ParseCodeBlock(); + + default: + // A statement with no introducer token can only be an expression + // statement. + return ParseExpressionStatement(); + } +} + } // namespace Carbon diff --git a/parser/parser_impl.h b/parser/parser_impl.h index 57fd8d3ba588..ea07909e743d 100644 --- a/parser/parser_impl.h +++ b/parser/parser_impl.h @@ -171,6 +171,9 @@ class ParseTree::Parser { // Parses an expression statement: an expression followed by a semicolon. auto ParseExpressionStatement() -> llvm::Optional; + // Parses a statement. + auto ParseStatement() -> llvm::Optional; + ParseTree& tree; TokenizedBuffer& tokens; TokenDiagnosticEmitter& emitter;