diff options
Diffstat (limited to 'boost/regex/v4/basic_regex_parser.hpp')
-rw-r--r-- | boost/regex/v4/basic_regex_parser.hpp | 212 |
1 files changed, 202 insertions, 10 deletions
diff --git a/boost/regex/v4/basic_regex_parser.hpp b/boost/regex/v4/basic_regex_parser.hpp index 3c331a57c4..4a80ab9c32 100644 --- a/boost/regex/v4/basic_regex_parser.hpp +++ b/boost/regex/v4/basic_regex_parser.hpp @@ -31,7 +31,7 @@ #endif namespace boost{ -namespace re_detail{ +namespace BOOST_REGEX_DETAIL_NS{ #ifdef BOOST_MSVC #pragma warning(push) @@ -68,6 +68,8 @@ public: bool parse_inner_set(basic_char_set<charT, traits>& char_set); bool parse_QE(); bool parse_perl_extension(); + bool parse_perl_verb(); + bool match_verb(const char*); bool add_emacs_code(bool negate); bool unwind_alts(std::ptrdiff_t last_paren_start); digraph<charT> get_next_set_literal(basic_char_set<charT, traits>& char_set); @@ -165,7 +167,7 @@ void basic_regex_parser<charT, traits>::parse(const charT* p1, const charT* p2, // have had an unexpected ')' : if(!result) { - fail(regex_constants::error_paren, ::boost::re_detail::distance(m_base, m_position), "Found a closing ) with no corresponding openening parenthesis."); + fail(regex_constants::error_paren, ::boost::BOOST_REGEX_DETAIL_NS::distance(m_base, m_position), "Found a closing ) with no corresponding openening parenthesis."); return; } // if an error has been set then give up now: @@ -421,6 +423,8 @@ bool basic_regex_parser<charT, traits>::parse_open_paren() { if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question) return parse_perl_extension(); + if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_star) + return parse_perl_verb(); } // // update our mark count, and append the required state: @@ -489,7 +493,7 @@ bool basic_regex_parser<charT, traits>::parse_open_paren() // if(m_position == m_end) { - this->fail(regex_constants::error_paren, ::boost::re_detail::distance(m_base, m_end)); + this->fail(regex_constants::error_paren, ::boost::BOOST_REGEX_DETAIL_NS::distance(m_base, m_end)); return false; } BOOST_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark); @@ -924,9 +928,9 @@ bool basic_regex_parser<charT, traits>::parse_match_any() static_cast<re_dot*>( this->append_state(syntax_element_wild, sizeof(re_dot)) )->mask = static_cast<unsigned char>(this->flags() & regbase::no_mod_s - ? re_detail::force_not_newline + ? BOOST_REGEX_DETAIL_NS::force_not_newline : this->flags() & regbase::mod_s ? - re_detail::force_newline : re_detail::dont_care); + BOOST_REGEX_DETAIL_NS::force_newline : BOOST_REGEX_DETAIL_NS::dont_care); return true; } @@ -963,7 +967,7 @@ bool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_ } if(0 == this->m_last_state) { - fail(regex_constants::error_badrepeat, ::boost::re_detail::distance(m_base, m_position), "Nothing to repeat."); + fail(regex_constants::error_badrepeat, ::boost::BOOST_REGEX_DETAIL_NS::distance(m_base, m_position), "Nothing to repeat."); return false; } if(this->m_last_state->type == syntax_element_endmark) @@ -1235,7 +1239,7 @@ bool basic_regex_parser<charT, traits>::parse_alt() // // we need to append a trailing jump: // - re_syntax_base* pj = this->append_state(re_detail::syntax_element_jump, sizeof(re_jump)); + re_syntax_base* pj = this->append_state(BOOST_REGEX_DETAIL_NS::syntax_element_jump, sizeof(re_jump)); std::ptrdiff_t jump_offset = this->getoffset(pj); // // now insert the alternative: @@ -1784,7 +1788,7 @@ charT basic_regex_parser<charT, traits>::unescape_character() { // an octal escape sequence, the first character must be a zero // followed by up to 3 octal digits: - std::ptrdiff_t len = (std::min)(::boost::re_detail::distance(m_position, m_end), static_cast<std::ptrdiff_t>(4)); + std::ptrdiff_t len = (std::min)(::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end), static_cast<std::ptrdiff_t>(4)); const charT* bp = m_position; int val = this->m_traits.toi(bp, bp + 1, 8); if(val != 0) @@ -2521,7 +2525,7 @@ option_group_jump: // Rewind to start of (? sequence: --m_position; while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; - this->fail(regex_constants::error_paren, ::boost::re_detail::distance(m_base, m_end)); + this->fail(regex_constants::error_paren, ::boost::BOOST_REGEX_DETAIL_NS::distance(m_base, m_end)); return false; } BOOST_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark); @@ -2653,6 +2657,194 @@ option_group_jump: } template <class charT, class traits> +bool basic_regex_parser<charT, traits>::match_verb(const char* verb) +{ + while(*verb) + { + if(static_cast<charT>(*verb) != *m_position) + { + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + if(++m_position == m_end) + { + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + ++verb; + } + return true; +} + +template <class charT, class traits> +bool basic_regex_parser<charT, traits>::parse_perl_verb() +{ + if(++m_position == m_end) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + switch(*m_position) + { + case 'F': + if(++m_position == m_end) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + if((this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark) || match_verb("AIL")) + { + if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + ++m_position; + this->append_state(syntax_element_fail); + return true; + } + break; + case 'A': + if(++m_position == m_end) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + if(match_verb("CCEPT")) + { + if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + ++m_position; + this->append_state(syntax_element_accept); + return true; + } + break; + case 'C': + if(++m_position == m_end) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + if(match_verb("OMMIT")) + { + if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + ++m_position; + static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_commit; + this->m_pdata->m_disable_match_any = true; + return true; + } + break; + case 'P': + if(++m_position == m_end) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + if(match_verb("RUNE")) + { + if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + ++m_position; + static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_prune; + this->m_pdata->m_disable_match_any = true; + return true; + } + break; + case 'S': + if(++m_position == m_end) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + if(match_verb("KIP")) + { + if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + ++m_position; + static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_skip; + this->m_pdata->m_disable_match_any = true; + return true; + } + break; + case 'T': + if(++m_position == m_end) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + if(match_verb("HEN")) + { + if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)) + { + // Rewind to start of (* sequence: + --m_position; + while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position; + fail(regex_constants::error_perl_extension, m_position - m_base); + return false; + } + ++m_position; + this->append_state(syntax_element_then); + this->m_pdata->m_disable_match_any = true; + return true; + } + break; + } + return false; +} + +template <class charT, class traits> bool basic_regex_parser<charT, traits>::add_emacs_code(bool negate) { // @@ -2862,7 +3054,7 @@ bool basic_regex_parser<charT, traits>::unwind_alts(std::ptrdiff_t last_paren_st #pragma warning(pop) #endif -} // namespace re_detail +} // namespace BOOST_REGEX_DETAIL_NS } // namespace boost #ifdef BOOST_MSVC |