File indexing completed on 2025-12-16 10:11:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_HPP_EAN_10_04_2005
0011 #define BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_HPP_EAN_10_04_2005
0012
0013
0014 #if defined(_MSC_VER)
0015 # pragma once
0016 # pragma warning(push)
0017 # pragma warning(disable : 4127)
0018 #endif
0019
0020 #include <boost/assert.hpp>
0021 #include <boost/xpressive/regex_constants.hpp>
0022 #include <boost/xpressive/detail/detail_fwd.hpp>
0023 #include <boost/xpressive/detail/core/matchers.hpp>
0024 #include <boost/xpressive/detail/utility/ignore_unused.hpp>
0025 #include <boost/xpressive/detail/dynamic/dynamic.hpp>
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 namespace boost { namespace xpressive { namespace detail
0046 {
0047
0048
0049
0050
0051 template<typename BidiIter, typename Char, typename Traits>
0052 inline sequence<BidiIter> make_char_xpression
0053 (
0054 Char ch
0055 , regex_constants::syntax_option_type flags
0056 , Traits const &tr
0057 )
0058 {
0059 if(0 != (regex_constants::icase_ & flags))
0060 {
0061 literal_matcher<Traits, mpl::true_, mpl::false_> matcher(ch, tr);
0062 return make_dynamic<BidiIter>(matcher);
0063 }
0064 else
0065 {
0066 literal_matcher<Traits, mpl::false_, mpl::false_> matcher(ch, tr);
0067 return make_dynamic<BidiIter>(matcher);
0068 }
0069 }
0070
0071
0072
0073
0074 template<typename BidiIter, typename Traits>
0075 inline sequence<BidiIter> make_any_xpression
0076 (
0077 regex_constants::syntax_option_type flags
0078 , Traits const &tr
0079 )
0080 {
0081 using namespace regex_constants;
0082 typedef typename iterator_value<BidiIter>::type char_type;
0083 typedef detail::set_matcher<Traits, mpl::int_<2> > set_matcher;
0084 typedef literal_matcher<Traits, mpl::false_, mpl::true_> literal_matcher;
0085
0086 char_type const newline = tr.widen('\n');
0087 set_matcher s;
0088 s.set_[0] = newline;
0089 s.set_[1] = 0;
0090 s.inverse();
0091
0092 switch(((int)not_dot_newline | not_dot_null) & flags)
0093 {
0094 case not_dot_null:
0095 return make_dynamic<BidiIter>(literal_matcher(char_type(0), tr));
0096
0097 case not_dot_newline:
0098 return make_dynamic<BidiIter>(literal_matcher(newline, tr));
0099
0100 case (int)not_dot_newline | not_dot_null:
0101 return make_dynamic<BidiIter>(s);
0102
0103 default:
0104 return make_dynamic<BidiIter>(any_matcher());
0105 }
0106 }
0107
0108
0109
0110
0111 template<typename BidiIter, typename Traits>
0112 inline sequence<BidiIter> make_literal_xpression
0113 (
0114 typename Traits::string_type const &literal
0115 , regex_constants::syntax_option_type flags
0116 , Traits const &tr
0117 )
0118 {
0119 BOOST_ASSERT(0 != literal.size());
0120 if(1 == literal.size())
0121 {
0122 return make_char_xpression<BidiIter>(literal[0], flags, tr);
0123 }
0124
0125 if(0 != (regex_constants::icase_ & flags))
0126 {
0127 string_matcher<Traits, mpl::true_> matcher(literal, tr);
0128 return make_dynamic<BidiIter>(matcher);
0129 }
0130 else
0131 {
0132 string_matcher<Traits, mpl::false_> matcher(literal, tr);
0133 return make_dynamic<BidiIter>(matcher);
0134 }
0135 }
0136
0137
0138
0139
0140 template<typename BidiIter, typename Traits>
0141 inline sequence<BidiIter> make_backref_xpression
0142 (
0143 int mark_nbr
0144 , regex_constants::syntax_option_type flags
0145 , Traits const &tr
0146 )
0147 {
0148 if(0 != (regex_constants::icase_ & flags))
0149 {
0150 return make_dynamic<BidiIter>
0151 (
0152 mark_matcher<Traits, mpl::true_>(mark_nbr, tr)
0153 );
0154 }
0155 else
0156 {
0157 return make_dynamic<BidiIter>
0158 (
0159 mark_matcher<Traits, mpl::false_>(mark_nbr, tr)
0160 );
0161 }
0162 }
0163
0164
0165
0166
0167 template<typename Char, typename Traits>
0168 inline void merge_charset
0169 (
0170 basic_chset<Char> &basic
0171 , compound_charset<Traits> const &compound
0172 , Traits const &tr
0173 )
0174 {
0175 detail::ignore_unused(tr);
0176 if(0 != compound.posix_yes())
0177 {
0178 typename Traits::char_class_type mask = compound.posix_yes();
0179 for(int i = 0; i <= static_cast<int>(UCHAR_MAX); ++i)
0180 {
0181 if(tr.isctype((Char)i, mask))
0182 {
0183 basic.set((Char)i);
0184 }
0185 }
0186 }
0187
0188 if(!compound.posix_no().empty())
0189 {
0190 for(std::size_t j = 0; j < compound.posix_no().size(); ++j)
0191 {
0192 typename Traits::char_class_type mask = compound.posix_no()[j];
0193 for(int i = 0; i <= static_cast<int>(UCHAR_MAX); ++i)
0194 {
0195 if(!tr.isctype((Char)i, mask))
0196 {
0197 basic.set((Char)i);
0198 }
0199 }
0200 }
0201 }
0202
0203 if(compound.is_inverted())
0204 {
0205 basic.inverse();
0206 }
0207 }
0208
0209
0210
0211
0212 template<typename BidiIter, typename Traits>
0213 inline sequence<BidiIter> make_charset_xpression
0214 (
0215 compound_charset<Traits> &chset
0216 , Traits const &tr
0217 , regex_constants::syntax_option_type flags
0218 )
0219 {
0220 typedef typename Traits::char_type char_type;
0221 bool const icase = (0 != (regex_constants::icase_ & flags));
0222 bool const optimize = is_narrow_char<char_type>::value && 0 != (regex_constants::optimize & flags);
0223
0224
0225 if(optimize)
0226 {
0227 typedef basic_chset<char_type> charset_type;
0228 charset_type charset(chset.base());
0229 if(icase)
0230 {
0231 charset_matcher<Traits, mpl::true_, charset_type> matcher(charset);
0232 merge_charset(matcher.charset_, chset, tr);
0233 return make_dynamic<BidiIter>(matcher);
0234 }
0235 else
0236 {
0237 charset_matcher<Traits, mpl::false_, charset_type> matcher(charset);
0238 merge_charset(matcher.charset_, chset, tr);
0239 return make_dynamic<BidiIter>(matcher);
0240 }
0241 }
0242
0243
0244 else if(chset.base().empty() && chset.posix_no().empty())
0245 {
0246 BOOST_ASSERT(0 != chset.posix_yes());
0247 posix_charset_matcher<Traits> matcher(chset.posix_yes(), chset.is_inverted());
0248 return make_dynamic<BidiIter>(matcher);
0249 }
0250
0251
0252 else
0253 {
0254 if(icase)
0255 {
0256 charset_matcher<Traits, mpl::true_> matcher(chset);
0257 return make_dynamic<BidiIter>(matcher);
0258 }
0259 else
0260 {
0261 charset_matcher<Traits, mpl::false_> matcher(chset);
0262 return make_dynamic<BidiIter>(matcher);
0263 }
0264 }
0265 }
0266
0267
0268
0269
0270 template<typename BidiIter, typename Traits>
0271 inline sequence<BidiIter> make_posix_charset_xpression
0272 (
0273 typename Traits::char_class_type m
0274 , bool no
0275 , regex_constants::syntax_option_type
0276 , Traits const &
0277 )
0278 {
0279 posix_charset_matcher<Traits> charset(m, no);
0280 return make_dynamic<BidiIter>(charset);
0281 }
0282
0283
0284
0285
0286 template<typename BidiIter, typename Traits>
0287 inline sequence<BidiIter> make_assert_begin_line
0288 (
0289 regex_constants::syntax_option_type flags
0290 , Traits const &tr
0291 )
0292 {
0293 if(0 != (regex_constants::single_line & flags))
0294 {
0295 return detail::make_dynamic<BidiIter>(detail::assert_bos_matcher());
0296 }
0297 else
0298 {
0299 detail::assert_bol_matcher<Traits> matcher(tr);
0300 return detail::make_dynamic<BidiIter>(matcher);
0301 }
0302 }
0303
0304
0305
0306
0307 template<typename BidiIter, typename Traits>
0308 inline sequence<BidiIter> make_assert_end_line
0309 (
0310 regex_constants::syntax_option_type flags
0311 , Traits const &tr
0312 )
0313 {
0314 if(0 != (regex_constants::single_line & flags))
0315 {
0316 return detail::make_dynamic<BidiIter>(detail::assert_eos_matcher());
0317 }
0318 else
0319 {
0320 detail::assert_eol_matcher<Traits> matcher(tr);
0321 return detail::make_dynamic<BidiIter>(matcher);
0322 }
0323 }
0324
0325
0326
0327
0328 template<typename BidiIter, typename Cond, typename Traits>
0329 inline sequence<BidiIter> make_assert_word(Cond, Traits const &tr)
0330 {
0331 return detail::make_dynamic<BidiIter>
0332 (
0333 detail::assert_word_matcher<Cond, Traits>(tr)
0334 );
0335 }
0336
0337
0338
0339
0340 template<typename BidiIter>
0341 inline sequence<BidiIter> make_independent_end_xpression(bool pure)
0342 {
0343 if(pure)
0344 {
0345 return detail::make_dynamic<BidiIter>(detail::true_matcher());
0346 }
0347 else
0348 {
0349 return detail::make_dynamic<BidiIter>(detail::independent_end_matcher());
0350 }
0351 }
0352
0353 }}}
0354
0355 #if defined(_MSC_VER)
0356 # pragma warning(pop)
0357 #endif
0358
0359 #endif