From da17cddd8fe5ab873de06eede24a6faa13e5eab9 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 5 Jul 2011 18:08:01 +0200 Subject: Actual regex implementation --- cutl/re/re.cxx | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 cutl/re/re.cxx (limited to 'cutl/re/re.cxx') diff --git a/cutl/re/re.cxx b/cutl/re/re.cxx new file mode 100644 index 0000000..9cd2f2e --- /dev/null +++ b/cutl/re/re.cxx @@ -0,0 +1,175 @@ +// file : cutl/re/re.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include + +#include + +#include + +using namespace std; + +namespace cutl +{ + namespace re + { + // + // format + // + + format:: + ~format () throw () + { + } + + char const* format:: + what () const throw () + { + return description_.c_str (); + } + + // + // regex + // + struct regex::impl + { + impl () {} + impl (string const& s): r (s, tr1::regex_constants::ECMAScript) {} + impl (tr1::regex const& r): r (r) {} + + tr1::regex r; + }; + + regex:: + ~regex () + { + delete impl_; + } + + regex:: + regex (regex const& r) + : impl_ (new impl (r.impl_->r)) + { + } + + regex& regex:: + operator= (regex const& r) + { + impl_->r = r.impl_->r; + return *this; + } + + void regex:: + init (string const* s) + { + try + { + if (impl_ == 0) + impl_ = s == 0 ? new impl : new impl (*s); + else + impl_->r = *s; + } + catch (tr1::regex_error const& e) + { + throw format (s == 0 ? "" : *s, e.what ()); + } + } + + bool regex:: + match (string const& s) const + { + return tr1::regex_match (s, impl_->r); + } + + bool regex:: + search (string const& s) const + { + return tr1::regex_search (s, impl_->r); + } + + string regex:: + replace (string const& s, string const& sub, bool first_only) const + { + tr1::regex_constants::match_flag_type f ( + tr1::regex_constants::format_default); + + if (first_only) + f |= tr1::regex_constants::format_first_only; + + return regex_replace (s, impl_->r, sub, f); + } + + string regex:: + str () const + { + return impl_->r.str (); + } + + bool regex:: + empty () const + { + return impl_->r.empty (); + } + + ostream& + operator<< (ostream& os, regex const& r) + { + return os << r.str ().c_str (); + } + + // + // regexsub + // + void regexsub:: + init (string const& s) + { + string r; + string::size_type p (parse (s, 0, r)); + regex_ = r; + p = parse (s, p, sub_); + if (p + 1 < s.size ()) + throw format (s, "junk after third delimiter"); + } + + // + // parse() + // + string::size_type + parse (string const& s, string::size_type p, string& r) + { + r.clear (); + string::size_type n (s.size ()); + + if (p >= n) + throw format (s, "empty expression"); + + char d (s[p++]); + + for (; p < n; ++p) + { + if (s[p] == d) + break; + + if (s[p] == '\\') + { + if (++p < n) + { + if (s[p] != d && s[p] != '\\') + r += '\\'; + r += s[p]; + } + // else {we ran out of stuff before finding the delimiter} + } + else + r += s[p]; + } + + if (p == n) + throw format (s, "missing closing delimiter"); + + return p; + } + } +} -- cgit v1.1