From 856846b66fec574311eeeb30d42d029c7bb86a27 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Tue, 27 Jul 2010 19:53:10 +0000 Subject: [PATCH] grep and egrep grammars git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@109534 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/regex | 70 ++++++++++++++++ test/re/re.alg/re.alg.search/egrep.pass.cpp | 92 +++++++++++++++++++++ test/re/re.alg/re.alg.search/grep.pass.cpp | 60 ++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 test/re/re.alg/re.alg.search/egrep.pass.cpp create mode 100644 test/re/re.alg/re.alg.search/grep.pass.cpp diff --git a/include/regex b/include/regex index b59a87c4..4d132a12 100644 --- a/include/regex +++ b/include/regex @@ -2701,6 +2701,12 @@ private: template _ForwardIterator __parse_pattern_character(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_grep(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_egrep(_ForwardIterator __first, _ForwardIterator __last); void __push_l_anchor() {__left_anchor_ = true;} void __push_r_anchor(); @@ -2832,8 +2838,10 @@ basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first, case awk: break; case grep: + __parse_grep(__first, __last); break; case egrep: + __parse_egrep(__first, __last); break; default: throw regex_error(regex_constants::__re_err_grammar); @@ -4108,6 +4116,68 @@ basic_regex<_CharT, _Traits>::__parse_pattern_character(_ForwardIterator __first return __first; } +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_grep(_ForwardIterator __first, + _ForwardIterator __last) +{ + __owns_one_state<_CharT>* __sa = __end_; + _ForwardIterator __t1 = _STD::find(__first, __last, _CharT('\n')); + if (__t1 != __first) + __parse_basic_reg_exp(__first, __t1); + else + __push_empty(); + __first = __t1; + if (__first != __last) + ++__first; + while (__first != __last) + { + __t1 = _STD::find(__first, __last, _CharT('\n')); + __owns_one_state<_CharT>* __sb = __end_; + if (__t1 != __first) + __parse_basic_reg_exp(__first, __t1); + else + __push_empty(); + __push_alternation(__sa, __sb); + __first = __t1; + if (__first != __last) + ++__first; + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_egrep(_ForwardIterator __first, + _ForwardIterator __last) +{ + __owns_one_state<_CharT>* __sa = __end_; + _ForwardIterator __t1 = _STD::find(__first, __last, _CharT('\n')); + if (__t1 != __first) + __parse_extended_reg_exp(__first, __t1); + else + __push_empty(); + __first = __t1; + if (__first != __last) + ++__first; + while (__first != __last) + { + __t1 = _STD::find(__first, __last, _CharT('\n')); + __owns_one_state<_CharT>* __sb = __end_; + if (__t1 != __first) + __parse_extended_reg_exp(__first, __t1); + else + __push_empty(); + __push_alternation(__sa, __sb); + __first = __t1; + if (__first != __last) + ++__first; + } + return __first; +} + template void basic_regex<_CharT, _Traits>::__push_loop(size_t __min, size_t __max, diff --git a/test/re/re.alg/re.alg.search/egrep.pass.cpp b/test/re/re.alg/re.alg.search/egrep.pass.cpp new file mode 100644 index 00000000..1fd2be06 --- /dev/null +++ b/test/re/re.alg/re.alg.search/egrep.pass.cpp @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// bool +// regex_search(BidirectionalIterator first, BidirectionalIterator last, +// match_results& m, +// const basic_regex& e, +// regex_constants::match_flag_type flags = regex_constants::match_default); + +#include + +#include +#include + +#include "../../iterators.h" + +int main() +{ + { + std::cmatch m; + const char s[] = "tournament"; + assert(std::regex_search(s, m, std::regex("tour\nto\ntournament", + std::regex_constants::egrep))); + 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 == s + std::char_traits::length(s)); + assert(m.length(0) == 10); + assert(m.position(0) == 0); + assert(m.str(0) == "tournament"); + } + { + std::cmatch m; + const char s[] = "ment"; + assert(std::regex_search(s, m, std::regex("tour\n\ntournament", + std::regex_constants::egrep))); + 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 == s + std::char_traits::length(s)); + assert(m.length(0) == 0); + assert(m.position(0) == 0); + assert(m.str(0) == ""); + } + { + std::cmatch m; + const char s[] = "tournament"; + assert(std::regex_search(s, m, std::regex("(tour|to|tournament)+\ntourna", + std::regex_constants::egrep))); + 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 == s + std::char_traits::length(s)); + assert(m.length(0) == 10); + assert(m.position(0) == 0); + assert(m.str(0) == "tournament"); + } + { + std::cmatch m; + const char s[] = "tourna"; + assert(std::regex_search(s, m, std::regex("(tour|to|tournament)+\ntourna", + std::regex_constants::egrep))); + 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 == s + std::char_traits::length(s)); + assert(m.length(0) == 6); + assert(m.position(0) == 0); + assert(m.str(0) == "tourna"); + } +} diff --git a/test/re/re.alg/re.alg.search/grep.pass.cpp b/test/re/re.alg/re.alg.search/grep.pass.cpp new file mode 100644 index 00000000..cfd08fee --- /dev/null +++ b/test/re/re.alg/re.alg.search/grep.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// bool +// regex_search(BidirectionalIterator first, BidirectionalIterator last, +// match_results& m, +// const basic_regex& e, +// regex_constants::match_flag_type flags = regex_constants::match_default); + +#include + +#include +#include + +#include "../../iterators.h" + +int main() +{ + { + std::cmatch m; + const char s[] = "tournament"; + assert(std::regex_search(s, m, std::regex("tour\nto\ntournament", + std::regex_constants::grep))); + 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 == s + std::char_traits::length(s)); + assert(m.length(0) == 10); + assert(m.position(0) == 0); + assert(m.str(0) == "tournament"); + } + { + std::cmatch m; + const char s[] = "ment"; + assert(std::regex_search(s, m, std::regex("tour\n\ntournament", + std::regex_constants::grep))); + 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 == s + std::char_traits::length(s)); + assert(m.length(0) == 0); + assert(m.position(0) == 0); + assert(m.str(0) == ""); + } +}