From 14de45296eb93a42282782769b03e2e42739a2aa Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 28 Mar 2020 11:48:52 +0100 Subject: LibJS: Fix broken parsing of `!o.a` Unary expressions parsing now respects precedence and associativity of operators. This patch also makes `typeof` left-associative which was an oversight. Thanks to Conrad for helping me work this out. :^) --- Libraries/LibJS/Parser.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'Libraries/LibJS/Parser.cpp') diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index ef0791622b..c4f2a3966f 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -150,6 +150,7 @@ Associativity Parser::operator_associativity(TokenType type) const case TokenType::ExclamationMarkEquals: case TokenType::EqualsEqualsEquals: case TokenType::ExclamationMarkEqualsEquals: + case TokenType::Typeof: case TokenType::Ampersand: case TokenType::Caret: case TokenType::Pipe: @@ -256,22 +257,24 @@ NonnullRefPtr Parser::parse_primary_expression() NonnullRefPtr Parser::parse_unary_prefixed_expression() { + auto precedence = operator_precedence(m_current_token.type()); + auto associativity = operator_associativity(m_current_token.type()); switch (m_current_token.type()) { case TokenType::PlusPlus: consume(); - return create_ast_node(UpdateOp::Increment, parse_primary_expression(), true); + return create_ast_node(UpdateOp::Increment, parse_expression(precedence, associativity), true); case TokenType::MinusMinus: consume(); - return create_ast_node(UpdateOp::Decrement, parse_primary_expression(), true); + return create_ast_node(UpdateOp::Decrement, parse_expression(precedence, associativity), true); case TokenType::ExclamationMark: consume(); - return create_ast_node(UnaryOp::Not, parse_primary_expression()); + return create_ast_node(UnaryOp::Not, parse_expression(precedence, associativity)); case TokenType::Tilde: consume(); - return create_ast_node(UnaryOp::BitwiseNot, parse_primary_expression()); + return create_ast_node(UnaryOp::BitwiseNot, parse_expression(precedence, associativity)); case TokenType::Typeof: consume(); - return create_ast_node(UnaryOp::Typeof, parse_primary_expression()); + return create_ast_node(UnaryOp::Typeof, parse_expression(precedence, associativity)); default: m_has_errors = true; expected("primary expression (missing switch case)"); -- cgit v1.2.3