mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 15:05:08 +00:00
LibJS: Add Parser::syntax_error() helper
Instead of having fprintf()s all over the place we can now use syntax_error("message") or syntax_error("message", line, column). This takes care of a consistent format, appending a newline and getting the line number and column of the current token if the last two params are omitted.
This commit is contained in:
parent
85fd0d2187
commit
624eaa32af
2 changed files with 14 additions and 18 deletions
|
@ -259,7 +259,6 @@ NonnullRefPtr<Statement> Parser::parse_statement()
|
||||||
consume_or_insert_semicolon();
|
consume_or_insert_semicolon();
|
||||||
return create_ast_node<ExpressionStatement>(move(expr));
|
return create_ast_node<ExpressionStatement>(move(expr));
|
||||||
}
|
}
|
||||||
m_parser_state.m_has_errors = true;
|
|
||||||
expected("statement (missing switch case)");
|
expected("statement (missing switch case)");
|
||||||
consume();
|
consume();
|
||||||
return create_ast_node<ErrorStatement>();
|
return create_ast_node<ErrorStatement>();
|
||||||
|
@ -390,7 +389,6 @@ NonnullRefPtr<Expression> Parser::parse_primary_expression()
|
||||||
case TokenType::New:
|
case TokenType::New:
|
||||||
return parse_new_expression();
|
return parse_new_expression();
|
||||||
default:
|
default:
|
||||||
m_parser_state.m_has_errors = true;
|
|
||||||
expected("primary expression (missing switch case)");
|
expected("primary expression (missing switch case)");
|
||||||
consume();
|
consume();
|
||||||
return create_ast_node<ErrorExpression>();
|
return create_ast_node<ErrorExpression>();
|
||||||
|
@ -430,7 +428,6 @@ NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression()
|
||||||
consume();
|
consume();
|
||||||
return create_ast_node<UnaryExpression>(UnaryOp::Delete, parse_expression(precedence, associativity));
|
return create_ast_node<UnaryExpression>(UnaryOp::Delete, parse_expression(precedence, associativity));
|
||||||
default:
|
default:
|
||||||
m_parser_state.m_has_errors = true;
|
|
||||||
expected("primary expression (missing switch case)");
|
expected("primary expression (missing switch case)");
|
||||||
consume();
|
consume();
|
||||||
return create_ast_node<ErrorExpression>();
|
return create_ast_node<ErrorExpression>();
|
||||||
|
@ -468,12 +465,7 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
||||||
need_colon = false;
|
need_colon = false;
|
||||||
is_spread = true;
|
is_spread = true;
|
||||||
} else {
|
} else {
|
||||||
m_parser_state.m_has_errors = true;
|
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()));
|
||||||
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());
|
|
||||||
consume();
|
consume();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -662,7 +654,6 @@ NonnullRefPtr<Expression> Parser::parse_secondary_expression(NonnullRefPtr<Expre
|
||||||
case TokenType::QuestionMark:
|
case TokenType::QuestionMark:
|
||||||
return parse_conditional_expression(move(lhs));
|
return parse_conditional_expression(move(lhs));
|
||||||
default:
|
default:
|
||||||
m_parser_state.m_has_errors = true;
|
|
||||||
expected("secondary expression (missing switch case)");
|
expected("secondary expression (missing switch case)");
|
||||||
consume();
|
consume();
|
||||||
return create_ast_node<ErrorExpression>();
|
return create_ast_node<ErrorExpression>();
|
||||||
|
@ -829,8 +820,7 @@ NonnullRefPtr<ThrowStatement> Parser::parse_throw_statement()
|
||||||
|
|
||||||
// Automatic semicolon insertion: terminate statement when throw is followed by newline
|
// Automatic semicolon insertion: terminate statement when throw is followed by newline
|
||||||
if (m_parser_state.m_current_token.trivia().contains('\n')) {
|
if (m_parser_state.m_current_token.trivia().contains('\n')) {
|
||||||
m_parser_state.m_has_errors = true;
|
syntax_error("No line break is allowed between 'throw' and its expression");
|
||||||
fprintf(stderr, "Syntax Error: no line break is allowed between 'throw' and its expression\n");
|
|
||||||
return create_ast_node<ThrowStatement>(create_ast_node<ErrorExpression>());
|
return create_ast_node<ThrowStatement>(create_ast_node<ErrorExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1197,14 +1187,18 @@ Token Parser::consume(TokenType expected_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::expected(const char* what)
|
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;
|
m_parser_state.m_has_errors = true;
|
||||||
auto& current_token = m_parser_state.m_current_token;
|
if (line == 0 || column == 0) {
|
||||||
fprintf(stderr, "Syntax Error: Unexpected token %s. Expected %s (line: %zu, column: %zu)\n",
|
line = m_parser_state.m_current_token.line_number();
|
||||||
current_token.name(),
|
column = m_parser_state.m_current_token.line_column();
|
||||||
what,
|
}
|
||||||
current_token.line_number(),
|
fprintf(stderr, "Syntax Error: %s (line: %zu, column: %zu)\n", message.characters(), line, column);
|
||||||
current_token.line_column());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::save_state()
|
void Parser::save_state()
|
||||||
|
@ -1218,4 +1212,5 @@ void Parser::load_state()
|
||||||
m_parser_state = m_saved_state.value();
|
m_parser_state = m_saved_state.value();
|
||||||
m_saved_state.clear();
|
m_saved_state.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,7 @@ private:
|
||||||
bool match(TokenType type) const;
|
bool match(TokenType type) const;
|
||||||
bool done() const;
|
bool done() const;
|
||||||
void expected(const char* what);
|
void expected(const char* what);
|
||||||
|
void syntax_error(const String& message, size_t line = 0, size_t column = 0);
|
||||||
Token consume();
|
Token consume();
|
||||||
Token consume(TokenType type);
|
Token consume(TokenType type);
|
||||||
void consume_or_insert_semicolon();
|
void consume_or_insert_semicolon();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue