123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- ///////////////////////////////////////////////////////////////////////////////
- /// \file parser.hpp
- /// Contains the definition of regex_compiler, a factory for building regex objects
- /// from strings.
- //
- // Copyright 2008 Eric Niebler. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_HPP_EAN_10_04_2005
- #define BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_HPP_EAN_10_04_2005
- // MS compatible compilers support #pragma once
- #if defined(_MSC_VER)
- # pragma once
- # pragma warning(push)
- # pragma warning(disable : 4127) // conditional expression is constant
- #endif
- #include <boost/assert.hpp>
- #include <boost/xpressive/regex_constants.hpp>
- #include <boost/xpressive/detail/detail_fwd.hpp>
- #include <boost/xpressive/detail/core/matchers.hpp>
- #include <boost/xpressive/detail/utility/ignore_unused.hpp>
- #include <boost/xpressive/detail/dynamic/dynamic.hpp>
- // The Regular Expression grammar, in pseudo BNF:
- //
- // expression = alternates ;
- //
- // alternates = sequence, *('|', sequence) ;
- //
- // sequence = quant, *(quant) ;
- //
- // quant = atom, [*+?] ;
- //
- // atom = literal |
- // '.' |
- // '\' any |
- // '(' expression ')' ;
- //
- // literal = not a meta-character ;
- //
- namespace boost { namespace xpressive { namespace detail
- {
- ///////////////////////////////////////////////////////////////////////////////
- // make_char_xpression
- //
- template<typename BidiIter, typename Char, typename Traits>
- inline sequence<BidiIter> make_char_xpression
- (
- Char ch
- , regex_constants::syntax_option_type flags
- , Traits const &tr
- )
- {
- if(0 != (regex_constants::icase_ & flags))
- {
- literal_matcher<Traits, mpl::true_, mpl::false_> matcher(ch, tr);
- return make_dynamic<BidiIter>(matcher);
- }
- else
- {
- literal_matcher<Traits, mpl::false_, mpl::false_> matcher(ch, tr);
- return make_dynamic<BidiIter>(matcher);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // make_any_xpression
- //
- template<typename BidiIter, typename Traits>
- inline sequence<BidiIter> make_any_xpression
- (
- regex_constants::syntax_option_type flags
- , Traits const &tr
- )
- {
- using namespace regex_constants;
- typedef typename iterator_value<BidiIter>::type char_type;
- typedef detail::set_matcher<Traits, mpl::int_<2> > set_matcher;
- typedef literal_matcher<Traits, mpl::false_, mpl::true_> literal_matcher;
- char_type const newline = tr.widen('\n');
- set_matcher s;
- s.set_[0] = newline;
- s.set_[1] = 0;
- s.inverse();
- switch(((int)not_dot_newline | not_dot_null) & flags)
- {
- case not_dot_null:
- return make_dynamic<BidiIter>(literal_matcher(char_type(0), tr));
- case not_dot_newline:
- return make_dynamic<BidiIter>(literal_matcher(newline, tr));
- case (int)not_dot_newline | not_dot_null:
- return make_dynamic<BidiIter>(s);
- default:
- return make_dynamic<BidiIter>(any_matcher());
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // make_literal_xpression
- //
- template<typename BidiIter, typename Traits>
- inline sequence<BidiIter> make_literal_xpression
- (
- typename Traits::string_type const &literal
- , regex_constants::syntax_option_type flags
- , Traits const &tr
- )
- {
- BOOST_ASSERT(0 != literal.size());
- if(1 == literal.size())
- {
- return make_char_xpression<BidiIter>(literal[0], flags, tr);
- }
- if(0 != (regex_constants::icase_ & flags))
- {
- string_matcher<Traits, mpl::true_> matcher(literal, tr);
- return make_dynamic<BidiIter>(matcher);
- }
- else
- {
- string_matcher<Traits, mpl::false_> matcher(literal, tr);
- return make_dynamic<BidiIter>(matcher);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // make_backref_xpression
- //
- template<typename BidiIter, typename Traits>
- inline sequence<BidiIter> make_backref_xpression
- (
- int mark_nbr
- , regex_constants::syntax_option_type flags
- , Traits const &tr
- )
- {
- if(0 != (regex_constants::icase_ & flags))
- {
- return make_dynamic<BidiIter>
- (
- mark_matcher<Traits, mpl::true_>(mark_nbr, tr)
- );
- }
- else
- {
- return make_dynamic<BidiIter>
- (
- mark_matcher<Traits, mpl::false_>(mark_nbr, tr)
- );
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // merge_charset
- //
- template<typename Char, typename Traits>
- inline void merge_charset
- (
- basic_chset<Char> &basic
- , compound_charset<Traits> const &compound
- , Traits const &tr
- )
- {
- detail::ignore_unused(tr);
- if(0 != compound.posix_yes())
- {
- typename Traits::char_class_type mask = compound.posix_yes();
- for(int i = 0; i <= static_cast<int>(UCHAR_MAX); ++i)
- {
- if(tr.isctype((Char)i, mask))
- {
- basic.set((Char)i);
- }
- }
- }
- if(!compound.posix_no().empty())
- {
- for(std::size_t j = 0; j < compound.posix_no().size(); ++j)
- {
- typename Traits::char_class_type mask = compound.posix_no()[j];
- for(int i = 0; i <= static_cast<int>(UCHAR_MAX); ++i)
- {
- if(!tr.isctype((Char)i, mask))
- {
- basic.set((Char)i);
- }
- }
- }
- }
- if(compound.is_inverted())
- {
- basic.inverse();
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // make_charset_xpression
- //
- template<typename BidiIter, typename Traits>
- inline sequence<BidiIter> make_charset_xpression
- (
- compound_charset<Traits> &chset
- , Traits const &tr
- , regex_constants::syntax_option_type flags
- )
- {
- typedef typename Traits::char_type char_type;
- bool const icase = (0 != (regex_constants::icase_ & flags));
- bool const optimize = is_narrow_char<char_type>::value && 0 != (regex_constants::optimize & flags);
- // don't care about compile speed -- fold eveything into a bitset<256>
- if(optimize)
- {
- typedef basic_chset<char_type> charset_type;
- charset_type charset(chset.base());
- if(icase)
- {
- charset_matcher<Traits, mpl::true_, charset_type> matcher(charset);
- merge_charset(matcher.charset_, chset, tr);
- return make_dynamic<BidiIter>(matcher);
- }
- else
- {
- charset_matcher<Traits, mpl::false_, charset_type> matcher(charset);
- merge_charset(matcher.charset_, chset, tr);
- return make_dynamic<BidiIter>(matcher);
- }
- }
- // special case to make [[:digit:]] fast
- else if(chset.base().empty() && chset.posix_no().empty())
- {
- BOOST_ASSERT(0 != chset.posix_yes());
- posix_charset_matcher<Traits> matcher(chset.posix_yes(), chset.is_inverted());
- return make_dynamic<BidiIter>(matcher);
- }
- // default, slow
- else
- {
- if(icase)
- {
- charset_matcher<Traits, mpl::true_> matcher(chset);
- return make_dynamic<BidiIter>(matcher);
- }
- else
- {
- charset_matcher<Traits, mpl::false_> matcher(chset);
- return make_dynamic<BidiIter>(matcher);
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // make_posix_charset_xpression
- //
- template<typename BidiIter, typename Traits>
- inline sequence<BidiIter> make_posix_charset_xpression
- (
- typename Traits::char_class_type m
- , bool no
- , regex_constants::syntax_option_type //flags
- , Traits const & //traits
- )
- {
- posix_charset_matcher<Traits> charset(m, no);
- return make_dynamic<BidiIter>(charset);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // make_assert_begin_line
- //
- template<typename BidiIter, typename Traits>
- inline sequence<BidiIter> make_assert_begin_line
- (
- regex_constants::syntax_option_type flags
- , Traits const &tr
- )
- {
- if(0 != (regex_constants::single_line & flags))
- {
- return detail::make_dynamic<BidiIter>(detail::assert_bos_matcher());
- }
- else
- {
- detail::assert_bol_matcher<Traits> matcher(tr);
- return detail::make_dynamic<BidiIter>(matcher);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // make_assert_end_line
- //
- template<typename BidiIter, typename Traits>
- inline sequence<BidiIter> make_assert_end_line
- (
- regex_constants::syntax_option_type flags
- , Traits const &tr
- )
- {
- if(0 != (regex_constants::single_line & flags))
- {
- return detail::make_dynamic<BidiIter>(detail::assert_eos_matcher());
- }
- else
- {
- detail::assert_eol_matcher<Traits> matcher(tr);
- return detail::make_dynamic<BidiIter>(matcher);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // make_assert_word
- //
- template<typename BidiIter, typename Cond, typename Traits>
- inline sequence<BidiIter> make_assert_word(Cond, Traits const &tr)
- {
- return detail::make_dynamic<BidiIter>
- (
- detail::assert_word_matcher<Cond, Traits>(tr)
- );
- }
- ///////////////////////////////////////////////////////////////////////////////
- // make_independent_end_xpression
- //
- template<typename BidiIter>
- inline sequence<BidiIter> make_independent_end_xpression(bool pure)
- {
- if(pure)
- {
- return detail::make_dynamic<BidiIter>(detail::true_matcher());
- }
- else
- {
- return detail::make_dynamic<BidiIter>(detail::independent_end_matcher());
- }
- }
- }}} // namespace boost::xpressive::detail
- #if defined(_MSC_VER)
- # pragma warning(pop)
- #endif
- #endif
|