summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2021-02-10 22:15:38 +0200
committerAndreas Kling <kling@serenityos.org>2021-02-13 19:50:09 +0100
commit8ace2cfa1848ad4402b0c8ffa1875d6d9bffec10 (patch)
treee143ccbd7abc8c5acadad70a59f667a2d06ef63b
parent2da5ecba41ca7cc6212cce8e27e082723e6f6782 (diff)
downloadserenity-8ace2cfa1848ad4402b0c8ffa1875d6d9bffec10.zip
LibCpp: Fix lexing & parsing of non-terminated strings
-rw-r--r--Userland/Libraries/LibCpp/Lexer.cpp4
-rw-r--r--Userland/Libraries/LibCpp/Parser.cpp29
-rw-r--r--Userland/Libraries/LibCpp/Parser.h1
3 files changed, 25 insertions, 9 deletions
diff --git a/Userland/Libraries/LibCpp/Lexer.cpp b/Userland/Libraries/LibCpp/Lexer.cpp
index 5273f87dd4..0507f11ec3 100644
--- a/Userland/Libraries/LibCpp/Lexer.cpp
+++ b/Userland/Libraries/LibCpp/Lexer.cpp
@@ -640,6 +640,10 @@ Vector<Token> Lexer::lex()
}
}
+ // If string is not terminated - stop before EOF
+ if (!peek(1))
+ break;
+
if (consume() == '"')
break;
}
diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp
index b62e7183e3..e06a449f27 100644
--- a/Userland/Libraries/LibCpp/Parser.cpp
+++ b/Userland/Libraries/LibCpp/Parser.cpp
@@ -53,7 +53,7 @@ Parser::Parser(const StringView& program)
dbgln("{}", m_program);
dbgln("Tokens:");
for (auto& token : m_tokens) {
- dbgln("{}", token.to_string());
+ dbgln("{} ({}:{}-{}:{})", token.to_string(), token.start().line, token.start().column, token.end().line, token.end().column);
}
#endif
}
@@ -673,9 +673,14 @@ StringView Parser::text_of_token(const Cpp::Token& token) const
StringView Parser::text_of_node(const ASTNode& node) const
{
- if (node.start().line == node.end().line) {
- ASSERT(node.start().column <= node.end().column);
- return m_lines[node.start().line].substring_view(node.start().column, node.end().column - node.start().column + 1);
+ return text_of_range(node.start(), node.end());
+}
+
+StringView Parser::text_of_range(Position start, Position end) const
+{
+ if (start.line == end.line) {
+ ASSERT(start.column <= end.column);
+ return m_lines[start.line].substring_view(start.column, end.column - start.column + 1);
}
auto index_of_position([this](auto position) {
@@ -686,8 +691,8 @@ StringView Parser::text_of_node(const ASTNode& node) const
start_index += position.column;
return start_index;
});
- auto start_index = index_of_position(node.start());
- auto end_index = index_of_position(node.end());
+ auto start_index = index_of_position(start);
+ auto end_index = index_of_position(end);
ASSERT(end_index >= start_index);
return m_program.substring_view(start_index, end_index - start_index);
}
@@ -717,6 +722,7 @@ bool Parser::match_expression()
return token_type == Token::Type::Integer
|| token_type == Token::Type::Float
|| token_type == Token::Type::Identifier
+ || token_type == Token::Type::DoubleQuotedString
|| match_unary_expression();
}
@@ -821,7 +827,6 @@ NonnullRefPtr<StringLiteral> Parser::parse_string_literal(ASTNode& parent)
auto token = peek();
if (token.type() != Token::Type::DoubleQuotedString && token.type() != Token::Type::EscapeSequence) {
ASSERT(start_token_index.has_value());
- // TODO: don't consume
end_token_index = m_state.token_index - 1;
break;
}
@@ -829,13 +834,19 @@ NonnullRefPtr<StringLiteral> Parser::parse_string_literal(ASTNode& parent)
start_token_index = m_state.token_index;
consume();
}
+
+ // String was not terminated
+ if (!end_token_index.has_value()) {
+ end_token_index = m_tokens.size() - 1;
+ }
+
ASSERT(start_token_index.has_value());
ASSERT(end_token_index.has_value());
+
Token start_token = m_tokens[start_token_index.value()];
Token end_token = m_tokens[end_token_index.value()];
- ASSERT(start_token.start().line == end_token.start().line);
- auto text = m_lines[start_token.start().line].substring_view(start_token.start().column, end_token.end().column - start_token.start().column + 1);
+ auto text = text_of_range(start_token.start(), end_token.end());
auto string_literal = create_ast_node<StringLiteral>(parent, start_token.start(), end_token.end());
string_literal->m_value = text;
return string_literal;
diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h
index b55dce0775..5fe0ec6279 100644
--- a/Userland/Libraries/LibCpp/Parser.h
+++ b/Userland/Libraries/LibCpp/Parser.h
@@ -114,6 +114,7 @@ private:
Token peek() const;
Optional<Token> peek(Token::Type) const;
Position position() const;
+ StringView text_of_range(Position start, Position end) const;
void save_state();
void load_state();