Skip to content

Commit

Permalink
Fix parsing bugs in UnaryExpression and Exponentiation operation
Browse files Browse the repository at this point in the history
Signed-off-by: HyukWoo Park <[email protected]>
  • Loading branch information
clover2123 authored and ksh8281 committed Dec 15, 2023
1 parent 4121b29 commit 9bc0956
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 69 deletions.
115 changes: 47 additions & 68 deletions src/parser/esprima_cpp/esprima.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2829,46 +2829,35 @@ class Parser {
template <class ASTBuilder>
ASTNode parseUnaryExpression(ASTBuilder& builder)
{
ASTNode exprNode = nullptr;
if (this->lookahead.type == Token::PunctuatorToken) {
auto punctuatorsKind = this->lookahead.valuePunctuatorKind;
ASTNode exprNode = nullptr;

if (punctuatorsKind == Plus) {
if (punctuatorsKind == Plus || punctuatorsKind == Minus || punctuatorsKind == Wave || punctuatorsKind == ExclamationMark) {
this->nextToken();
MetaNode node = this->startNode(&this->lookahead);
ASTNode subExpr = this->inheritCoverGrammar(builder, &Parser::parseUnaryExpression<ASTBuilder>);
exprNode = this->finalize(node, builder.createUnaryExpressionPlusNode(subExpr));
this->context->isAssignmentTarget = false;
this->context->isBindingElement = false;
return exprNode;
} else if (punctuatorsKind == Minus) {
this->nextToken();
if (this->lookahead.type == Token::NumericLiteralToken) {
return parseNumericLiteralNode(builder, true);
} else {
MetaNode node = this->startNode(&this->lookahead);
ASTNode subExpr = this->inheritCoverGrammar(builder, &Parser::parseUnaryExpression<ASTBuilder>);
exprNode = this->finalize(node, builder.createUnaryExpressionMinusNode(subExpr));
this->context->isAssignmentTarget = false;
this->context->isBindingElement = false;

switch (punctuatorsKind) {
case Plus: {
return this->finalize(node, builder.createUnaryExpressionPlusNode(subExpr));
}
case Minus: {
return this->finalize(node, builder.createUnaryExpressionMinusNode(subExpr));
}
case Wave: {
return this->finalize(node, builder.createUnaryExpressionBitwiseNotNode(subExpr));
}
case ExclamationMark: {
return this->finalize(node, builder.createUnaryExpressionLogicalNotNode(subExpr));
}
default: {
RELEASE_ASSERT_NOT_REACHED();
return exprNode;
}
} else if (punctuatorsKind == Wave) {
this->nextToken();
MetaNode node = this->startNode(&this->lookahead);
ASTNode subExpr = this->inheritCoverGrammar(builder, &Parser::parseUnaryExpression<ASTBuilder>);
exprNode = this->finalize(node, builder.createUnaryExpressionBitwiseNotNode(subExpr));
this->context->isAssignmentTarget = false;
this->context->isBindingElement = false;
return exprNode;
} else if (punctuatorsKind == ExclamationMark) {
this->nextToken();
MetaNode node = this->startNode(&this->lookahead);
ASTNode subExpr = this->inheritCoverGrammar(builder, &Parser::parseUnaryExpression<ASTBuilder>);
exprNode = this->finalize(node, builder.createUnaryExpressionLogicalNotNode(subExpr));
this->context->isAssignmentTarget = false;
this->context->isBindingElement = false;
return exprNode;
}
} else if (punctuatorsKind == Hash) {
ALLOC_TOKEN(hashToken);
this->nextToken(hashToken);
Expand Down Expand Up @@ -2897,47 +2886,39 @@ class Parser {
this->throwUnexpectedToken(*hashToken);
}
} else if (this->lookahead.type == Token::KeywordToken) {
ASTNode exprNode = nullptr;

if (this->lookahead.valueKeywordKind == DeleteKeyword) {
this->nextToken();
MetaNode node = this->startNode(&this->lookahead);
ASTNode subExpr = this->inheritCoverGrammar(builder, &Parser::parseUnaryExpression<ASTBuilder>);

if (this->context->strict && subExpr->isIdentifier()) {
this->throwError(Messages::StrictDelete);
}
auto valueKeywordKind = this->lookahead.valueKeywordKind;

if (subExpr->type() == ASTNodeType::MemberExpression) {
if (subExpr->asMemberExpression()->isReferencePrivateField()) {
this->throwError(Messages::CannnotUsePrivateFieldHere);
}
}

exprNode = this->finalize(node, builder.createUnaryExpressionDeleteNode(subExpr));
this->context->isAssignmentTarget = false;
this->context->isBindingElement = false;

return exprNode;
} else if (this->lookahead.valueKeywordKind == VoidKeyword) {
if (valueKeywordKind == DeleteKeyword || valueKeywordKind == VoidKeyword || valueKeywordKind == TypeofKeyword) {
this->nextToken();
MetaNode node = this->startNode(&this->lookahead);
ASTNode subExpr = this->inheritCoverGrammar(builder, &Parser::parseUnaryExpression<ASTBuilder>);
exprNode = this->finalize(node, builder.createUnaryExpressionVoidNode(subExpr));
this->context->isAssignmentTarget = false;
this->context->isBindingElement = false;

return exprNode;
} else if (this->lookahead.valueKeywordKind == TypeofKeyword) {
this->nextToken();

MetaNode node = this->startNode(&this->lookahead);
ASTNode subExpr = this->inheritCoverGrammar(builder, &Parser::parseUnaryExpression<ASTBuilder>);
exprNode = this->finalize(node, builder.createUnaryExpressionTypeOfNode(subExpr));
this->context->isAssignmentTarget = false;
this->context->isBindingElement = false;
switch (valueKeywordKind) {
case DeleteKeyword: {
if (this->context->strict && subExpr->isIdentifier()) {
this->throwError(Messages::StrictDelete);
}

return exprNode;
if (subExpr->type() == ASTNodeType::MemberExpression) {
if (subExpr->asMemberExpression()->isReferencePrivateField()) {
this->throwError(Messages::CannnotUsePrivateFieldHere);
}
}
return this->finalize(node, builder.createUnaryExpressionDeleteNode(subExpr));
}
case VoidKeyword: {
return this->finalize(node, builder.createUnaryExpressionVoidNode(subExpr));
}
case TypeofKeyword: {
return this->finalize(node, builder.createUnaryExpressionTypeOfNode(subExpr));
}
default: {
RELEASE_ASSERT_NOT_REACHED();
return exprNode;
}
}
}
} else if (this->matchContextualKeyword(AwaitKeyword)) {
bool parseAwait = false;
Expand All @@ -2961,8 +2942,7 @@ class Parser {
}
}
if (parseAwait) {
ASTNode exprNode = this->parseAwaitExpression(builder);
return exprNode;
return this->parseAwaitExpression(builder);
}
}

Expand All @@ -2974,11 +2954,10 @@ class Parser {
{
ALLOC_TOKEN(startToken);
*startToken = this->lookahead;
bool seenMinus = this->match(Minus);
ASTNode expr = this->inheritCoverGrammar(builder, &Parser::parseUnaryExpression<ASTBuilder>);

if (!expr->isUnaryOperation() && this->match(Exponentiation)) {
if (UNLIKELY(seenMinus)) {
if (this->match(Exponentiation)) {
if (expr->isUnaryOperation() && (startToken->type != Token::PunctuatorToken || startToken->valuePunctuatorKind != PunctuatorKind::LeftParenthesis)) {
this->throwError("Unary operator used immediately before exponentiation expression. Parenthesis must be used to disambiguate operator precedence");
}
this->nextToken();
Expand Down
2 changes: 1 addition & 1 deletion test/vendortest

0 comments on commit 9bc0956

Please sign in to comment.