diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index 2288a31d92..22f10bbfa0 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -259,7 +259,6 @@ NonnullRefPtr Parser::parse_statement() consume_or_insert_semicolon(); return create_ast_node(move(expr)); } - m_parser_state.m_has_errors = true; expected("statement (missing switch case)"); consume(); return create_ast_node(); @@ -390,7 +389,6 @@ NonnullRefPtr Parser::parse_primary_expression() case TokenType::New: return parse_new_expression(); default: - m_parser_state.m_has_errors = true; expected("primary expression (missing switch case)"); consume(); return create_ast_node(); @@ -430,7 +428,6 @@ NonnullRefPtr Parser::parse_unary_prefixed_expression() consume(); return create_ast_node(UnaryOp::Delete, parse_expression(precedence, associativity)); default: - m_parser_state.m_has_errors = true; expected("primary expression (missing switch case)"); consume(); return create_ast_node(); @@ -468,12 +465,7 @@ NonnullRefPtr Parser::parse_object_expression() need_colon = false; is_spread = true; } else { - m_parser_state.m_has_errors = true; - auto& current_token = m_parser_state.m_current_token; - fprintf(stderr, "Syntax Error: Unexpected token %s as member in object initialization. Expected a numeric literal, string literal or identifier (line: %zu, column: %zu))\n", - current_token.name(), - current_token.line_number(), - current_token.line_column()); + syntax_error(String::format("Unexpected token %s as member in object initialization. Expected a numeric literal, string literal or identifier", m_parser_state.m_current_token.name())); consume(); continue; } @@ -662,7 +654,6 @@ NonnullRefPtr Parser::parse_secondary_expression(NonnullRefPtr(); @@ -829,8 +820,7 @@ NonnullRefPtr Parser::parse_throw_statement() // Automatic semicolon insertion: terminate statement when throw is followed by newline if (m_parser_state.m_current_token.trivia().contains('\n')) { - m_parser_state.m_has_errors = true; - fprintf(stderr, "Syntax Error: no line break is allowed between 'throw' and its expression\n"); + syntax_error("No line break is allowed between 'throw' and its expression"); return create_ast_node(create_ast_node()); } @@ -1197,14 +1187,18 @@ Token Parser::consume(TokenType expected_type) } void Parser::expected(const char* what) +{ + syntax_error(String::format("Unexpected token %s. Expected %s", m_parser_state.m_current_token.name(), what)); +} + +void Parser::syntax_error(const String& message, size_t line, size_t column) { m_parser_state.m_has_errors = true; - auto& current_token = m_parser_state.m_current_token; - fprintf(stderr, "Syntax Error: Unexpected token %s. Expected %s (line: %zu, column: %zu)\n", - current_token.name(), - what, - current_token.line_number(), - current_token.line_column()); + if (line == 0 || column == 0) { + line = m_parser_state.m_current_token.line_number(); + column = m_parser_state.m_current_token.line_column(); + } + fprintf(stderr, "Syntax Error: %s (line: %zu, column: %zu)\n", message.characters(), line, column); } void Parser::save_state() @@ -1218,4 +1212,5 @@ void Parser::load_state() m_parser_state = m_saved_state.value(); m_saved_state.clear(); } + } diff --git a/Libraries/LibJS/Parser.h b/Libraries/LibJS/Parser.h index 297c36efe6..e6df36e390 100644 --- a/Libraries/LibJS/Parser.h +++ b/Libraries/LibJS/Parser.h @@ -89,6 +89,7 @@ private: bool match(TokenType type) const; bool done() const; void expected(const char* what); + void syntax_error(const String& message, size_t line = 0, size_t column = 0); Token consume(); Token consume(TokenType type); void consume_or_insert_semicolon();