00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00023
00070
00071
00072 #ifndef _CTTL_XTL_PRIMARY_H_INCLUDED_
00073 #define _CTTL_XTL_PRIMARY_H_INCLUDED_
00074
00075 #include <set>
00076
00077 namespace cttl_impl {
00078
00108 template< typename DerivedT >
00109 struct xtl_primary {
00110
00135 template< typename UniverseT >
00136 size_t match( UniverseT& edge_ )
00137 {
00138
00139 size_t saved_first_offset = edge_.space_policy().match( edge_ );
00140
00141 if ( edge_.length() <= 0 ) {
00142
00143 edge_.first.offset( saved_first_offset );
00144 CTTL_TRACE_TEXT_RESULT( false, 'L', "empty universe" );
00145 return UniverseT::string_T::npos;
00146 }
00147
00148
00149
00150 size_t match_offset = static_cast< DerivedT* >( this )->internal_match( edge_ );
00151
00152 if ( match_offset == UniverseT::string_T::npos ) {
00153
00154
00155 edge_.first.offset( saved_first_offset );
00156 return UniverseT::string_T::npos;
00157 }
00158
00159 if ( edge_.length() < 0 ) {
00160
00161
00162 edge_.first.offset( saved_first_offset );
00163 CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme match out-of-universe bounds" );
00164 return UniverseT::string_T::npos;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 if ( primary_length( match_offset, edge_.first.offset() ) ) {
00177
00178 size_t offset_minus_one = edge_.first.offset() - 1;
00179 if ( offset_minus_one != edge_.space_policy().lower_bound( offset_minus_one, edge_.second.offset() ) ) {
00180
00181
00182
00183
00184 edge_.first.offset( saved_first_offset );
00185 CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme match inside void space" );
00186 return UniverseT::string_T::npos;
00187 }
00188 }
00189
00190
00191 return match_offset;
00192 }
00193
00218 template< typename UniverseT >
00219 size_t find( UniverseT& edge_ )
00220 {
00221 size_t saved_first_offset = edge_.first.offset();
00222
00223 replay_find:
00224 if ( edge_.length() <= 0 ) {
00225
00226
00227 edge_.first.offset( saved_first_offset );
00228 CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme find: invalid universe" );
00229 return UniverseT::string_T::npos;
00230 }
00231
00232 size_t offset_before_replay = edge_.first.offset();
00233 size_t match_offset = static_cast< DerivedT* >( this )->internal_find( edge_ );
00234
00235 if ( match_offset == UniverseT::string_T::npos ) {
00236
00237
00238 edge_.first.offset( saved_first_offset );
00239 return UniverseT::string_T::npos;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 if ( edge_.length() < 0 ) {
00251
00252
00253 edge_.first.offset( saved_first_offset );
00254 CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme find: out-of-universe bounds" );
00255 return UniverseT::string_T::npos;
00256 }
00257
00258
00259
00260
00261 if ( edge_.space_policy().lower_bound( match_offset, edge_ ) ) {
00262
00263
00264
00265 if ( offset_before_replay < edge_.first.offset() )
00266 goto replay_find;
00267
00268 edge_.first.offset( saved_first_offset );
00269 CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme find: lower bound inside void region" );
00270 return UniverseT::string_T::npos;
00271 }
00272
00273 if ( primary_length( match_offset, edge_.first.offset() )
00274 &&
00275 edge_.space_policy().lower_bound( edge_.first.offset() - 1, edge_ ) )
00276 {
00277
00278
00279
00280 if ( offset_before_replay < edge_.first.offset() )
00281 goto replay_find;
00282
00283 edge_.first.offset( saved_first_offset );
00284 CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme find: upper bound inside void region" );
00285 return UniverseT::string_T::npos;
00286 }
00287
00288
00289 return match_offset;
00290 }
00291
00320 template< typename UniverseT >
00321 size_t bang_find( UniverseT& edge_ )
00322 {
00323 return find( edge_ );
00324 }
00325
00326 protected:
00339 int primary_length( size_t upper_offset_, size_t lower_offset_ ) const
00340 {
00341 return lower_offset_ - upper_offset_;
00342 }
00343
00344 };
00345
00371 template< bool accept_emty_universe = false >
00372 class xtl_bool {
00373
00374 private:
00375 bool m_value;
00376
00377 public:
00378
00379
00381 xtl_bool( bool value_ )
00382 : m_value( value_ )
00383 {
00384 }
00385
00386
00387
00407 template< typename UniverseT >
00408 size_t match( UniverseT& edge_ )
00409 {
00410 if ( !accept_emty_universe && m_value && !edge_.length() ) {
00411 CTTL_TRACE_TEXT_RESULT( false, char( '0' + int( m_value ) ), "epsilon match: empty universe" );
00412 return UniverseT::string_T::npos;
00413 }
00414
00415 return internal_match( edge_ );
00416 }
00417
00437 template< typename UniverseT >
00438 size_t find( UniverseT& edge_ )
00439 {
00440 return internal_match( edge_ );
00441 }
00442
00462 template< typename UniverseT >
00463 size_t bang_find( UniverseT& edge_ )
00464 {
00465 return internal_match( edge_ );
00466 }
00467
00486 template< typename UniverseT >
00487 size_t internal_match( UniverseT& edge_ )
00488 {
00489 typedef typename UniverseT::char_T char_T;
00490
00491
00492 if ( m_value ) {
00493 CTTL_TRACE_RESULT( true, char( '0' + int( m_value ) ) );
00494 return edge_.first.offset();
00495 } else {
00496 CTTL_TRACE_RESULT( false, char( '0' + int( m_value ) ) );
00497 return UniverseT::string_T::npos;
00498 }
00499 }
00500
00501 };
00502
00503
00515 template< typename StringT >
00516 class xtl_keyword {
00517
00518 private:
00519 std::set< StringT > const& m_keywords;
00520
00521 public:
00522
00523
00525 xtl_keyword( std::set< StringT > const& keywords_ )
00526 : m_keywords( keywords_ )
00527 {
00528 }
00529
00531 void operator=( xtl_keyword< StringT > const& ) const
00532 {
00533 }
00534
00535
00536
00556 template< typename UniverseT >
00557 size_t match( UniverseT const& edge_ ) const
00558 {
00559
00560
00561 if ( m_keywords.find( edge_.text() ) != m_keywords.end() ) {
00562 CTTL_TRACE_RESULT( true, 'S' );
00563 return edge_.first.offset();
00564 }
00565
00566 CTTL_TRACE_RESULT( false, 'S' );
00567 return UniverseT::string_T::npos;
00568 }
00569
00570 };
00571
00572
00580 class xtl_char_symbol : public xtl_primary< xtl_char_symbol > {
00581
00582 public:
00583
00584
00585
00615 template< typename UniverseT >
00616 size_t find( UniverseT& edge_ )
00617 {
00618 return xtl_primary< xtl_char_symbol >::match( edge_ );
00619 }
00620
00650 template< typename UniverseT >
00651 size_t bang_find( UniverseT& edge_ )
00652 {
00653 return xtl_primary< xtl_char_symbol >::match( edge_ );
00654 }
00655
00686 template< typename UniverseT >
00687 size_t internal_match( UniverseT& edge_ )
00688 {
00689
00690
00691 size_t match_offset = edge_.first.offset();
00692
00693 edge_.first.offset( match_offset + 1 );
00694 CTTL_TRACE_TEXT_RESULT( true, edge_.first[ -1 ], "symbol" );
00695 return match_offset;
00696 }
00697
00698 };
00699
00700
00711 template< typename CharT >
00712 class xtl_char : public xtl_primary< xtl_char< CharT > > {
00713
00714 private:
00716 CharT m_char;
00717
00718 public:
00719
00720
00722 xtl_char( CharT char_ )
00723 : m_char( char_ )
00724 {
00725 }
00726
00727
00728
00759 template< typename UniverseT >
00760 size_t internal_match( UniverseT& edge_ )
00761 {
00762 if ( edge_.parent().text()[ edge_.first.offset() ] == m_char ) {
00763
00764
00765 size_t match_offset = edge_.first.offset();
00766
00767 edge_.first.offset( match_offset + 1 );
00768 CTTL_TRACE_TEXT_RESULT( true, m_char, "char" );
00769 return match_offset;
00770 }
00771
00772 CTTL_TRACE_TEXT_RESULT( false, m_char, "char" );
00773 return UniverseT::string_T::npos;
00774 }
00775
00806 template< typename UniverseT >
00807 size_t internal_find( UniverseT& edge_ )
00808 {
00809 size_t new_offset = edge_.parent().text().find( m_char, edge_.first.offset() );
00810 if ( new_offset != UniverseT::string_T::npos ) {
00811
00812
00813 edge_.first.offset( new_offset + 1 );
00814 CTTL_TRACE_TEXT_RESULT( true, m_char, "char" );
00815 return new_offset;
00816 }
00817
00818 CTTL_TRACE_TEXT_RESULT( false, m_char, "char" );
00819 return UniverseT::string_T::npos;
00820 }
00821 };
00822
00823
00835 template< typename CharT >
00836 class xtl_char_begin : public xtl_primary< xtl_char_begin< CharT > > {
00837
00838 private:
00840 CharT m_char;
00841
00842 public:
00843
00844
00846 xtl_char_begin( CharT char_ )
00847 : m_char( char_ )
00848 {
00849 }
00850
00851
00852
00871 template< typename UniverseT >
00872 size_t internal_match( UniverseT& edge_ )
00873 {
00874 if ( edge_.parent().text()[ edge_.first.offset() ] == m_char ) {
00875
00876 CTTL_TRACE_TEXT_RESULT( true, m_char, "begin( char )" );
00877
00878 return edge_.first.offset();
00879 }
00880
00881 CTTL_TRACE_TEXT_RESULT( false, m_char, "begin( char )" );
00882 return UniverseT::string_T::npos;
00883 }
00884
00903 template< typename UniverseT >
00904 size_t internal_find( UniverseT& edge_ )
00905 {
00906 size_t new_offset = edge_.parent().text().find( m_char, edge_.first.offset() );
00907 if ( new_offset != UniverseT::string_T::npos ) {
00908
00909
00910 edge_.first.offset( new_offset );
00911 CTTL_TRACE_TEXT_RESULT( true, m_char, "begin( char )" );
00912 return new_offset;
00913 }
00914
00915 CTTL_TRACE_TEXT_RESULT( false, m_char, "begin( char )" );
00916 return UniverseT::string_T::npos;
00917 }
00918
00919 };
00920
00921
00932 template< typename CharT >
00933 class xtl_char_end : public xtl_primary< xtl_char_end< CharT > > {
00934
00935 private:
00937 CharT m_char;
00938
00939 public:
00940
00941
00943 xtl_char_end( CharT char_ )
00944 : m_char( char_ )
00945 {
00946 }
00947
00948
00949
00968 template< typename UniverseT >
00969 size_t internal_match( UniverseT& edge_ )
00970 {
00971 if ( edge_.parent().text()[ edge_.first.offset() ] == m_char ) {
00972
00973 edge_.first.offset( edge_.first.offset() + 1 );
00974 CTTL_TRACE_TEXT_RESULT( true, m_char, "end( char )" );
00975 return edge_.first.offset();
00976 }
00977
00978 CTTL_TRACE_TEXT_RESULT( false, m_char, "end( char )" );
00979 return UniverseT::string_T::npos;
00980 }
00981
01000 template< typename UniverseT >
01001 size_t internal_find( UniverseT& edge_ )
01002 {
01003 size_t new_offset = edge_.parent().text().find( m_char, edge_.first.offset() );
01004 if ( new_offset != UniverseT::string_T::npos ) {
01005
01006
01007 edge_.first.offset( ++new_offset );
01008 CTTL_TRACE_TEXT_RESULT( true, m_char, "end( char )" );
01009 return new_offset;
01010 }
01011
01012 CTTL_TRACE_TEXT_RESULT( false, m_char, "end( char )" );
01013 return UniverseT::string_T::npos;
01014 }
01015 };
01016
01017
01018
01026 class xtl_iswhat_begin : public xtl_primary< xtl_iswhat_begin > {
01027
01028 private:
01030 iswhat_T m_iswhat;
01031
01032 public:
01033
01034
01036 xtl_iswhat_begin( iswhat_T iswhat_ )
01037 : m_iswhat( iswhat_ )
01038 {
01039 }
01040
01041
01042
01061 template< typename UniverseT >
01062 size_t internal_match( UniverseT const& edge_ )
01063 {
01064 if ( m_iswhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01065
01066 CTTL_TRACE_RESULT( true, '<' );
01067 return edge_.first.offset();
01068 }
01069 CTTL_TRACE_RESULT( false, '<' );
01070 return UniverseT::string_T::npos;
01071 }
01072
01091 template< typename UniverseT >
01092 size_t internal_find( UniverseT& edge_ )
01093 {
01094 typename UniverseT::string_T const& str = edge_.parent().text();
01095 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01096
01097
01098 it = std::find_if( it, str.end(), m_iswhat );
01099 if ( it == str.end() ) {
01100 CTTL_TRACE_RESULT( false, '<' );
01101 return UniverseT::string_T::npos;
01102 }
01103
01104 size_t new_offset = std::distance( str.begin(), it );
01105 edge_.first.offset( new_offset );
01106 CTTL_TRACE_RESULT( true, '<' );
01107 return new_offset;
01108 }
01109
01110 };
01111
01112
01121 class xtl_iswhat_first : public xtl_primary< xtl_iswhat_first > {
01122
01123 private:
01125 iswhat_T m_iswhat;
01126
01127 public:
01128
01129
01131 xtl_iswhat_first( iswhat_T iswhat_ )
01132 : m_iswhat( iswhat_ )
01133 {
01134 }
01135
01136
01137
01168 template< typename UniverseT >
01169 size_t internal_match( UniverseT& edge_ )
01170 {
01171 if ( m_iswhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01172
01173
01174 size_t match_offset = edge_.first.offset();
01175
01176
01177 edge_.first.offset( edge_.first.offset() + 1 );
01178 CTTL_TRACE_RESULT( true, 'F' );
01179 return match_offset;
01180 }
01181 CTTL_TRACE_RESULT( false, 'F' );
01182 return UniverseT::string_T::npos;
01183 }
01184
01215 template< typename UniverseT >
01216 size_t internal_find( UniverseT& edge_ )
01217 {
01218 typename UniverseT::string_T const& str = edge_.parent().text();
01219 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01220
01221
01222 it = std::find_if( it, str.end(), m_iswhat );
01223 if ( it == str.end() ) {
01224 CTTL_TRACE_RESULT( false, 'F' );
01225 return UniverseT::string_T::npos;
01226 }
01227
01228 size_t new_offset = std::distance( str.begin(), it );
01229
01230
01231 edge_.first.offset( new_offset + 1 );
01232 CTTL_TRACE_RESULT( true, 'F' );
01233 return new_offset;
01234 }
01235
01236 };
01237
01238
01246 class xtl_iswhat_end : public xtl_primary< xtl_iswhat_end > {
01247
01248 private:
01250 iswhat_T m_iswhat;
01251
01252 public:
01253
01254
01256 xtl_iswhat_end( iswhat_T iswhat_ )
01257 : m_iswhat( iswhat_ )
01258 {
01259 }
01260
01261
01262
01287 template< typename UniverseT >
01288 size_t match( UniverseT& edge_ )
01289 {
01290 size_t match_offset = xtl_primary< xtl_iswhat_end >::match( edge_ );
01291
01292 if ( match_offset != UniverseT::string_T::npos ) {
01293 return edge_.first.offset();
01294 }
01295 return UniverseT::string_T::npos;
01296 }
01297
01316 template< typename UniverseT >
01317 size_t internal_match( UniverseT& edge_ )
01318 {
01319 if ( m_iswhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01320
01321
01322 size_t match_offset = edge_.first.offset();
01323
01324
01325 typename UniverseT::string_T const& str = edge_.parent().text();
01326 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01327 it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswhat ) ) );
01328
01329 if ( it != str.end() )
01330 edge_.first.offset( std::distance( str.begin(), it ) );
01331 else
01332 edge_.first.offset( str.length() );
01333
01334 CTTL_TRACE_RESULT( true, '>' );
01335 return match_offset;
01336
01337 } else if ( edge_.first.offset() ) {
01338
01339
01340 size_t offset_minus_one = edge_.first.offset() - 1;
01341 if ( offset_minus_one != edge_.space_policy().lower_bound( offset_minus_one, edge_.second.offset() ) ) {
01342
01343 CTTL_TRACE_RESULT( false, '>' );
01344 return UniverseT::string_T::npos;
01345 }
01346
01347 if ( m_iswhat( edge_.parent().text()[ offset_minus_one ] ) ) {
01348
01349 CTTL_TRACE_RESULT( true, '>' );
01350 return edge_.first.offset();
01351 }
01352 }
01353 CTTL_TRACE_RESULT( false, '>' );
01354 return UniverseT::string_T::npos;
01355 }
01356
01375 template< typename UniverseT >
01376 size_t internal_find( UniverseT& edge_ )
01377 {
01378 typename UniverseT::string_T const& str = edge_.parent().text();
01379 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01380
01381
01382 it = std::find_if( it, str.end(), m_iswhat );
01383 if ( it == str.end() ) {
01384 CTTL_TRACE_RESULT( false, '>' );
01385 return UniverseT::string_T::npos;
01386 }
01387
01388
01389 size_t new_offset = UniverseT::string_T::npos;
01390 it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswhat ) ) );
01391 if ( it != str.end() )
01392 new_offset = std::distance( str.begin(), it );
01393 else
01394 new_offset = str.length();
01395
01396
01397 edge_.first.offset( new_offset );
01398 CTTL_TRACE_RESULT( true, '>' );
01399 return new_offset;
01400 }
01401
01402 };
01403
01404
01412 class xtl_iswhat_entity : public xtl_primary< xtl_iswhat_entity > {
01413
01414 private:
01416 iswhat_T m_iswhat;
01417
01418 public:
01419
01420
01422 xtl_iswhat_entity( iswhat_T iswhat_ )
01423 : m_iswhat( iswhat_ )
01424 {
01425 }
01426
01427
01428
01453 template< typename UniverseT >
01454 size_t internal_match( UniverseT& edge_ )
01455 {
01456 if ( m_iswhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01457
01458
01459 size_t match_offset = edge_.first.offset();
01460
01461
01462 typename UniverseT::string_T const& str = edge_.parent().text();
01463 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01464 it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswhat ) ) );
01465
01466 if ( it != str.end() )
01467 edge_.first.offset( std::distance( str.begin(), it ) );
01468 else
01469 edge_.first.offset( str.length() );
01470
01471 CTTL_TRACE_RESULT( true, '$' );
01472 return match_offset;
01473 }
01474 CTTL_TRACE_RESULT( false, '$' );
01475 return UniverseT::string_T::npos;
01476 }
01477
01496 template< typename UniverseT >
01497 size_t internal_find( UniverseT& edge_ )
01498 {
01499 typename UniverseT::string_T const& str = edge_.parent().text();
01500 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01501
01502
01503 it = std::find_if( it, str.end(), m_iswhat );
01504 if ( it == str.end() ) {
01505 CTTL_TRACE_RESULT( false, '$' );
01506 return UniverseT::string_T::npos;
01507 }
01508
01509 size_t new_offset = std::distance( str.begin(), it );
01510
01511 size_t match_offset = new_offset;
01512
01513
01514 it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswhat ) ) );
01515 if ( it != str.end() )
01516 new_offset = std::distance( str.begin(), it );
01517 else
01518 new_offset = str.length();
01519
01520
01521 edge_.first.offset( new_offset );
01522 CTTL_TRACE_RESULT( true, '$' );
01523 return match_offset;
01524 }
01525
01526 };
01527
01528
01536 class xtl_iswwhat_begin : public xtl_primary< xtl_iswwhat_begin > {
01537
01538 private:
01540 iswwhat_T m_iswwhat;
01541
01542 public:
01543
01544
01546 xtl_iswwhat_begin( iswwhat_T iswwhat_ )
01547 : m_iswwhat( iswwhat_ )
01548 {
01549 }
01550
01551
01552
01571 template< typename UniverseT >
01572 size_t internal_match( UniverseT const& edge_ )
01573 {
01574 if ( m_iswwhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01575
01576 CTTL_TRACE_RESULT( true, '<' );
01577 return edge_.first.offset();
01578 }
01579 CTTL_TRACE_RESULT( false, '<' );
01580 return UniverseT::string_T::npos;
01581 }
01582
01601 template< typename UniverseT >
01602 size_t internal_find( UniverseT& edge_ )
01603 {
01604 typename UniverseT::string_T const& str = edge_.parent().text();
01605 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01606
01607
01608 it = std::find_if( it, str.end(), m_iswwhat );
01609 if ( it == str.end() ) {
01610 CTTL_TRACE_RESULT( false, '<' );
01611 return UniverseT::string_T::npos;
01612 }
01613
01614 size_t new_offset = std::distance( str.begin(), it );
01615
01616 edge_.first.offset( new_offset );
01617 CTTL_TRACE_RESULT( true, '<' );
01618 return new_offset;
01619 }
01620
01621 };
01622
01623
01632 class xtl_iswwhat_first : public xtl_primary< xtl_iswwhat_first > {
01633
01634 private:
01636 iswwhat_T m_iswwhat;
01637
01638 public:
01639
01640
01642 xtl_iswwhat_first( iswwhat_T iswwhat_ )
01643 : m_iswwhat( iswwhat_ )
01644 {
01645 }
01646
01647
01648
01679 template< typename UniverseT >
01680 size_t internal_match( UniverseT& edge_ )
01681 {
01682 if ( m_iswwhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01683
01684
01685 size_t match_offset = edge_.first.offset();
01686
01687 edge_.first.offset( edge_.first.offset() + 1 );
01688 CTTL_TRACE_RESULT( true, 'F' );
01689 return match_offset;
01690 }
01691 CTTL_TRACE_RESULT( false, 'F' );
01692 return UniverseT::string_T::npos;
01693 }
01694
01725 template< typename UniverseT >
01726 size_t internal_find( UniverseT& edge_ )
01727 {
01728 typename UniverseT::string_T const& str = edge_.parent().text();
01729 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01730
01731
01732 it = std::find_if( it, str.end(), m_iswwhat );
01733 if ( it == str.end() ) {
01734 CTTL_TRACE_RESULT( false, 'F' );
01735 return UniverseT::string_T::npos;
01736 }
01737
01738 size_t new_offset = std::distance( str.begin(), it );
01739
01740
01741 edge_.first.offset( new_offset + 1 );
01742 CTTL_TRACE_RESULT( true, 'F' );
01743 return new_offset;
01744 }
01745
01746 };
01747
01748
01756 class xtl_iswwhat_end : public xtl_primary< xtl_iswwhat_end > {
01757
01758 private:
01760 iswwhat_T m_iswwhat;
01761
01762 public:
01763
01764
01766 xtl_iswwhat_end( iswwhat_T iswwhat_ )
01767 : m_iswwhat( iswwhat_ )
01768 {
01769 }
01770
01771
01772
01797 template< typename UniverseT >
01798 size_t match( UniverseT& edge_ )
01799 {
01800 size_t match_offset = xtl_primary< xtl_iswwhat_end >::match( edge_ );
01801
01802 if ( match_offset != UniverseT::string_T::npos ) {
01803 return edge_.first.offset();
01804 }
01805 return UniverseT::string_T::npos;
01806 }
01807
01826 template< typename UniverseT >
01827 size_t internal_match( UniverseT& edge_ )
01828 {
01829 if ( m_iswwhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01830
01831
01832 size_t match_offset = edge_.first.offset();
01833
01834
01835 typename UniverseT::string_T const& str = edge_.parent().text();
01836 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01837 it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswwhat ) ) );
01838
01839 if ( it != str.end() )
01840 edge_.first.offset( std::distance( str.begin(), it ) );
01841 else
01842 edge_.first.offset( str.length() );
01843
01844 CTTL_TRACE_RESULT( true, '>' );
01845 return match_offset;
01846
01847 } else if ( edge_.first.offset() ) {
01848
01849
01850 size_t offset_minus_one = edge_.first.offset() - 1;
01851 if ( offset_minus_one != edge_.space_policy().lower_bound( offset_minus_one, edge_.second.offset() ) ) {
01852
01853 CTTL_TRACE_RESULT( false, '>' );
01854 return UniverseT::string_T::npos;
01855 }
01856
01857 if ( m_iswwhat( edge_.parent().text()[ offset_minus_one ] ) ) {
01858
01859 CTTL_TRACE_RESULT( true, '>' );
01860 return edge_.first.offset();
01861 }
01862 }
01863 CTTL_TRACE_RESULT( false, '>' );
01864 return UniverseT::string_T::npos;
01865 }
01866
01885 template< typename UniverseT >
01886 size_t internal_find( UniverseT& edge_ )
01887 {
01888 typename UniverseT::string_T const& str = edge_.parent().text();
01889 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01890
01891
01892 it = std::find_if( it, str.end(), m_iswwhat );
01893 if ( it == str.end() ) {
01894 CTTL_TRACE_RESULT( false, '>' );
01895 return UniverseT::string_T::npos;
01896 }
01897
01898
01899 size_t new_offset = UniverseT::string_T::npos;
01900 it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswwhat ) ) );
01901 if ( it != str.end() )
01902 new_offset = std::distance( str.begin(), it );
01903 else
01904 new_offset = str.length();
01905
01906
01907 edge_.first.offset( new_offset );
01908
01909
01910
01911
01912 CTTL_TRACE_RESULT( true, '>' );
01913 return new_offset;
01914 }
01915
01916 };
01917
01918
01926 class xtl_iswwhat_entity : public xtl_primary< xtl_iswwhat_entity > {
01927
01928 private:
01930 iswwhat_T m_iswwhat;
01931
01932 public:
01933
01934
01936 xtl_iswwhat_entity( iswwhat_T iswwhat_ )
01937 : m_iswwhat( iswwhat_ )
01938 {
01939 }
01940
01941
01942
01967 template< typename UniverseT >
01968 size_t internal_match( UniverseT& edge_ )
01969 {
01970 if ( m_iswwhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01971
01972
01973 size_t match_offset = edge_.first.offset();
01974
01975
01976 typename UniverseT::string_T const& str = edge_.parent().text();
01977 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01978 it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswwhat ) ) );
01979
01980 if ( it != str.end() )
01981 edge_.first.offset( std::distance( str.begin(), it ) );
01982 else
01983 edge_.first.offset( str.length() );
01984
01985 CTTL_TRACE_RESULT( true, '$' );
01986 return match_offset;
01987 }
01988 CTTL_TRACE_RESULT( false, '$' );
01989 return UniverseT::string_T::npos;
01990 }
01991
02010 template< typename UniverseT >
02011 size_t internal_find( UniverseT& edge_ )
02012 {
02013 typename UniverseT::string_T const& str = edge_.parent().text();
02014 typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
02015
02016
02017 it = std::find_if( it, str.end(), m_iswwhat );
02018 if ( it == str.end() ) {
02019 CTTL_TRACE_RESULT( false, '$' );
02020 return UniverseT::string_T::npos;
02021 }
02022
02023 size_t new_offset = std::distance( str.begin(), it );
02024
02025 size_t match_offset = new_offset;
02026
02027
02028 it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswwhat ) ) );
02029 if ( it != str.end() )
02030 new_offset = std::distance( str.begin(), it );
02031 else
02032 new_offset = str.length();
02033
02034
02035 edge_.first.offset( new_offset );
02036 CTTL_TRACE_RESULT( true, '$' );
02037 return match_offset;
02038 }
02039
02040 };
02041
02042
02054 template< typename StringT >
02055 class xtl_text_begin : public xtl_primary< xtl_text_begin< StringT > > {
02056
02057 private:
02059 StringT m_any_text;
02060
02061 public:
02062
02063
02065 xtl_text_begin( StringT const& any_text_ )
02066 : m_any_text( any_text_ )
02067 {
02068 }
02069
02070
02071
02090 template< typename UniverseT >
02091 size_t internal_match( UniverseT& edge_ )
02092 {
02093 typename UniverseT::string_T const& str = edge_.parent().text();
02094 if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02095
02096
02097 CTTL_TRACE_TEXT_RESULT( true, '<', m_any_text.c_str() );
02098 return edge_.first.offset();
02099 }
02100
02101 CTTL_TRACE_TEXT_RESULT( false, '<', m_any_text.c_str() );
02102 return UniverseT::string_T::npos;
02103 }
02104
02123 template< typename UniverseT >
02124 size_t internal_find( UniverseT& edge_ )
02125 {
02126 typename UniverseT::string_T const& str = edge_.parent().text();
02127 size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02128 if ( new_offset != UniverseT::string_T::npos ) {
02129
02130
02131 edge_.first.offset( new_offset );
02132 CTTL_TRACE_TEXT_RESULT( true, '<', m_any_text.c_str() );
02133 return new_offset;
02134 }
02135
02136 CTTL_TRACE_TEXT_RESULT( false, '<', m_any_text.c_str() );
02137 return UniverseT::string_T::npos;
02138 }
02139 };
02140
02141
02153 template< typename StringT >
02154 class xtl_text_ref_begin : public xtl_primary< xtl_text_ref_begin< StringT > > {
02155
02156 private:
02158 StringT const& m_any_text;
02159
02160 public:
02161
02162
02164 xtl_text_ref_begin( StringT const* str_ptr_ )
02165 : m_any_text( *str_ptr_ )
02166 {
02167 }
02168
02170 void operator=( xtl_text_ref_begin< StringT > const& ) const
02171 {
02172 }
02173
02174
02175
02194 template< typename UniverseT >
02195 size_t internal_match( UniverseT& edge_ )
02196 {
02197 typename UniverseT::string_T const& str = edge_.parent().text();
02198 if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02199
02200
02201 CTTL_TRACE_TEXT_RESULT( true, '<', m_any_text.c_str() );
02202 return edge_.first.offset();
02203 }
02204
02205 CTTL_TRACE_TEXT_RESULT( false, '<', m_any_text.c_str() );
02206 return UniverseT::string_T::npos;
02207 }
02208
02227 template< typename UniverseT >
02228 size_t internal_find( UniverseT& edge_ )
02229 {
02230 typename UniverseT::string_T const& str = edge_.parent().text();
02231 size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02232 if ( new_offset != UniverseT::string_T::npos ) {
02233
02234
02235 edge_.first.offset( new_offset );
02236 CTTL_TRACE_TEXT_RESULT( true, '<', m_any_text.c_str() );
02237 return new_offset;
02238 }
02239
02240 CTTL_TRACE_TEXT_RESULT( false, '<', m_any_text.c_str() );
02241 return UniverseT::string_T::npos;
02242 }
02243 };
02244
02245
02257 template< typename StringT >
02258 class xtl_text_end : public xtl_primary< xtl_text_end< StringT > > {
02259
02260 private:
02262 StringT m_any_text;
02263
02264 public:
02265
02266
02268 xtl_text_end( StringT const& any_text_ )
02269 : m_any_text( any_text_ )
02270 {
02271 }
02272
02273
02274
02299 template< typename UniverseT >
02300 size_t match( UniverseT& edge_ )
02301 {
02302 size_t match_offset = xtl_primary< xtl_text_end >::match( edge_ );
02303 if ( match_offset != UniverseT::string_T::npos ) {
02304 return edge_.first.offset();
02305 }
02306 return UniverseT::string_T::npos;
02307 }
02308
02327 template< typename UniverseT >
02328 size_t internal_match( UniverseT& edge_ )
02329 {
02330 typename UniverseT::string_T const& str = edge_.parent().text();
02331 if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02332
02333
02334 size_t match_offset = edge_.first.offset();
02335
02336
02337 size_t new_offset = str.find_first_not_of( m_any_text, edge_.first.offset() );
02338 if ( new_offset == UniverseT::string_T::npos )
02339 new_offset = str.length();
02340
02341
02342 edge_.first.offset( new_offset );
02343 CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02344 return match_offset;
02345
02346 } else if ( edge_.first.offset() ) {
02347
02348
02349 size_t offset_minus_one = edge_.first.offset() - 1;
02350 if ( offset_minus_one != edge_.space_policy().lower_bound( offset_minus_one, edge_.second.offset() ) ) {
02351
02352 CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02353 return UniverseT::string_T::npos;
02354 }
02355
02356 if ( m_any_text.find( str[ offset_minus_one ] ) != UniverseT::string_T::npos ) {
02357
02358 CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02359 return edge_.first.offset();
02360 }
02361 }
02362
02363 CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02364 return UniverseT::string_T::npos;
02365 }
02366
02385 template< typename UniverseT >
02386 size_t internal_find( UniverseT& edge_ )
02387 {
02388 typename UniverseT::string_T const& str = edge_.parent().text();
02389 size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02390 if ( new_offset != UniverseT::string_T::npos ) {
02391
02392
02393 new_offset = str.find_first_not_of( m_any_text, new_offset );
02394 if ( new_offset == UniverseT::string_T::npos )
02395 new_offset = str.length();
02396
02397
02398 edge_.first.offset( new_offset );
02399 CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02400 return new_offset;
02401 }
02402
02403 CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02404 return UniverseT::string_T::npos;
02405 }
02406 };
02407
02408
02420 template< typename StringT >
02421 class xtl_text_ref_end : public xtl_primary< xtl_text_ref_end< StringT > > {
02422
02423 private:
02425 StringT const& m_any_text;
02426
02427 public:
02428
02429
02431 xtl_text_ref_end( StringT const* str_ptr_ )
02432 : m_any_text( *str_ptr_ )
02433 {
02434 }
02435
02437 void operator=( xtl_text_ref_end< StringT > const& ) const
02438 {
02439 }
02440
02441
02442
02467 template< typename UniverseT >
02468 size_t match( UniverseT& edge_ )
02469 {
02470 size_t match_offset = xtl_primary< xtl_text_ref_end >::match( edge_ );
02471 if ( match_offset != UniverseT::string_T::npos ) {
02472 return edge_.first.offset();
02473 }
02474 return UniverseT::string_T::npos;
02475 }
02476
02495 template< typename UniverseT >
02496 size_t internal_match( UniverseT& edge_ )
02497 {
02498 typename UniverseT::string_T const& str = edge_.parent().text();
02499 if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02500
02501
02502 size_t match_offset = edge_.first.offset();
02503
02504
02505 size_t new_offset = str.find_first_not_of( m_any_text, edge_.first.offset() );
02506 if ( new_offset == UniverseT::string_T::npos )
02507 new_offset = str.length();
02508
02509
02510 edge_.first.offset( new_offset );
02511 CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02512 return match_offset;
02513
02514 } else if ( edge_.first.offset() ) {
02515
02516
02517 size_t offset_minus_one = edge_.first.offset() - 1;
02518 if ( offset_minus_one != edge_.space_policy().lower_bound( offset_minus_one, edge_.second.offset() ) ) {
02519
02520 CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02521 return UniverseT::string_T::npos;
02522 }
02523
02524 if ( m_any_text.find( str[ offset_minus_one ] ) != UniverseT::string_T::npos ) {
02525
02526 CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02527 return edge_.first.offset();
02528 }
02529 }
02530
02531 CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02532 return UniverseT::string_T::npos;
02533 }
02534
02553 template< typename UniverseT >
02554 size_t internal_find( UniverseT& edge_ )
02555 {
02556 typename UniverseT::string_T const& str = edge_.parent().text();
02557 size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02558 if ( new_offset != UniverseT::string_T::npos ) {
02559
02560
02561 new_offset = str.find_first_not_of( m_any_text, new_offset );
02562 if ( new_offset == UniverseT::string_T::npos )
02563 new_offset = str.length();
02564
02565
02566 edge_.first.offset( new_offset );
02567 CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02568 return new_offset;
02569 }
02570
02571 CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02572 return UniverseT::string_T::npos;
02573 }
02574 };
02575
02576
02588 template< typename StringT >
02589 class xtl_text_first : public xtl_primary< xtl_text_first< StringT > > {
02590
02591 private:
02593 StringT m_any_text;
02594
02595 public:
02596
02597
02599 xtl_text_first( StringT const& any_text_ )
02600 : m_any_text( any_text_ )
02601 {
02602 }
02603
02604
02605
02636 template< typename UniverseT >
02637 size_t internal_match( UniverseT& edge_ )
02638 {
02639 typename UniverseT::string_T const& str = edge_.parent().text();
02640 if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02641
02642
02643 size_t match_offset = edge_.first.offset();
02644
02645 edge_.first.offset( edge_.first.offset() + 1 );
02646 CTTL_TRACE_TEXT_RESULT( true, 'F', m_any_text.c_str() );
02647 return match_offset;
02648 }
02649
02650 CTTL_TRACE_TEXT_RESULT( false, 'F', m_any_text.c_str() );
02651 return UniverseT::string_T::npos;
02652 }
02653
02684 template< typename UniverseT >
02685 size_t internal_find( UniverseT& edge_ )
02686 {
02687 typename UniverseT::string_T const& str = edge_.parent().text();
02688 size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02689 if ( new_offset != UniverseT::string_T::npos ) {
02690
02691
02692
02693 edge_.first.offset( new_offset + 1 );
02694 CTTL_TRACE_TEXT_RESULT( true, 'F', m_any_text.c_str() );
02695 return new_offset;
02696 }
02697
02698 CTTL_TRACE_TEXT_RESULT( false, 'F', m_any_text.c_str() );
02699 return UniverseT::string_T::npos;
02700 }
02701 };
02702
02703
02715 template< typename StringT >
02716 class xtl_text_ref_first : public xtl_primary< xtl_text_ref_first< StringT > > {
02717
02718 private:
02720 StringT const& m_any_text;
02721
02722 public:
02723
02724
02726 xtl_text_ref_first( StringT const* str_ptr_ )
02727 : m_any_text( *str_ptr_ )
02728 {
02729 }
02730
02732 void operator=( xtl_text_ref_first< StringT > const& ) const
02733 {
02734 }
02735
02736
02737
02768 template< typename UniverseT >
02769 size_t internal_match( UniverseT& edge_ )
02770 {
02771 typename UniverseT::string_T const& str = edge_.parent().text();
02772 if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02773
02774
02775 size_t match_offset = edge_.first.offset();
02776
02777
02778 edge_.first.offset( edge_.first.offset() + 1 );
02779 CTTL_TRACE_TEXT_RESULT( true, 'F', m_any_text.c_str() );
02780 return match_offset;
02781 }
02782
02783 CTTL_TRACE_TEXT_RESULT( false, 'F', m_any_text.c_str() );
02784 return UniverseT::string_T::npos;
02785 }
02786
02817 template< typename UniverseT >
02818 size_t internal_find( UniverseT& edge_ )
02819 {
02820 typename UniverseT::string_T const& str = edge_.parent().text();
02821 size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02822 if ( new_offset != UniverseT::string_T::npos ) {
02823
02824
02825
02826 edge_.first.offset( new_offset + 1 );
02827 CTTL_TRACE_TEXT_RESULT( true, 'F', m_any_text.c_str() );
02828 return new_offset;
02829 }
02830
02831 CTTL_TRACE_TEXT_RESULT( false, 'F', m_any_text.c_str() );
02832 return UniverseT::string_T::npos;
02833 }
02834 };
02835
02836
02848 template< typename StringT >
02849 class xtl_text_entity : public xtl_primary< xtl_text_entity< StringT > > {
02850
02851 private:
02853 StringT m_any_text;
02854
02855 public:
02856
02857
02859 xtl_text_entity( typename StringT::value_type const* any_text_ )
02860 : m_any_text( any_text_ )
02861 {
02862 }
02863
02865 xtl_text_entity( StringT const& any_text_ )
02866 : m_any_text( any_text_ )
02867 {
02868 }
02869
02870
02871
02890 template< typename UniverseT >
02891 size_t internal_match( UniverseT& edge_ )
02892 {
02893 typename UniverseT::string_T const& str = edge_.parent().text();
02894 if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02895
02896
02897 size_t match_offset = edge_.first.offset();
02898
02899
02900 size_t new_offset = str.find_first_not_of( m_any_text, edge_.first.offset() );
02901 if ( new_offset == UniverseT::string_T::npos )
02902 new_offset = str.length();
02903
02904
02905 edge_.first.offset( new_offset );
02906 CTTL_TRACE_TEXT_RESULT( true, '$', m_any_text.c_str() );
02907 return match_offset;
02908 }
02909
02910 CTTL_TRACE_TEXT_RESULT( false, '$', m_any_text.c_str() );
02911 return UniverseT::string_T::npos;
02912 }
02913
02932 template< typename UniverseT >
02933 size_t internal_find( UniverseT& edge_ )
02934 {
02935 typename UniverseT::string_T const& str = edge_.parent().text();
02936 size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02937 if ( new_offset != UniverseT::string_T::npos ) {
02938
02939
02940 size_t match_offset = new_offset;
02941
02942
02943 new_offset = str.find_first_not_of( m_any_text, new_offset );
02944 if ( new_offset == UniverseT::string_T::npos )
02945 new_offset = str.length();
02946
02947
02948 edge_.first.offset( new_offset );
02949 CTTL_TRACE_TEXT_RESULT( true, '$', m_any_text.c_str() );
02950 return match_offset;
02951 }
02952
02953 CTTL_TRACE_TEXT_RESULT( false, '$', m_any_text.c_str() );
02954 return UniverseT::string_T::npos;
02955 }
02956 };
02957
02958
02970 template< typename StringT >
02971 class xtl_text_ref_entity : public xtl_primary< xtl_text_ref_entity< StringT > > {
02972
02973 private:
02975 StringT const& m_str_ref;
02976
02977 public:
02978
02979
02981 xtl_text_ref_entity( StringT const* str_ptr_ )
02982 : m_str_ref( *str_ptr_ )
02983 {
02984 }
02985
02987 void operator=( xtl_text_ref_entity< StringT > const& ) const
02988 {
02989 }
02990
02991
02992
03011 template< typename UniverseT >
03012 size_t internal_match( UniverseT& edge_ )
03013 {
03014 typename UniverseT::string_T const& str = edge_.parent().text();
03015 if ( m_str_ref.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
03016
03017
03018 size_t match_offset = edge_.first.offset();
03019
03020
03021 size_t new_offset = str.find_first_not_of( m_str_ref, edge_.first.offset() );
03022 if ( new_offset == UniverseT::string_T::npos )
03023 new_offset = str.length();
03024
03025
03026 edge_.first.offset( new_offset );
03027 CTTL_TRACE_TEXT_RESULT( true, '$', m_str_ref.c_str() );
03028 return match_offset;
03029 }
03030
03031 CTTL_TRACE_TEXT_RESULT( false, '$', m_str_ref.c_str() );
03032 return UniverseT::string_T::npos;
03033 }
03034
03053 template< typename UniverseT >
03054 size_t internal_find( UniverseT& edge_ )
03055 {
03056 typename UniverseT::string_T const& str = edge_.parent().text();
03057 size_t new_offset = str.find_first_of( m_str_ref, edge_.first.offset() );
03058 if ( new_offset != UniverseT::string_T::npos ) {
03059
03060
03061 size_t match_offset = new_offset;
03062
03063
03064 new_offset = str.find_first_not_of( m_str_ref, new_offset );
03065 if ( new_offset == UniverseT::string_T::npos )
03066 new_offset = str.length();
03067
03068 edge_.first.offset( new_offset );
03069 CTTL_TRACE_TEXT_RESULT( true, '$', m_str_ref.c_str() );
03070 return match_offset;
03071 }
03072
03073 CTTL_TRACE_TEXT_RESULT( false, '$', m_str_ref.c_str() );
03074 return UniverseT::string_T::npos;
03075 }
03076 };
03077
03078
03089 template< typename StringT >
03090 class xtl_text_symbol : public xtl_primary< xtl_text_symbol< StringT > > {
03091
03092 private:
03094 StringT m_text;
03095
03096 public:
03097
03098
03100 xtl_text_symbol( StringT const& str_ref_ )
03101 : m_text( str_ref_ )
03102 {
03103 }
03104
03105
03106
03137 template< typename UniverseT >
03138 size_t internal_match( UniverseT& edge_ )
03139 {
03140 typename UniverseT::string_T const& str = edge_.parent().text();
03141 if ( edge_.first.offset() + m_text.length() <= str.length() ) {
03142 if ( str.substr( edge_.first.offset(), m_text.length() ) == m_text ) {
03143
03144
03145 size_t match_offset = edge_.first.offset();
03146
03147 edge_.first.offset( edge_.first.offset() + m_text.length() );
03148 CTTL_TRACE_TEXT_RESULT( true, 'T', m_text.c_str() );
03149 return match_offset;
03150 }
03151 }
03152
03153 CTTL_TRACE_TEXT_RESULT( false, 'T', m_text.c_str() );
03154 return UniverseT::string_T::npos;
03155 }
03156
03187 template< typename UniverseT >
03188 size_t internal_find( UniverseT& edge_ )
03189 {
03190 size_t new_offset = edge_.parent().text().find( m_text, edge_.first.offset() );
03191 if ( new_offset != UniverseT::string_T::npos ) {
03192
03193
03194 edge_.first.offset( new_offset + m_text.length() );
03195 CTTL_TRACE_TEXT_RESULT( true, 'T', m_text.c_str() );
03196 return new_offset;
03197 }
03198
03199 CTTL_TRACE_TEXT_RESULT( false, 'T', m_text.c_str() );
03200 return UniverseT::string_T::npos;
03201 }
03202 };
03203
03204
03215 template< typename StringT >
03216 class xtl_text_ref_symbol : public xtl_primary< xtl_text_ref_symbol< StringT > > {
03217
03218 private:
03220 StringT const& m_text_ref;
03221
03222 public:
03223
03224
03226 xtl_text_ref_symbol( StringT const* str_ptr_ )
03227 : m_text_ref( *str_ptr_ )
03228 {
03229 }
03230
03232 void operator=( xtl_text_ref_symbol< StringT > const& )const
03233 {
03234 }
03235
03236
03237
03268 template< typename UniverseT >
03269 size_t internal_match( UniverseT& edge_ )
03270 {
03271 typename UniverseT::string_T const& str = edge_.parent().text();
03272 if ( edge_.first.offset() + m_text_ref.length() <= str.length() ) {
03273 if ( str.substr( edge_.first.offset(), m_text_ref.length() ) == m_text_ref ) {
03274
03275
03276 size_t match_offset = edge_.first.offset();
03277
03278 edge_.first.offset( edge_.first.offset() + m_text_ref.length() );
03279 CTTL_TRACE_TEXT_RESULT( true, 'T', m_text_ref.c_str() );
03280 return match_offset;
03281 }
03282 }
03283
03284 CTTL_TRACE_TEXT_RESULT( false, 'T', m_text_ref.c_str() );
03285 return UniverseT::string_T::npos;
03286 }
03287
03318 template< typename UniverseT >
03319 size_t internal_find( UniverseT& edge_ )
03320 {
03321 size_t new_offset = edge_.parent().text().find(
03322 m_text_ref,
03323 edge_.first.offset()
03324 );
03325
03326 if ( new_offset != UniverseT::string_T::npos ) {
03327
03328
03329 edge_.first.offset( new_offset + m_text_ref.length() );
03330 CTTL_TRACE_TEXT_RESULT( true, 'T', m_text_ref.c_str() );
03331 return new_offset;
03332 }
03333
03334 CTTL_TRACE_TEXT_RESULT( false, 'T', m_text_ref.c_str() );
03335 return UniverseT::string_T::npos;
03336 }
03337 };
03338
03339
03347 class xtl_position_bof {
03348
03349 public:
03350
03351
03352
03353
03354
03371 template< typename UniverseT >
03372 static size_t match( UniverseT& edge_ )
03373 {
03374 if ( edge_.first.offset() == 0 ) {
03375 CTTL_TRACE_RESULT( true, 'A' );
03376 return 0;
03377 }
03378
03379 CTTL_TRACE_RESULT( false, 'A' );
03380 return UniverseT::string_T::npos;
03381 }
03382
03397 template< typename UniverseT >
03398 static size_t find( UniverseT& edge_ )
03399 {
03400
03401 edge_.first.offset( 0 );
03402 CTTL_TRACE_RESULT( true, 'A' );
03403 return 0;
03404 }
03405
03420 template< typename UniverseT >
03421 static size_t bang_find( UniverseT& edge_ )
03422 {
03423 return find( edge_ );
03424 }
03425
03426 };
03427
03428
03436 class xtl_position_eof {
03437
03438 public:
03439
03440
03441
03442
03443
03463 template< typename UniverseT >
03464 static size_t match( UniverseT& edge_ )
03465 {
03466 if ( !edge_.length() ) {
03467 CTTL_TRACE_STATIC_RESULT( true, 'Z', "EOF" );
03468 return edge_.second.offset();
03469 }
03470
03471 if ( edge_.length() < 0 )
03472 return find( edge_ );
03473
03474
03475 size_t saved_first_offset = edge_.space_policy().match( edge_ );
03476
03477 if ( !edge_.length() ) {
03478 CTTL_TRACE_STATIC_RESULT( true, 'Z', "EOF" );
03479 return edge_.second.offset();
03480 }
03481
03482
03483 edge_.first.offset( saved_first_offset );
03484 CTTL_TRACE_STATIC_RESULT( false, 'Z', "EOF" );
03485 return UniverseT::string_T::npos;
03486 }
03487
03505 template< typename UniverseT >
03506 static size_t find( UniverseT& edge_ )
03507 {
03508
03509 edge_.first.offset( edge_.second.offset() );
03510 CTTL_TRACE_STATIC_RESULT( true, 'Z', "EOF" );
03511 return edge_.second.offset();
03512 }
03513
03531 template< typename UniverseT >
03532 static size_t bang_find( UniverseT& edge_ )
03533 {
03534 return find( edge_ );
03535 }
03536
03537 };
03538
03539
03555 template< typename Static_predicateT >
03556 class xtl_predicate {
03557
03559 Static_predicateT m_predicate;
03560
03561 public:
03562
03564 xtl_predicate( Static_predicateT const& predicate_ )
03565 :
03566 m_predicate( predicate_ )
03567 {
03568 }
03569
03586 template< typename UniverseT >
03587 size_t match( UniverseT& edge_ )
03588 {
03589 CTTL_TRACE_LEVEL_MATCH( 'R' );
03590 return m_predicate( edge_ );
03591 }
03592
03609 template< typename UniverseT >
03610 size_t find( UniverseT& edge_ )
03611 {
03612 CTTL_TRACE_LEVEL_FIND( 'R' );
03613 edge_.parent().container().m_flags.set( xtl_flag_runtime_find );
03614 return m_predicate( edge_ );
03615 }
03616
03633 template< typename UniverseT >
03634 size_t bang_find( UniverseT& edge_ )
03635 {
03636 CTTL_TRACE_LEVEL_BANG( 'R' );
03637 edge_.parent().container().m_flags.set( xtl_flag_runtime_bang_find );
03638 return m_predicate( edge_ );
03639 }
03640
03641 };
03642
03643
03659 template< typename ObjectT, typename Member_predicateT >
03660 class xtl_member_predicate {
03661
03663 ObjectT& m_object;
03664
03666 Member_predicateT m_predicate;
03667
03668 public:
03669
03671 xtl_member_predicate(
03672 ObjectT& object_ref_,
03673 Member_predicateT& predicate_
03674 )
03675 :
03676 m_object( object_ref_ ),
03677 m_predicate( predicate_ )
03678 {
03679 }
03680
03682 void operator=( xtl_member_predicate< ObjectT, Member_predicateT > const& ) const
03683 {
03684 }
03685
03702 template< typename UniverseT >
03703 size_t match( UniverseT& edge_ )
03704 {
03705 CTTL_TRACE_LEVEL_MATCH( 'R' );
03706 return std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ );
03707 }
03708
03725 template< typename UniverseT >
03726 size_t find( UniverseT& edge_ )
03727 {
03728 CTTL_TRACE_LEVEL_FIND( 'R' );
03729 edge_.parent().container().m_flags.set( xtl_flag_runtime_find );
03730 return std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ );
03731 }
03732
03749 template< typename UniverseT >
03750 size_t bang_find( UniverseT& edge_ )
03751 {
03752 CTTL_TRACE_LEVEL_BANG( 'R' );
03753 edge_.parent().container().m_flags.set( xtl_flag_runtime_bang_find );
03754 return std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ );
03755 }
03756
03757 };
03758
03759
03765 struct xtl_traced_predicate_base {
03766
03768 int m_line;
03769
03771 std::string m_rule_name;
03772
03774 xtl_traced_predicate_base( int line_, char const* rule_name_ )
03775 :
03776 m_line( line_ ),
03777 m_rule_name( rule_name_ )
03778 {
03779 }
03780
03782 template< typename UniverseT >
03783 void trace_prolog( UniverseT& edge_, char const* mode_ )
03784 {
03785 xtl_trace_grammar::depth( +1 );
03786 std::cout << xtl_trace_grammar::exact_edge2text( edge_, true ).c_str();
03787 xtl_trace_grammar::build_skyline( '-' );
03788
03789 std::cout
03790 << m_line
03791 << "->"
03792 << mode_
03793 << m_rule_name
03794 << '@'
03795 << edge_.first.offset()
03796 << '-'
03797 << edge_.second.offset()
03798 << std::endl
03799 ;
03800 }
03801
03803 template< typename UniverseT >
03804 size_t trace_epilog( UniverseT& edge_, size_t result_ )
03805 {
03806 if ( result_ != CTTL_STD_STRING::npos ) {
03807 size_t begin_offset = result_;
03808 size_t end_offset = std::min(
03809 begin_offset + xtl_trace_grammar::fragment_length,
03810 edge_.first.offset()
03811 );
03812
03813
03814 begin_offset = std::min( begin_offset, end_offset );
03815 end_offset = std::max( begin_offset, end_offset );
03816 std::string str_temp = edge_.parent().container().text_absolute_substring(
03817 begin_offset,
03818 end_offset
03819 ).c_str();
03820
03821 std::cout << xtl_trace_grammar::exact_edge2text( edge_, true ).c_str();
03822 xtl_trace_grammar::build_skyline( '+' );
03823 std::cout
03824 << m_line
03825 << "<-"
03826 << m_rule_name
03827 << '@'
03828 << begin_offset
03829 << '-'
03830 << std::max( end_offset, edge_.first.offset() )
03831 << '\t'
03832 << '\''
03833 << xtl_trace_grammar::whitespace2monospace( str_temp )
03834 << '\''
03835 << std::endl
03836 ;
03837
03838 } else {
03839 std::cout << xtl_trace_grammar::exact_edge2text( edge_, false ).c_str();
03840 xtl_trace_grammar::build_skyline( '~' );
03841 std::cout
03842 << m_line
03843 << "<-"
03844 << m_rule_name
03845 << '@'
03846 << edge_.first.offset()
03847 << std::endl
03848 ;
03849 }
03850 xtl_trace_grammar::depth( -1 );
03851 return result_;
03852 }
03853
03854 };
03855
03856
03872 template< typename ObjectT, typename Member_predicateT >
03873 class xtl_member_traced_predicate : public xtl_traced_predicate_base {
03874
03876 ObjectT& m_object;
03877
03879 Member_predicateT m_predicate;
03880
03881 public:
03882
03884 xtl_member_traced_predicate(
03885 int line_,
03886 char const* rule_name_,
03887 ObjectT& object_ref_,
03888 Member_predicateT& predicate_
03889 )
03890 :
03891 xtl_traced_predicate_base( line_, rule_name_ ),
03892 m_object( object_ref_ ),
03893 m_predicate( predicate_ )
03894 {
03895 }
03896
03898 void operator=( xtl_member_traced_predicate< ObjectT, Member_predicateT > const& ) const
03899 {
03900 }
03901
03918 template< typename UniverseT >
03919 size_t match( UniverseT& edge_ )
03920 {
03921 trace_prolog( edge_, "" );
03922 return trace_epilog(
03923 edge_,
03924 std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ )
03925 );
03926 }
03927
03944 template< typename UniverseT >
03945 size_t find( UniverseT& edge_ )
03946 {
03947 edge_.parent().container().m_flags.set( xtl_flag_runtime_find );
03948 trace_prolog( edge_, "!" );
03949 return trace_epilog(
03950 edge_,
03951 std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ )
03952 );
03953 }
03954
03971 template< typename UniverseT >
03972 size_t bang_find( UniverseT& edge_ )
03973 {
03974 edge_.parent().container().m_flags.set( xtl_flag_runtime_bang_find );
03975 trace_prolog( edge_, "!!" );
03976 return trace_epilog(
03977 edge_,
03978 std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ )
03979 );
03980 }
03981
03982 };
03983
03984
03999 template< typename Static_predicateT >
04000 class xtl_static_traced_predicate : public xtl_traced_predicate_base {
04001
04003 Static_predicateT m_predicate;
04004
04005 public:
04006
04008 xtl_static_traced_predicate(
04009 int line_,
04010 char const* rule_name_,
04011 Static_predicateT const& predicate_
04012 )
04013 :
04014 xtl_traced_predicate_base( line_, rule_name_ ),
04015 m_predicate( predicate_ )
04016 {
04017 }
04018
04035 template< typename UniverseT >
04036 size_t match( UniverseT& edge_ )
04037 {
04038 trace_prolog( edge_, "" );
04039 return trace_epilog( edge_, m_predicate( edge_ ) );
04040 }
04041
04058 template< typename UniverseT >
04059 size_t find( UniverseT& edge_ )
04060 {
04061 edge_.parent().container().m_flags.set( xtl_flag_runtime_find );
04062 trace_prolog( edge_, "!" );
04063 return trace_epilog( edge_, m_predicate( edge_ ) );
04064 }
04065
04082 template< typename UniverseT >
04083 size_t bang_find( UniverseT& edge_ )
04084 {
04085 edge_.parent().container().m_flags.set( xtl_flag_runtime_bang_find );
04086 trace_prolog( edge_, "!!" );
04087 return trace_epilog( edge_, m_predicate( edge_ ) );
04088 }
04089
04090 };
04091
04092
04118 template< typename Static_predicateT >
04119 inline xtl_wrap< xtl_static_traced_predicate< Static_predicateT > >
04120 xtl_traced_rule( int line_, char const* rule_name_, const Static_predicateT pred_ )
04121 {
04122 return xtl_wrap< xtl_static_traced_predicate< Static_predicateT > >(
04123 xtl_static_traced_predicate< Static_predicateT >(
04124 line_,
04125 rule_name_,
04126 pred_
04127 )
04128 );
04129 }
04130
04160 template< typename ObjectT, typename PredicateT >
04161 inline xtl_wrap< xtl_member_traced_predicate< ObjectT, PredicateT > >
04162 xtl_traced_rule( int line_, char const* rule_name_, ObjectT& object_ref_, PredicateT pred_ )
04163 {
04164 return xtl_wrap< xtl_member_traced_predicate< ObjectT, PredicateT > >(
04165 xtl_member_traced_predicate< ObjectT, PredicateT >(
04166 line_,
04167 rule_name_,
04168 object_ref_,
04169 pred_
04170 )
04171 );
04172 }
04173
04174 }
04175
04176 #endif // _CTTL_XTL_PRIMARY_H_INCLUDED_