Sfoglia il codice sorgente

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.
Linus Groh 5 anni fa
parent
commit
624eaa32af
2 ha cambiato i file con 14 aggiunte e 18 eliminazioni
  1. 13 18
      Libraries/LibJS/Parser.cpp
  2. 1 0
      Libraries/LibJS/Parser.h

+ 13 - 18
Libraries/LibJS/Parser.cpp

@@ -259,7 +259,6 @@ NonnullRefPtr<Statement> Parser::parse_statement()
             consume_or_insert_semicolon();
             return create_ast_node<ExpressionStatement>(move(expr));
         }
-        m_parser_state.m_has_errors = true;
         expected("statement (missing switch case)");
         consume();
         return create_ast_node<ErrorStatement>();
@@ -390,7 +389,6 @@ NonnullRefPtr<Expression> 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<ErrorExpression>();
@@ -430,7 +428,6 @@ NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression()
         consume();
         return create_ast_node<UnaryExpression>(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<ErrorExpression>();
@@ -468,12 +465,7 @@ NonnullRefPtr<ObjectExpression> 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<Expression> Parser::parse_secondary_expression(NonnullRefPtr<Expre
     case TokenType::QuestionMark:
         return parse_conditional_expression(move(lhs));
     default:
-        m_parser_state.m_has_errors = true;
         expected("secondary expression (missing switch case)");
         consume();
         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
     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<ThrowStatement>(create_ast_node<ErrorExpression>());
     }
 
@@ -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();
 }
+
 }

+ 1 - 0
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();