6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
13 * LOCATION: see http://www.boost.org for most recent version.
14 * FILE perl_matcher_common.cpp
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Definitions of perl_matcher member functions that are
17 * specific to the recursive implementation.
20 #ifndef BOOST_REGEX_V4_PERL_MATCHER_RECURSIVE_HPP
21 #define BOOST_REGEX_V4_PERL_MATCHER_RECURSIVE_HPP
25 #pragma warning(disable: 4103)
27 #ifdef BOOST_HAS_ABI_HEADERS
28 # include BOOST_ABI_PREFIX
36 #pragma warning(disable: 4800)
40 namespace BOOST_REGEX_DETAIL_NS{
42 template <class BidiIterator>
46 sub_match<BidiIterator> sub;
49 backup_subex(const match_results<BidiIterator, A>& w, int i)
50 : index(i), sub(w[i], false) {}
52 void restore(match_results<BidiIterator, A>& w)
54 w.set_first(sub.first, index, index == 0);
55 w.set_second(sub.second, index, sub.matched, index == 0);
57 const sub_match<BidiIterator>& get() { return sub; }
60 template <class BidiIterator, class Allocator, class traits>
61 bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
63 static matcher_proc_type const s_match_vtable[34] =
65 (&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
66 &perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
67 &perl_matcher<BidiIterator, Allocator, traits>::match_literal,
68 &perl_matcher<BidiIterator, Allocator, traits>::match_start_line,
69 &perl_matcher<BidiIterator, Allocator, traits>::match_end_line,
70 &perl_matcher<BidiIterator, Allocator, traits>::match_wild,
71 &perl_matcher<BidiIterator, Allocator, traits>::match_match,
72 &perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,
73 &perl_matcher<BidiIterator, Allocator, traits>::match_within_word,
74 &perl_matcher<BidiIterator, Allocator, traits>::match_word_start,
75 &perl_matcher<BidiIterator, Allocator, traits>::match_word_end,
76 &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,
77 &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,
78 &perl_matcher<BidiIterator, Allocator, traits>::match_backref,
79 &perl_matcher<BidiIterator, Allocator, traits>::match_long_set,
80 &perl_matcher<BidiIterator, Allocator, traits>::match_set,
81 &perl_matcher<BidiIterator, Allocator, traits>::match_jump,
82 &perl_matcher<BidiIterator, Allocator, traits>::match_alt,
83 &perl_matcher<BidiIterator, Allocator, traits>::match_rep,
84 &perl_matcher<BidiIterator, Allocator, traits>::match_combining,
85 &perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,
86 &perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,
87 // Although this next line *should* be evaluated at compile time, in practice
88 // some compilers (VC++) emit run-time initialisation which breaks thread
89 // safety, so use a dispatch function instead:
90 //(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),
91 &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_dispatch,
92 &perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,
93 &perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,
94 &perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,
95 &perl_matcher<BidiIterator, Allocator, traits>::match_backstep,
96 &perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref,
97 &perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case,
98 &perl_matcher<BidiIterator, Allocator, traits>::match_recursion,
99 &perl_matcher<BidiIterator, Allocator, traits>::match_fail,
100 &perl_matcher<BidiIterator, Allocator, traits>::match_accept,
101 &perl_matcher<BidiIterator, Allocator, traits>::match_commit,
102 &perl_matcher<BidiIterator, Allocator, traits>::match_then,
105 if(state_count > max_state_count)
106 raise_error(traits_inst, regex_constants::error_complexity);
109 matcher_proc_type proc = s_match_vtable[pstate->type];
113 if((m_match_flags & match_partial) && (position == last) && (position != search_base))
114 m_has_partial_match = true;
121 template <class BidiIterator, class Allocator, class traits>
122 bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
124 int index = static_cast<const re_brace*>(pstate)->index;
125 icase = static_cast<const re_brace*>(pstate)->icase;
130 pstate = pstate->next.p;
135 // forward lookahead assert:
136 BidiIterator old_position(position);
137 const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
138 pstate = pstate->next.p->next.p;
139 r = match_all_states();
140 pstate = next_pstate;
141 position = old_position;
142 if((r && (index != -1)) || (!r && (index != -2)))
146 if(r && m_have_accept)
147 r = skip_until_paren(INT_MAX);
152 // independent sub-expression:
153 bool old_independent = m_independent;
154 m_independent = true;
155 const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
156 pstate = pstate->next.p->next.p;
157 bool can_backtrack = m_can_backtrack;
158 r = match_all_states();
160 m_can_backtrack = can_backtrack;
161 pstate = next_pstate;
162 m_independent = old_independent;
163 #ifdef BOOST_REGEX_MATCH_EXTRA
164 if(r && (m_match_flags & match_extra))
167 // our captures have been stored in *m_presult
168 // we need to unpack them, and insert them
169 // back in the right order when we unwind the stack:
172 match_results<BidiIterator, Allocator> tm(*m_presult);
173 for(i = 0; i < tm.size(); ++i)
174 (*m_presult)[i].get_captures().clear();
175 // match everything else:
176 r = match_all_states();
177 // now place the stored captures back:
178 for(i = 0; i < tm.size(); ++i)
180 typedef typename sub_match<BidiIterator>::capture_sequence_type seq;
181 seq& s1 = (*m_presult)[i].get_captures();
182 const seq& s2 = tm[i].captures();
190 if(r && m_have_accept)
191 r = skip_until_paren(INT_MAX);
196 // conditional expression:
197 const re_alt* alt = static_cast<const re_alt*>(pstate->next.p);
198 BOOST_ASSERT(alt->type == syntax_element_alt);
199 pstate = alt->next.p;
200 if(pstate->type == syntax_element_assert_backref)
202 if(!match_assert_backref())
208 // zero width assertion, have to match this recursively:
209 BOOST_ASSERT(pstate->type == syntax_element_startmark);
210 bool negated = static_cast<const re_brace*>(pstate)->index == -2;
211 BidiIterator saved_position = position;
212 const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
213 pstate = pstate->next.p->next.p;
214 bool res = match_all_states();
215 position = saved_position;
219 pstate = next_pstate;
227 // Reset start of $0, since we have a \K escape
228 backup_subex<BidiIterator> sub(*m_presult, 0);
229 m_presult->set_first(position, 0, true);
230 pstate = pstate->next.p;
231 r = match_all_states();
233 sub.restore(*m_presult);
238 BOOST_ASSERT(index > 0);
239 if((m_match_flags & match_nosubs) == 0)
241 backup_subex<BidiIterator> sub(*m_presult, index);
242 m_presult->set_first(position, index);
243 pstate = pstate->next.p;
244 r = match_all_states();
246 sub.restore(*m_presult);
247 #ifdef BOOST_REGEX_MATCH_EXTRA
249 // we have a match, push the capture information onto the stack:
251 else if(sub.get().matched && (match_extra & m_match_flags))
252 ((*m_presult)[index]).get_captures().push_back(sub.get());
257 pstate = pstate->next.p;
265 template <class BidiIterator, class Allocator, class traits>
266 bool perl_matcher<BidiIterator, Allocator, traits>::match_alt()
268 bool take_first, take_second;
269 const re_alt* jmp = static_cast<const re_alt*>(pstate);
271 // find out which of these two alternatives we need to take:
274 take_first = jmp->can_be_null & mask_take;
275 take_second = jmp->can_be_null & mask_skip;
279 take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);
280 take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);
285 // we can take the first alternative,
286 // see if we need to push next alternative:
289 BidiIterator oldposition(position);
290 const re_syntax_base* old_pstate = jmp->alt.p;
291 pstate = pstate->next.p;
293 if(!match_all_states())
296 position = oldposition;
299 m_can_backtrack = true;
305 return m_can_backtrack;
307 pstate = pstate->next.p;
315 return false; // neither option is possible
318 template <class BidiIterator, class Allocator, class traits>
319 bool perl_matcher<BidiIterator, Allocator, traits>::match_rep()
322 #pragma warning(push)
323 #pragma warning(disable:4127 4244)
325 const re_repeat* rep = static_cast<const re_repeat*>(pstate);
327 // Always copy the repeat count, so that the state is restored
328 // when we exit this scope:
330 repeater_count<BidiIterator> r(rep->state_id, &next_count, position, this->recursion_stack.size() ? this->recursion_stack.back().idx : INT_MIN + 3);
332 // If we've had at least one repeat already, and the last one
333 // matched the NULL string then set the repeat count to
336 next_count->check_null_repeat(position, rep->max);
338 // find out which of these two alternatives we need to take:
339 bool take_first, take_second;
342 take_first = rep->can_be_null & mask_take;
343 take_second = rep->can_be_null & mask_skip;
347 take_first = can_start(*position, rep->_map, (unsigned char)mask_take);
348 take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);
351 if(next_count->get_count() < rep->min)
353 // we must take the repeat:
356 // increase the counter:
358 pstate = rep->next.p;
359 return match_all_states();
363 bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
366 // try and take the repeat if we can:
367 if((next_count->get_count() < rep->max) && take_first)
369 // store position in case we fail:
370 BidiIterator pos = position;
371 // increase the counter:
373 pstate = rep->next.p;
374 if(match_all_states())
378 // failed repeat, reset posistion and fall through for alternative:
386 return false; // can't take anything, fail...
390 // try and skip the repeat if we can:
393 // store position in case we fail:
394 BidiIterator pos = position;
396 if(match_all_states())
400 // failed alternative, reset posistion and fall through for repeat:
403 if((next_count->get_count() < rep->max) && take_first)
405 // increase the counter:
407 pstate = rep->next.p;
408 return match_all_states();
417 template <class BidiIterator, class Allocator, class traits>
418 bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()
421 #pragma warning(push)
422 #pragma warning(disable:4127)
425 const re_repeat* rep = static_cast<const re_repeat*>(pstate);
426 re_syntax_base* psingle = rep->next.p;
427 // match compulsary repeats first:
428 while(count < rep->min)
435 bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
439 while(count < rep->max)
446 if((rep->leading) && (count < rep->max))
449 return backtrack_till_match(count - rep->min);
453 // non-greedy, keep trying till we get a match:
454 BidiIterator save_pos;
457 if((rep->leading) && (rep->max == UINT_MAX))
462 if(match_all_states())
464 if((count >= rep->max) || !m_can_backtrack)
478 template <class BidiIterator, class Allocator, class traits>
479 bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
482 #pragma warning(push)
483 #pragma warning(disable:4127)
485 if(m_match_flags & match_not_dot_null)
486 return match_dot_repeat_slow();
487 if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)
488 return match_dot_repeat_slow();
490 // start by working out how much we can skip:
492 const re_repeat* rep = static_cast<const re_repeat*>(pstate);
494 #pragma warning(push)
495 #pragma warning(disable:4267)
497 bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
498 std::size_t count = (std::min)(static_cast<std::size_t>(::boost::BOOST_REGEX_DETAIL_NS::distance(position, last)), static_cast<std::size_t>(greedy ? rep->max : rep->min));
502 return false; // not enough text left to match
504 std::advance(position, count);
508 if((rep->leading) && (count < rep->max) && greedy)
511 return backtrack_till_match(count - rep->min);
513 // non-greedy, keep trying till we get a match:
514 BidiIterator save_pos;
517 while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
522 if((rep->leading) && (rep->max == UINT_MAX))
527 if(match_all_states())
529 if((count >= rep->max) || !m_can_backtrack)
533 position = ++save_pos;
541 template <class BidiIterator, class Allocator, class traits>
542 bool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()
545 #pragma warning(push)
546 #pragma warning(disable:4127)
547 #pragma warning(disable:4267)
550 #pragma option push -w-8008 -w-8066 -w-8004
552 const re_repeat* rep = static_cast<const re_repeat*>(pstate);
553 BOOST_ASSERT(1 == static_cast<const re_literal*>(rep->next.p)->length);
554 const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(rep->next.p) + 1);
556 // start by working out how much we can skip:
558 bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
559 std::size_t count, desired;
560 if(::boost::is_random_access_iterator<BidiIterator>::value)
564 (std::size_t)(greedy ? rep->max : rep->min),
565 (std::size_t)::boost::BOOST_REGEX_DETAIL_NS::distance(position, last));
570 while(--desired && (traits_inst.translate_nocase(*position) == what))
577 while(--desired && (traits_inst.translate(*position) == what))
582 count = count - desired;
587 desired = greedy ? rep->max : rep->min;
588 while((count < desired) && (position != last) && (traits_inst.translate(*position, icase) == what))
594 if((rep->leading) && (count < rep->max) && greedy)
600 return backtrack_till_match(count - rep->min);
602 // non-greedy, keep trying till we get a match:
603 BidiIterator save_pos;
606 while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
608 if((traits_inst.translate(*position, icase) == what))
614 return false; // counldn't repeat even though it was the only option
616 if((rep->leading) && (rep->max == UINT_MAX))
621 if(match_all_states())
623 if((count >= rep->max) || !m_can_backtrack)
628 if(traits_inst.translate(*position, icase) == what)
646 template <class BidiIterator, class Allocator, class traits>
647 bool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()
650 #pragma warning(push)
651 #pragma warning(disable:4127)
654 #pragma option push -w-8008 -w-8066 -w-8004
656 const re_repeat* rep = static_cast<const re_repeat*>(pstate);
657 const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;
660 // start by working out how much we can skip:
662 bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
663 std::size_t desired = greedy ? rep->max : rep->min;
664 if(::boost::is_random_access_iterator<BidiIterator>::value)
666 BidiIterator end = position;
667 // Move end forward by "desired", preferably without using distance or advance if we can
668 // as these can be slow for some iterator types.
669 std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : ::boost::BOOST_REGEX_DETAIL_NS::distance(position, last);
673 std::advance(end, desired);
674 BidiIterator origin(position);
675 while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
679 count = (unsigned)::boost::BOOST_REGEX_DETAIL_NS::distance(origin, position);
683 while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
689 if((rep->leading) && (count < rep->max) && greedy)
695 return backtrack_till_match(count - rep->min);
697 // non-greedy, keep trying till we get a match:
698 BidiIterator save_pos;
701 while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
703 if(map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
709 return false; // counldn't repeat even though it was the only option
711 if((rep->leading) && (rep->max == UINT_MAX))
716 if(match_all_states())
718 if((count >= rep->max) || !m_can_backtrack)
723 if(map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
741 template <class BidiIterator, class Allocator, class traits>
742 bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
745 #pragma warning(push)
746 #pragma warning(disable:4127)
749 #pragma option push -w-8008 -w-8066 -w-8004
751 typedef typename traits::char_class_type char_class_type;
752 const re_repeat* rep = static_cast<const re_repeat*>(pstate);
753 const re_set_long<char_class_type>* set = static_cast<const re_set_long<char_class_type>*>(pstate->next.p);
756 // start by working out how much we can skip:
758 bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
759 std::size_t desired = greedy ? rep->max : rep->min;
760 if(::boost::is_random_access_iterator<BidiIterator>::value)
762 BidiIterator end = position;
763 // Move end forward by "desired", preferably without using distance or advance if we can
764 // as these can be slow for some iterator types.
765 std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : ::boost::BOOST_REGEX_DETAIL_NS::distance(position, last);
769 std::advance(end, desired);
770 BidiIterator origin(position);
771 while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
775 count = (unsigned)::boost::BOOST_REGEX_DETAIL_NS::distance(origin, position);
779 while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
785 if((rep->leading) && (count < rep->max) && greedy)
791 return backtrack_till_match(count - rep->min);
793 // non-greedy, keep trying till we get a match:
794 BidiIterator save_pos;
797 while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
799 if(position != re_is_set_member(position, last, set, re.get_data(), icase))
805 return false; // counldn't repeat even though it was the only option
807 if((rep->leading) && (rep->max == UINT_MAX))
812 if(match_all_states())
814 if((count >= rep->max) || !m_can_backtrack)
819 if(position != re_is_set_member(position, last, set, re.get_data(), icase))
837 template <class BidiIterator, class Allocator, class traits>
838 bool perl_matcher<BidiIterator, Allocator, traits>::backtrack_till_match(std::size_t count)
841 #pragma warning(push)
842 #pragma warning(disable:4127)
846 if((m_match_flags & match_partial) && (position == last))
847 m_has_partial_match = true;
849 const re_repeat* rep = static_cast<const re_repeat*>(pstate);
850 BidiIterator backtrack = position;
853 if(rep->can_be_null & mask_skip)
856 if(match_all_states())
861 position = --backtrack;
869 while(count && !can_start(*position, rep->_map, mask_skip))
876 backtrack = position;
877 if(match_all_states())
881 position = --backtrack;
890 template <class BidiIterator, class Allocator, class traits>
891 bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()
893 BOOST_ASSERT(pstate->type == syntax_element_recurse);
895 // Set new call stack:
897 if(recursion_stack.capacity() == 0)
899 recursion_stack.reserve(50);
901 recursion_stack.push_back(recursion_info<results_type>());
902 recursion_stack.back().preturn_address = pstate->next.p;
903 recursion_stack.back().results = *m_presult;
904 recursion_stack.back().repeater_stack = next_count;
905 pstate = static_cast<const re_jump*>(pstate)->alt.p;
906 recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index;
908 repeater_count<BidiIterator>* saved = next_count;
909 repeater_count<BidiIterator> r(&next_count); // resets all repeat counts since we're recursing and starting fresh on those
911 bool can_backtrack = m_can_backtrack;
912 bool result = match_all_states();
913 m_can_backtrack = can_backtrack;
918 next_count = recursion_stack.back().repeater_stack;
919 *m_presult = recursion_stack.back().results;
920 recursion_stack.pop_back();
926 template <class BidiIterator, class Allocator, class traits>
927 bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()
929 int index = static_cast<const re_brace*>(pstate)->index;
930 icase = static_cast<const re_brace*>(pstate)->icase;
933 if((m_match_flags & match_nosubs) == 0)
935 m_presult->set_second(position, index);
937 if(!recursion_stack.empty())
939 if(index == recursion_stack.back().idx)
941 recursion_info<results_type> saved = recursion_stack.back();
942 recursion_stack.pop_back();
943 pstate = saved.preturn_address;
944 repeater_count<BidiIterator>* saved_count = next_count;
945 next_count = saved.repeater_stack;
946 *m_presult = saved.results;
947 if(!match_all_states())
949 recursion_stack.push_back(saved);
950 next_count = saved_count;
956 else if((index < 0) && (index != -4))
958 // matched forward lookahead:
962 pstate = pstate ? pstate->next.p : 0;
966 template <class BidiIterator, class Allocator, class traits>
967 bool perl_matcher<BidiIterator, Allocator, traits>::match_match()
969 if(!recursion_stack.empty())
971 BOOST_ASSERT(0 == recursion_stack.back().idx);
972 const re_syntax_base* saved_state = pstate = recursion_stack.back().preturn_address;
973 *m_presult = recursion_stack.back().results;
974 recursion_stack.pop_back();
975 if(!match_all_states())
977 recursion_stack.push_back(recursion_info<results_type>());
978 recursion_stack.back().preturn_address = saved_state;
979 recursion_stack.back().results = *m_presult;
984 if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))
986 if((m_match_flags & match_all) && (position != last))
988 if((m_match_flags & regex_constants::match_not_initial_null) && (position == search_base))
990 m_presult->set_second(position);
992 m_has_found_match = true;
993 if((m_match_flags & match_posix) == match_posix)
995 m_result.maybe_assign(*m_presult);
996 if((m_match_flags & match_any) == 0)
999 #ifdef BOOST_REGEX_MATCH_EXTRA
1000 if(match_extra & m_match_flags)
1002 for(unsigned i = 0; i < m_presult->size(); ++i)
1003 if((*m_presult)[i].matched)
1004 ((*m_presult)[i]).get_captures().push_back((*m_presult)[i]);
1010 template <class BidiIterator, class Allocator, class traits>
1011 bool perl_matcher<BidiIterator, Allocator, traits>::match_commit()
1013 m_can_backtrack = false;
1014 int action = static_cast<const re_commit*>(pstate)->action;
1024 pstate = pstate->next.p;
1028 template <class BidiIterator, class Allocator, class traits>
1029 bool perl_matcher<BidiIterator, Allocator, traits>::match_then()
1031 pstate = pstate->next.p;
1032 if(match_all_states())
1034 m_can_backtrack = false;
1039 template <class BidiIterator, class Allocator, class traits>
1040 bool perl_matcher<BidiIterator, Allocator, traits>::skip_until_paren(int index, bool have_match)
1044 if(pstate->type == syntax_element_endmark)
1046 if(static_cast<const re_brace*>(pstate)->index == index)
1049 return this->match_endmark();
1050 pstate = pstate->next.p;
1055 // Unenclosed closing ), occurs when (*ACCEPT) is inside some other
1056 // parenthesis which may or may not have other side effects associated with it.
1057 bool r = match_endmark();
1058 m_have_accept = true;
1064 else if(pstate->type == syntax_element_match)
1066 else if(pstate->type == syntax_element_startmark)
1068 int idx = static_cast<const re_brace*>(pstate)->index;
1069 pstate = pstate->next.p;
1070 skip_until_paren(idx, false);
1073 pstate = pstate->next.p;
1079 } // namespace BOOST_REGEX_DETAIL_NS
1080 } // namespace boost
1082 #pragma warning(pop)
1086 #pragma warning(push)
1087 #pragma warning(disable: 4103)
1089 #ifdef BOOST_HAS_ABI_HEADERS
1090 # include BOOST_ABI_SUFFIX
1093 #pragma warning(pop)