Skip to content

Commit

Permalink
Fix a parsing bug in nullish-coalescing
Browse files Browse the repository at this point in the history
Signed-off-by: HyukWoo Park <[email protected]>
  • Loading branch information
clover2123 committed Nov 7, 2024
1 parent 92602e2 commit e9611db
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
26 changes: 23 additions & 3 deletions src/parser/esprima_cpp/esprima.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2964,10 +2964,19 @@ class Parser {

ASTNode expr = this->inheritCoverGrammar(builder, &Parser::parseExponentiationExpression<ASTBuilder>);

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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion test/vendortest

0 comments on commit e9611db

Please sign in to comment.