[cfe-commits] [libcxx] r108168 - in /libcxx/trunk: include/regex test/re/re.alg/re.alg.search/basic.pass.cpp

Howard Hinnant hhinnant at apple.com
Mon Jul 12 11:16:05 PDT 2010


Author: hhinnant
Date: Mon Jul 12 13:16:05 2010
New Revision: 108168

URL: http://llvm.org/viewvc/llvm-project?rev=108168&view=rev
Log:
back references for BRE

Modified:
    libcxx/trunk/include/regex
    libcxx/trunk/test/re/re.alg/re.alg.search/basic.pass.cpp

Modified: libcxx/trunk/include/regex
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/regex?rev=108168&r1=108167&r2=108168&view=diff
==============================================================================
--- libcxx/trunk/include/regex (original)
+++ libcxx/trunk/include/regex Mon Jul 12 13:16:05 2010
@@ -1627,6 +1627,59 @@
     __s.__node_ = this->first();
 }
 
+// __back_ref
+
+template <class _CharT>
+class __back_ref
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    unsigned __mexp_;
+public:
+    typedef _STD::__state<_CharT> __state;
+
+    explicit __back_ref(unsigned __mexp, __node<_CharT>* __s)
+        : base(__s), __mexp_(__mexp) {}
+
+    virtual void __exec(__state&) const;
+
+    virtual string speak() const
+    {
+        ostringstream os;
+        os << "__back_ref " << __mexp_;
+        return os.str();
+    }
+};
+
+template <class _CharT>
+void
+__back_ref<_CharT>::__exec(__state& __s) const
+{
+    sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_-1];
+    if (__sm.matched)
+    {
+        ptrdiff_t __len = __sm.second - __sm.first;
+        if (__s.__last_ - __s.__current_ >= __len &&
+            _STD::equal(__sm.first, __sm.second, __s.__current_))
+        {
+            __s.__do_ = __state::__accept_but_not_consume;
+            __s.__current_ += __len;
+            __s.__node_ = this->first();
+        }
+        else
+        {
+            __s.__do_ = __state::__reject;
+            __s.__node_ = nullptr;
+        }
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
 // __r_anchor
 
 template <class _CharT>
@@ -1971,7 +2024,7 @@
     void __push_char(const typename _Traits::string_type& __c) {}
     void __push_range() {}
     void __push_class_type(typename _Traits::char_class_type) {}
-    void __push_back_ref(int __i) {}
+    void __push_back_ref(int __i);
     void __push_alternation() {}
     void __push_begin_marked_subexpression();
     void __push_end_marked_subexpression(unsigned);
@@ -2528,7 +2581,8 @@
                     __temp = __parse_Back_close_brace(__first, __last);
                     if (__temp == __first)
                         throw regex_error(regex_constants::error_brace);
-                    __push_exact_repeat(__min);
+                    __push_loop(__min, __min, __s, __mexp_begin, __mexp_end,
+                                    true);
                     __first = __temp;
                 }
                 else
@@ -2545,7 +2599,8 @@
                     {
                         if (__max < __min)
                             throw regex_error(regex_constants::error_badbrace);
-                        __push_loop(__min, __max, __s);
+                        __push_loop(__min, __max, __s, __mexp_begin, __mexp_end,
+                                    true);
                     }
                     __first = __temp;
                 }
@@ -2896,6 +2951,14 @@
     __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
 }
 
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_back_ref(int __i)
+{
+    __end_->first() = new __back_ref<_CharT>(__i, __end_->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
+
 typedef basic_regex<char>    regex;
 typedef basic_regex<wchar_t> wregex;
 
@@ -3606,14 +3669,8 @@
                 }
                 break;
             case __state::__accept_and_consume:
-                // needs to be changed for the case that this state
-                // consumed more than one character.  This will adjust
-                // __current based on __s.__current_
-                if (__current != __last)
-                {
-                    ++__current;
-                    ++__j;
-                }
+                __j += __s.__current_ - __current;
+                __current = __s.__current_;
                 break;
             case __state::__repeat:
             case __state::__accept_but_not_consume:

Modified: libcxx/trunk/test/re/re.alg/re.alg.search/basic.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/re/re.alg/re.alg.search/basic.pass.cpp?rev=108168&r1=108167&r2=108168&view=diff
==============================================================================
--- libcxx/trunk/test/re/re.alg/re.alg.search/basic.pass.cpp (original)
+++ libcxx/trunk/test/re/re.alg/re.alg.search/basic.pass.cpp Mon Jul 12 13:16:05 2010
@@ -310,4 +310,166 @@
         assert(m.position(1) == 0);
         assert(m.str(1) == "");
     }
