diff --git a/Libraries/LibGUI/CppLexer.cpp b/Libraries/LibGUI/CppLexer.cpp index bbd76a45de..78a7558779 100644 --- a/Libraries/LibGUI/CppLexer.cpp +++ b/Libraries/LibGUI/CppLexer.cpp @@ -243,6 +243,61 @@ Vector CppLexer::lex() tokens.append(token); }; + auto match_escape_sequence = [&]() -> size_t { + switch (peek(1)) { + case '\'': + case '"': + case '?': + case '\\': + case 'a': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + case 'v': + return 2; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': { + size_t octal_digits = 1; + for (size_t i = 0; i < 2; ++i) { + char next = peek(2 + i); + if (next < '0' || next > '7') + break; + ++octal_digits; + } + return 1 + octal_digits; + } + case 'x': { + size_t hex_digits = 0; + for (size_t i = 0; i < 2; ++i) { + if (!isxdigit(peek(2 + i))) + break; + ++hex_digits; + } + return 2 + hex_digits; + } + case 'u': { + bool is_unicode = true; + for (size_t i = 0; i < 4; ++i) { + if (!isxdigit(peek(2 + i))) { + is_unicode = false; + break; + } + } + return is_unicode ? 6 : 0; + } + default: + return 0; + } + }; + while (m_index < m_input.length()) { auto ch = peek(); if (isspace(ch)) { @@ -328,6 +383,19 @@ Vector CppLexer::lex() begin_token(); consume(); while (peek()) { + if (peek() == '\\') { + size_t escape = match_escape_sequence(); + if (escape > 0) { + commit_token(CppToken::Type::DoubleQuotedString); + begin_token(); + for (size_t i = 0; i < escape; ++i) + consume(); + commit_token(CppToken::Type::EscapeSequence); + begin_token(); + continue; + } + } + if (consume() == '"') break; } @@ -338,6 +406,19 @@ Vector CppLexer::lex() begin_token(); consume(); while (peek()) { + if (peek() == '\\') { + size_t escape = match_escape_sequence(); + if (escape > 0) { + commit_token(CppToken::Type::SingleQuotedString); + begin_token(); + for (size_t i = 0; i < escape; ++i) + consume(); + commit_token(CppToken::Type::EscapeSequence); + begin_token(); + continue; + } + } + if (consume() == '\'') break; } diff --git a/Libraries/LibGUI/CppLexer.h b/Libraries/LibGUI/CppLexer.h index 09e8ed8087..63583cd4a1 100644 --- a/Libraries/LibGUI/CppLexer.h +++ b/Libraries/LibGUI/CppLexer.h @@ -46,6 +46,7 @@ namespace GUI { __TOKEN(Semicolon) \ __TOKEN(DoubleQuotedString) \ __TOKEN(SingleQuotedString) \ + __TOKEN(EscapeSequence) \ __TOKEN(Comment) \ __TOKEN(Number) \ __TOKEN(Keyword) \ diff --git a/Libraries/LibGUI/CppSyntaxHighlighter.cpp b/Libraries/LibGUI/CppSyntaxHighlighter.cpp index 3f1d5c4340..abb11248a4 100644 --- a/Libraries/LibGUI/CppSyntaxHighlighter.cpp +++ b/Libraries/LibGUI/CppSyntaxHighlighter.cpp @@ -23,6 +23,8 @@ static TextStyle style_for_token_type(CppToken::Type type) case CppToken::Type::SingleQuotedString: case CppToken::Type::Number: return { Color::from_rgb(0x800000) }; + case CppToken::Type::EscapeSequence: + return { Color::from_rgb(0x800080), &Gfx::Font::default_bold_fixed_width_font() }; case CppToken::Type::PreprocessorStatement: return { Color::from_rgb(0x008080) }; case CppToken::Type::Comment: