00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00026
00038
00039
00040 #ifndef _CTTL_POLICY_H_INCLUDED_
00041 #define _CTTL_POLICY_H_INCLUDED_
00042
00043 #include "xtl_region_map.h"
00044
00045 namespace cttl {
00046
00047 using namespace cttl_impl;
00048
00050 const int flag_follow_space = 1;
00051
00053 const int flag_follow_region = 2;
00054
00056 const int flag_greedy = 4;
00057
00059 const int flag_cpp_comments = 8;
00060
00062 const int flag_follow_either = flag_follow_space | flag_follow_region;
00063
00068 class policy_mapped_space
00069 {
00070 protected:
00072 xtl_region_map m_region_map;
00073
00074 public:
00081 typedef policy_default strict_policy_T;
00082
00111 template< typename ExprT, typename SubstrT >
00112 size_t match( xtl_wrap< ExprT > derived_expr_, SubstrT& substr_ )
00113 {
00114 for( ;; ) {
00115 if ( derived_expr_.match( substr_ ) != SubstrT::string_T::npos ) {
00116
00117 if ( lower_bound( substr_.first.offset(), substr_ ) )
00118
00119 continue;
00120 else
00121
00122 break;
00123 }
00124
00125
00126 if ( lower_bound( substr_.first.offset(), substr_ ) )
00127
00128 continue;
00129
00130
00131 break;
00132 }
00133
00134
00135 return substr_.first.offset();
00136 }
00137
00158 template< typename SubstrT >
00159 bool lower_bound( size_t start_offset_, SubstrT& substr_ )
00160 {
00161 size_t adjusted_offset = lower_bound( start_offset_, substr_.second.offset() );
00162 if ( adjusted_offset != start_offset_ ) {
00163 substr_.first.offset( adjusted_offset );
00164 return true;
00165 }
00166
00167 return false;
00168 }
00169
00185 size_t lower_bound( size_t offset_, size_t substr_length_ )
00186 {
00187 return m_region_map.find_not_region( offset_, substr_length_ );
00188 }
00189
00202 template< typename StringT, typename CharT >
00203 void text_insert_go( node< StringT >& node_, CharT const* pchar_ )
00204 {
00205 text_insert_go( node_, StringT( pchar_ ) );
00206 }
00207
00220 template< typename StringT >
00221 void text_insert_go( node< StringT >& node_, StringT const& str_ )
00222 {
00223 size_t str_length = str_.length();
00224
00225 if ( !str_.length() )
00226 return;
00227
00228 size_t insertion_offset = node_.offset();
00229
00230 node_.parent().insert(
00231 insertion_offset,
00232 str_
00233 );
00234
00235 m_region_map.adjust(
00236 insertion_offset,
00237 int( str_length )
00238 );
00239
00240 xtl_identity_insert_go< StringT > insert_go(
00241 insertion_offset,
00242 int( str_length )
00243 );
00244
00245 node_.adjust( insert_go );
00246 }
00247
00261 template< typename StringT, typename PolicyT >
00262 void text_insert_go( node< StringT >& node_target_, const_edge< PolicyT, StringT > const& edge_source_ )
00263 {
00264 StringT const& str = edge_source_.parent();
00265 size_t source_from_offset_ = edge_source_.first.offset();
00266 size_t source_to_offset_ = edge_source_.second.offset();
00267
00268 size_t str_length = source_to_offset_ - source_from_offset_;
00269
00270 if ( !str.length() )
00271 return;
00272
00273 size_t insertion_offset = node_target_.offset();
00274
00275 node_target_.parent().insert(
00276 insertion_offset,
00277 str,
00278 source_from_offset_,
00279 str_length
00280 );
00281
00282 m_region_map.adjust(
00283 insertion_offset,
00284 int( str_length )
00285 );
00286
00287 xtl_identity_insert_go< StringT > insert_go(
00288 insertion_offset,
00289 int( str_length )
00290 );
00291
00292 node_target_.adjust( insert_go );
00293 }
00294
00295
00308 template< typename StringT, typename CharT >
00309 void text_insert_stay( node< StringT >& node_, CharT const* pchar_ )
00310 {
00311 text_insert_stay( node_, StringT( pchar_ ) );
00312 }
00313
00326 template< typename StringT >
00327 void text_insert_stay( node< StringT >& node_, StringT const& str_ )
00328 {
00329 size_t str_length = str_.length();
00330
00331 if ( !str_length )
00332 return;
00333
00334 size_t insertion_offset = node_.offset();
00335
00336 node_.parent().insert(
00337 insertion_offset,
00338 str_
00339 );
00340
00341 m_region_map.adjust(
00342 insertion_offset,
00343 int( str_length )
00344 );
00345
00346 xtl_identity_insert_stay< StringT > insert_stay(
00347 insertion_offset,
00348 int( str_length )
00349 );
00350
00351 node_.adjust( insert_stay );
00352 }
00353
00354
00367 template< typename StringT, typename PolicyT >
00368 void text_insert_stay( node< StringT >& node_target_, const_edge< PolicyT, StringT > const& edge_source_ )
00369 {
00370 StringT const& str = edge_source_.parent();
00371 size_t source_from_offset_ = edge_source_.first.offset();
00372 size_t source_to_offset_ = edge_source_.second.offset();
00373
00374 size_t str_length = source_to_offset_ - source_from_offset_;
00375
00376 if ( !str_length )
00377 return;
00378
00379 size_t insertion_offset = node_target_.offset();
00380
00381 node_target_.parent().insert(
00382 insertion_offset,
00383 str,
00384 source_from_offset_,
00385 str_length
00386 );
00387
00388 m_region_map.adjust(
00389 insertion_offset,
00390 int( str_length )
00391 );
00392
00393 xtl_identity_insert_stay< StringT > insert_stay(
00394 insertion_offset,
00395 int( str_length )
00396 );
00397
00398 node_target_.adjust( insert_stay );
00399 }
00400
00402 void region_clear()
00403 {
00404 m_region_map.clear();
00405 }
00406
00411 void region_adjust( size_t after_offset_, int delta_offset_ )
00412 {
00413 m_region_map.adjust( after_offset_, delta_offset_ );
00414 }
00415
00417 void region_insert( size_t first_offset_, size_t second_offset_ )
00418 {
00419 m_region_map.insert(
00420 first_offset_,
00421 second_offset_
00422 );
00423 }
00424
00426 void region_erase( size_t first_offset_, size_t second_offset_ )
00427 {
00428 m_region_map.erase(
00429 first_offset_,
00430 second_offset_
00431 );
00432 }
00433
00441 template< typename StringT >
00442 StringT region_difference( StringT const& str_, size_t first_offset_, size_t second_offset_ )
00443 {
00444 return m_region_map.text_difference(
00445 str_,
00446 first_offset_,
00447 second_offset_
00448 );
00449 }
00450
00451 };
00452
00459 template< int White_spaceT = flag_follow_space >
00460 struct policy_space
00461 {
00462 };
00463
00468 template<>
00469 struct policy_space< flag_follow_space > : public policy_default
00470 {
00495 template< typename SubstrT >
00496 static size_t match( SubstrT& substr_ )
00497 {
00498 CTTL_TRACE_SILENT( true );
00499 typedef typename SubstrT::char_T char_T;
00500 size_t ungreedy_offset = substr_.first.offset();
00501 (
00502 true
00503 ^
00504 +(
00505 symbol( char_T( ' ' ) )
00506 |
00507 symbol( char_T( '\n' ) )
00508 |
00509 symbol( char_T( '\r' ) )
00510 |
00511 symbol( char_T( '\t' ) )
00512 |
00513 symbol( char_T( '\v' ) )
00514 |
00515 symbol( char_T( '\f' ) )
00516 )
00517 ).match( substr_ );
00518
00519 return ungreedy_offset;
00520 }
00521 };
00522
00542 template<>
00543 struct policy_space< flag_follow_region > : public policy_mapped_space
00544 {
00570 template< typename SubstrT >
00571 size_t match( SubstrT& substr_ )
00572 {
00573 size_t ungreedy_offset = substr_.first.offset();
00574 lower_bound( ungreedy_offset, substr_ );
00575
00576 return ungreedy_offset;
00577 }
00578 };
00579
00580
00585 template<>
00586 struct policy_space< flag_follow_space | flag_follow_region > : public policy_space< flag_follow_region >
00587 {
00615 template< typename SubstrT >
00616 size_t match( SubstrT& substr_ )
00617 {
00618 CTTL_TRACE_SILENT( true );
00619 typedef typename SubstrT::char_T char_T;
00620 size_t ungreedy_offset = substr_.first.offset();
00621 policy_mapped_space::match(
00622 true
00623 ^
00624 +(
00625 symbol( char_T( ' ' ) )
00626 |
00627 symbol( char_T( '\n' ) )
00628 |
00629 symbol( char_T( '\r' ) )
00630 |
00631 symbol( char_T( '\t' ) )
00632 |
00633 symbol( char_T( '\v' ) )
00634 |
00635 symbol( char_T( '\f' ) )
00636 ),
00637 substr_
00638 );
00639
00640 return ungreedy_offset;
00641 }
00642 };
00643
00644
00652 template<>
00653 struct policy_space< flag_greedy | flag_follow_space > : public policy_space< flag_follow_space >
00654 {
00679 template< typename SubstrT >
00680 static size_t match( SubstrT& substr_ )
00681 {
00682 CTTL_TRACE_SILENT( true );
00683 typedef typename SubstrT::char_T char_T;
00684 (
00685 true
00686 ^
00687 +(
00688 symbol( char_T( ' ' ) )
00689 |
00690 symbol( char_T( '\n' ) )
00691 |
00692 symbol( char_T( '\r' ) )
00693 |
00694 symbol( char_T( '\t' ) )
00695 |
00696 symbol( char_T( '\v' ) )
00697 |
00698 symbol( char_T( '\f' ) )
00699 )
00700 ).match( substr_ );
00701
00702 return substr_.first.offset();
00703 }
00704 };
00705
00706
00713 template<>
00714 struct policy_space< flag_greedy > : public policy_space< flag_greedy | flag_follow_space >
00715 {
00716 };
00717
00718
00725 template<>
00726 struct policy_space< flag_greedy | flag_follow_region > : public policy_space< flag_follow_region >
00727 {
00753 template< typename SubstrT >
00754 size_t match( SubstrT& substr_ )
00755 {
00756 lower_bound( substr_.first.offset(), substr_ );
00757
00758 return substr_.first.offset();
00759 }
00760 };
00761
00762
00770 template<>
00771 struct policy_space< flag_greedy | flag_follow_space | flag_follow_region > : public policy_space< flag_follow_space | flag_follow_region >
00772 {
00799 template< typename SubstrT >
00800 size_t match( SubstrT& substr_ )
00801 {
00802 CTTL_TRACE_SILENT( true );
00803 typedef typename SubstrT::char_T char_T;
00804 policy_mapped_space::match(
00805 true
00806 ^
00807 +(
00808 symbol( char_T( ' ' ) )
00809 |
00810 symbol( char_T( '\n' ) )
00811 |
00812 symbol( char_T( '\r' ) )
00813 |
00814 symbol( char_T( '\t' ) )
00815 |
00816 symbol( char_T( '\v' ) )
00817 |
00818 symbol( char_T( '\f' ) )
00819 ),
00820 substr_
00821 );
00822
00823 return substr_.first.offset();
00824 }
00825 };
00826
00827
00835 template<>
00836 struct policy_space< flag_cpp_comments > : public policy_default
00837 {
00863 template< typename SubstrT >
00864 static size_t match( SubstrT& substr_ )
00865 {
00866 CTTL_TRACE_SILENT( true );
00867 size_t ungreedy_offset = substr_.first.offset();
00868 (
00869 true ^ rule( policy_space< flag_cpp_comments >::space_and_comment )
00870
00871 ).match( substr_ );
00872
00873
00874 return ungreedy_offset;
00875 }
00876
00888 static size_t space_and_comment( const_edge< policy_default, CTTL_STD_STRING >& substr_ )
00889 {
00890 return (
00891 (
00892 entity( isspace )
00893 +
00894 (
00895 (
00896 rule( policy_space< flag_cpp_comments >::comment )
00897 +
00898 rule( policy_space< flag_cpp_comments >::space_and_comment )
00899 )
00900 |
00901 begin( true )
00902 )
00903 )
00904 |
00905 (
00906 rule( policy_space< flag_cpp_comments >::comment )
00907 +
00908 (
00909 rule( policy_space< flag_cpp_comments >::space_and_comment )
00910 |
00911 begin( true )
00912 )
00913 )
00914 |
00915 begin( true )
00916
00917 ).match( substr_ );
00918 }
00919
00931 static size_t comment( const_edge< policy_default, CTTL_STD_STRING >& substr_ )
00932 {
00933 typedef const_edge< policy_default, CTTL_STD_STRING >::char_T char_T;
00934 return (
00935 begin( char_T( '/' ) )
00936 +
00937 (
00938 ( symbol( char_T( '/' ) ) + symbol( char_T( '/' ) ) + !begin( symbol( char_T( '\n' ) ) | end() ) )
00939 |
00940 ( symbol( char_T( '/' ) ) + symbol( char_T( '*' ) ) + !!( symbol( char_T( '*' ) ) + symbol( char_T( '/' ) ) ) )
00941 )
00942 ).match( substr_ );
00943 }
00944
00945 };
00946
00947
00955 template<>
00956 struct policy_space< flag_greedy | flag_cpp_comments > : public policy_space< flag_cpp_comments >
00957 {
00983 template< typename SubstrT >
00984 static size_t match( SubstrT& substr_ )
00985 {
00986 policy_space< flag_cpp_comments >::match( substr_ );
00987 return substr_.first.offset();
00988 }
00989 };
00990
00991 }
00992
00993 #endif // _CTTL_POLICY_H_INCLUDED_