From b8495f0953f06caeca9f99f1e6ef157cfe358a89 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Fri, 13 Oct 2017 10:44:24 +0800 Subject: [PATCH] Regex: Rework parsing, treat lookarounds as assertions, and flags separately --- src/regex_impl.cc | 122 ++++++++++++++++++++++++++-------------------- 1 file changed, 69 insertions(+), 53 deletions(-) diff --git a/src/regex_impl.cc b/src/regex_impl.cc index 2a517d01..89f3b5aa 100644 --- a/src/regex_impl.cc +++ b/src/regex_impl.cc @@ -135,6 +135,8 @@ private: AstNodePtr term() { + while (flag()) // read all flags + {} if (auto node = assertion()) return node; if (auto node = atom()) @@ -145,6 +147,34 @@ private: return nullptr; } + bool peek(StringView expected) const + { + auto it = m_pos; + for (Iterator expected_it{expected.begin(), expected}; expected_it != expected.end(); ++expected_it) + { + if (it == m_regex.end() or *it++ != *expected_it) + return false; + } + return true; + } + + bool flag() + { + if (peek("(?i)")) + { + m_ignore_case = true; + m_pos += 4; + return true; + } + if (peek("(?I)")) + { + m_ignore_case = false; + m_pos += 4; + return true; + } + return false; + } + AstNodePtr assertion() { if (at_end()) @@ -166,6 +196,34 @@ private: case 'K': m_pos += 2; return new_node(ParsedRegex::ResetStart); } break; + case '(': + { + Optional lookaround_op; + constexpr struct { StringView prefix; ParsedRegex::Op op; } lookarounds[] = { + { "(?=", ParsedRegex::LookAhead }, + { "(?!", ParsedRegex::NegativeLookAhead }, + { "(?<=", ParsedRegex::LookBehind }, + { "(?>>{}'", error, StringView{m_regex.begin(), m_pos.base()},