From 19882c94abb5e5d7fc73627565c1d9c70ab4a83b Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Thu, 4 Aug 2022 15:18:37 +0800 Subject: [PATCH] Fix syntax error of break&continue statement issue: I5IZ26 Signed-off-by: zhangrengao Change-Id: I352ec93e8fafd33fa28e3c5941bf6016dec2273b --- es2panda/compiler/core/dynamicContext.cpp | 2 +- es2panda/parser/context/parserContext.h | 1 + es2panda/parser/parserImpl.h | 2 ++ es2panda/parser/statementParser.cpp | 35 +++++++++++++++++++++-- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/es2panda/compiler/core/dynamicContext.cpp b/es2panda/compiler/core/dynamicContext.cpp index 73e9e9ddcb..f4402d572d 100644 --- a/es2panda/compiler/core/dynamicContext.cpp +++ b/es2panda/compiler/core/dynamicContext.cpp @@ -36,7 +36,7 @@ DynamicContext::~DynamicContext() LabelContext::LabelContext(PandaGen *pg, const ir::LabelledStatement *labelledStmt) : DynamicContext(pg, LabelTarget(labelledStmt->Ident()->Name())), labelledStmt_(labelledStmt) { - if (!labelledStmt->Body()->IsBlockStatement()) { + if (!labelledStmt->Body()->IsBlockStatement() && !labelledStmt->Body()->IsIfStatement()) { return; } diff --git a/es2panda/parser/context/parserContext.h b/es2panda/parser/context/parserContext.h index 757a3d5be8..95d9743ee5 100644 --- a/es2panda/parser/context/parserContext.h +++ b/es2panda/parser/context/parserContext.h @@ -59,6 +59,7 @@ enum class ParserStatus { IN_AMBIENT_CONTEXT = (1 << 24), IN_CLASS_BODY = (1 << 25), IN_DECORATOR = (1 << 26), + DISALLOW_CONTINUE = (1 << 27), }; DEFINE_BITOPS(ParserStatus) diff --git a/es2panda/parser/parserImpl.h b/es2panda/parser/parserImpl.h index e73468a664..9a4d37a1e9 100644 --- a/es2panda/parser/parserImpl.h +++ b/es2panda/parser/parserImpl.h @@ -392,6 +392,8 @@ private: void CheckLabelledFunction(const ir::Statement *node); void CheckDeclare(); + bool IsLabelFollowedByIterationStatement(); + bool ParseDirective(ArenaVector *statements); void ParseDirectivePrologue(ArenaVector *statements); ArenaVector ParseStatementList(StatementParsingFlags flags = StatementParsingFlags::ALLOW_LEXICAL); diff --git a/es2panda/parser/statementParser.cpp b/es2panda/parser/statementParser.cpp index c1e63e01d4..7a0df02cc9 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -116,6 +116,27 @@ void ParserImpl::CheckDeclare() } } +bool ParserImpl::IsLabelFollowedByIterationStatement() +{ + lexer_->NextToken(); + + switch (lexer_->GetToken().Type()) { + case lexer::TokenType::KEYW_DO: + case lexer::TokenType::KEYW_FOR: + case lexer::TokenType::KEYW_WHILE: { + return true; + } + case lexer::TokenType::LITERAL_IDENT: { + if (lexer_->Lookahead() == LEX_CHAR_COLON) { + lexer_->NextToken(); + return IsLabelFollowedByIterationStatement(); + } + } + default: + return false; + } + return false; +} ir::Statement *ParserImpl::ParseStatement(StatementParsingFlags flags) { bool isDeclare = false; @@ -877,7 +898,8 @@ ir::ContinueStatement *ParserImpl::ParseContinueStatement() const auto &label = lexer_->GetToken().Ident(); const ParserContext *labelCtx = context_.FindLabel(label); - if (!labelCtx || !(labelCtx->Status() & ParserStatus::IN_ITERATION)) { + if (!labelCtx || !(labelCtx->Status() & ParserStatus::IN_ITERATION) || + (labelCtx->Status() & ParserStatus::DISALLOW_CONTINUE)) { ThrowSyntaxError("Undefined label"); } @@ -1345,6 +1367,10 @@ ir::IfStatement *ParserImpl::ParseIfStatement() ir::LabelledStatement *ParserImpl::ParseLabelledStatement(const lexer::LexerPosition &pos) { + const auto savedPos = lexer_->Save(); + bool isLabelFollowedByIterationStatement = IsLabelFollowedByIterationStatement(); + lexer_->Rewind(savedPos); + const util::StringView &actualLabel = pos.token.Ident(); // TODO(frobert) : check correctness @@ -1356,7 +1382,12 @@ ir::LabelledStatement *ParserImpl::ParseLabelledStatement(const lexer::LexerPosi ThrowSyntaxError("Label already declared", pos.token.Start()); } - SavedParserContext newCtx(this, ParserStatus::IN_LABELED, actualLabel); + SavedParserContext newCtx(this, ParserStatus::IN_LABELED | context_.Status(), actualLabel); + if (isLabelFollowedByIterationStatement) { + context_.Status() &= ~ParserStatus::DISALLOW_CONTINUE; + } else { + context_.Status() |= ParserStatus::DISALLOW_CONTINUE; + } auto *identNode = AllocNode(actualLabel, Allocator()); identNode->SetRange(pos.token.Loc()); -- Gitee