From e9611db6e4c81c050cc0df57cf382437b4182a2f Mon Sep 17 00:00:00 2001 From: HyukWoo Park Date: Tue, 5 Nov 2024 21:30:42 +0900 Subject: [PATCH] Fix a parsing bug in nullish-coalescing Signed-off-by: HyukWoo Park --- src/parser/esprima_cpp/esprima.cpp | 26 +++++++++++++++++++++++--- test/vendortest | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/parser/esprima_cpp/esprima.cpp b/src/parser/esprima_cpp/esprima.cpp index e6c910768..5cd999290 100644 --- a/src/parser/esprima_cpp/esprima.cpp +++ b/src/parser/esprima_cpp/esprima.cpp @@ -2964,10 +2964,19 @@ class Parser { ASTNode expr = this->inheritCoverGrammar(builder, &Parser::parseExponentiationExpression); + bool allowAndOr = true; + bool allowNullishCoalescing = true; ALLOC_TOKEN(token); *token = this->lookahead; int prec = this->binaryPrecedence(token); if (prec > 0) { + if (token->type == Token::PunctuatorToken) { + if (token->valuePunctuatorKind == PunctuatorKind::LogicalAnd || token->valuePunctuatorKind == PunctuatorKind::LogicalOr) { + allowNullishCoalescing = false; + } else if (token->valuePunctuatorKind == PunctuatorKind::NullishCoalescing) { + allowAndOr = false; + } + } this->nextToken(); token->prec = prec; @@ -2995,6 +3004,20 @@ class Parser { break; } + if (this->lookahead.type == Token::PunctuatorToken) { + if (!allowAndOr && (this->lookahead.valuePunctuatorKind == PunctuatorKind::LogicalAnd || this->lookahead.valuePunctuatorKind == PunctuatorKind::LogicalOr)) { + this->throwError(Messages::CannotChainLogicalWithNullish); + } else if (!allowNullishCoalescing && (this->lookahead.valuePunctuatorKind == PunctuatorKind::NullishCoalescing)) { + this->throwError(Messages::CannotChainLogicalWithNullish); + } + + if (this->lookahead.valuePunctuatorKind == PunctuatorKind::LogicalAnd || this->lookahead.valuePunctuatorKind == PunctuatorKind::LogicalOr) { + allowNullishCoalescing = false; + } else if (this->lookahead.valuePunctuatorKind == PunctuatorKind::NullishCoalescing) { + allowAndOr = false; + } + } + // Reduce: make a binary expression from the three topmost entries. while ((stack.size() > 1) && (prec <= tokenStack.back().prec)) { right = stack.back(); @@ -3084,9 +3107,6 @@ class Parser { case LogicalAnd: return builder.createBinaryExpressionLogicalAndNode(left, right); case NullishCoalescing: - if (left->isLogicalOperation() || right->isLogicalOperation()) { - this->throwError(Messages::CannotChainLogicalWithNullish); - } return builder.createBinaryExpressionNullishCoalescingNode(left, right); default: RELEASE_ASSERT_NOT_REACHED(); diff --git a/test/vendortest b/test/vendortest index c9f0f43c4..4d76c58d4 160000 --- a/test/vendortest +++ b/test/vendortest @@ -1 +1 @@ -Subproject commit c9f0f43c4c1922bf79fc7b655deb8523f0548a5b +Subproject commit 4d76c58d4881167cdc415e859ad2c1c9e281c0f9