+    {
+        std::cmatch m;
+        const char s[] = "abbc";
+        assert(!std::regex_search(s, m, std::regex("ab\\{3,5\\}c", std::regex_constants::basic)));
+        assert(m.size() == 0);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "abbbc";
+        assert(std::regex_search(s, m, std::regex("ab\\{3,5\\}c", std::regex_constants::basic)));
+        assert(m.size() == 1);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == m[0].second);
+        assert(m.length(0) == sizeof(s)-1);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "abbbbc";
+        assert(std::regex_search(s, m, std::regex("ab\\{3,5\\}c", std::regex_constants::basic)));
+        assert(m.size() == 1);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == m[0].second);
+        assert(m.length(0) == sizeof(s)-1);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "abbbbbc";
+        assert(std::regex_search(s, m, std::regex("ab\\{3,5\\}c", std::regex_constants::basic)));
+        assert(m.size() == 1);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == m[0].second);
+        assert(m.length(0) == sizeof(s)-1);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "adefc";
+        assert(!std::regex_search(s, m, std::regex("ab\\{3,5\\}c", std::regex_constants::basic)));
+        assert(m.size() == 0);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "abbbbbbc";
+        assert(!std::regex_search(s, m, std::regex("ab\\{3,5\\}c", std::regex_constants::basic)));
+        assert(m.size() == 0);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "adec";
+        assert(!std::regex_search(s, m, std::regex("a.\\{3,5\\}c", std::regex_constants::basic)));
+        assert(m.size() == 0);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "adefc";
+        assert(std::regex_search(s, m, std::regex("a.\\{3,5\\}c", std::regex_constants::basic)));
+        assert(m.size() == 1);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == m[0].second);
+        assert(m.length(0) == sizeof(s)-1);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "adefgc";
+        assert(std::regex_search(s, m, std::regex("a.\\{3,5\\}c", std::regex_constants::basic)));
+        assert(m.size() == 1);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == m[0].second);
+        assert(m.length(0) == sizeof(s)-1);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "adefghc";
+        assert(std::regex_search(s, m, std::regex("a.\\{3,5\\}c", std::regex_constants::basic)));
+        assert(m.size() == 1);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == m[0].second);
+        assert(m.length(0) == sizeof(s)-1);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "adefghic";
+        assert(!std::regex_search(s, m, std::regex("a.\\{3,5\\}c", std::regex_constants::basic)));
+        assert(m.size() == 0);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "-ab,ab-";
+        assert(std::regex_search(s, m, std::regex("-\\(.*\\),\\1-", std::regex_constants::basic)));
+        assert(m.size() == 2);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == m[0].second);
+        assert(m.length(0) == std::char_traits<char>::length(s));
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+        assert(m.length(1) == 2);
+        assert(m.position(1) == 1);
+        assert(m.str(1) == "ab");
+    }
+    {
+        std::cmatch m;
+        const char s[] = "ababbabb";
+        assert(std::regex_search(s, m, std::regex("^\\(ab*\\)*\\1$", std::regex_constants::basic)));
+        assert(m.size() == 2);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == m[0].second);
+        assert(m.length(0) == std::char_traits<char>::length(s));
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+        assert(m.length(1) == 3);
+        assert(m.position(1) == 2);
+        assert(m.str(1) == "abb");
+    }
+    {
+        std::cmatch m;
+        const char s[] = "ababbab";
+        assert(!std::regex_search(s, m, std::regex("^\\(ab*\\)*\\1$", std::regex_constants::basic)));
+        assert(m.size() == 0);
+    }
 }





More information about the cfe-commits mailing list