Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67230 - sandbox/configurator/boost/configurator/detail
From: for.dshevchenko_at_[hidden]
Date: 2010-12-14 13:04:02


Author: dshevchenko
Date: 2010-12-14 13:03:59 EST (Tue, 14 Dec 2010)
New Revision: 67230
URL: http://svn.boost.org/trac/boost/changeset/67230

Log:
Using Spirit for comments removing!

Text files modified:
   sandbox/configurator/boost/configurator/detail/comments_remover.hpp | 143 ++++++++++++++++++---------------------
   1 files changed, 66 insertions(+), 77 deletions(-)

Modified: sandbox/configurator/boost/configurator/detail/comments_remover.hpp
==============================================================================
--- sandbox/configurator/boost/configurator/detail/comments_remover.hpp (original)
+++ sandbox/configurator/boost/configurator/detail/comments_remover.hpp 2010-12-14 13:03:59 EST (Tue, 14 Dec 2010)
@@ -15,6 +15,11 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/algorithm/string.hpp>
 
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_stl.hpp>
+
 #include <algorithm>
 
 namespace boost {
@@ -31,7 +36,9 @@
 /// \brief Comments remover.
 ///
 /// Removes one-line comments and multi-line comments.
+
 class comments_remover {
+ typedef boost::spirit::qi::rule< string_const_it > simple_rule;
 public:
     comments_remover() :
             one_line_comment_sign( "//" )
@@ -47,95 +54,77 @@
     }
 public:
     void operator()( str_storage& obtained_strings ) const {
- remove_one_line_comments_from( obtained_strings );
- remove_multi_line_comments_from( obtained_strings );
- remove_empty_strings_from( obtained_strings );
- }
-private:
- void remove_one_line_comments_from( str_storage& obtained_strings ) const {
- std::for_each( obtained_strings.begin()
- , obtained_strings.end()
- , boost::bind( &comments_remover::remove_one_line_comment
- , this
- , ::_1 ) );
- trim_all( obtained_strings );
- }
-
- void remove_one_line_comment( std::string& s ) const {
- s.erase( boost::find_first( s, one_line_comment_sign ).begin()
- , s.end() );
+ std::string obtained = concatenate( obtained_strings );
+ std::string without_one_line_comments;
+ bool remove_success = remove_one_line_comments( obtained, without_one_line_comments );
+ if ( remove_success ) {
+ std::string without_comments;
+ remove_success = remove_multi_line_comments( without_one_line_comments
+ , without_comments );
+ if ( remove_success ) {
+ resplit( without_comments, obtained_strings );
+ remove_empty_strings_from( obtained_strings );
+ } else {
+ notify( "Something wrong with multi-line comments!" );
+ }
+ } else {
+ notify( "Something wrong with one-line comments!" );
+ }
     }
 private:
- void remove_multi_line_comments_from( str_storage& obtained_strings ) const {
- if ( at_least_one_multi_line_comment_exists_in( obtained_strings ) ) {
- std::string s = concatenate( obtained_strings );
- std::string uncomment_s = extract_uncomment_strings_from( s );
- resplit( uncomment_s, obtained_strings );
- } else {}
- }
-
- bool at_least_one_multi_line_comment_exists_in( const str_storage& obtained_strings ) const {
- BOOST_FOREACH ( const std::string& s, obtained_strings ) {
- if ( multi_line_comment_exists_in( s ) ) {
- return true;
- } else {}
- }
- return false;
- }
-
- bool multi_line_comment_exists_in( const std::string& s ) const {
- return boost::contains( s, multi_line_comment_begin_sign )
- || boost::contains( s, multi_line_comment_end_sign );
- }
-
     std::string concatenate( const str_storage& obtained_strings ) const {
- std::string conc;
+ std::string result;
         BOOST_FOREACH ( const std::string& s, obtained_strings ) {
- conc += s + '\n';
- }
- return conc;
- }
-
- std::string extract_uncomment_strings_from( const std::string& s ) const {
- string_const_it first_it = s.begin();
- string_const_it end_it = s.end();
- const size_t multi_line_comment_sign_size = 2;
-
- std::string uncomment_strings;
- while ( true ) {
- string_const_it begin_of_comment = std::search( first_it
- , end_it
- , multi_line_comment_begin_sign.begin()
- , multi_line_comment_begin_sign.end() );
- string_const_it end_of_comment = std::search( first_it
- , end_it
- , multi_line_comment_end_sign.begin()
- , multi_line_comment_end_sign.end() );
- if ( end_it == begin_of_comment ) {
- uncomment_strings.append( first_it, end_it );
- break;
- } else if ( end_it == end_of_comment ) {
- notify( "Unclosed multi-line comment detected in line "
- + get_line_number( s, begin_of_comment ) + "!" );
- } else if ( begin_of_comment > end_of_comment ) {
- notify( "Unopened multi-line comment detected in line "
- + get_line_number( s, end_of_comment ) + "!" );
- }
-
- uncomment_strings.append( first_it, begin_of_comment );
- first_it = end_of_comment + multi_line_comment_sign_size;
+ result += s + '\n';
         }
- return uncomment_strings;
+ return result;
     }
 
     void resplit( const std::string& s, str_storage& obtained_strings ) const {
         obtained_strings.clear();
         boost::split( obtained_strings, s, boost::is_any_of( "\n" ) );
     }
+private:
+ bool remove_one_line_comments( const std::string& s, std::string& without_comments ) const {
+ using boost::spirit::qi::_1;
+ using boost::phoenix::push_back;
+ using boost::spirit::qi::lit;
+ using boost::spirit::qi::char_;
+ using boost::spirit::qi::eol;
+ using boost::spirit::qi::lexeme;
+
+ simple_rule comments = lit( one_line_comment_sign )
+ >> *( char_ - eol );
+ simple_rule native =
+ lexeme[ *( char_[ push_back( boost::phoenix::ref(without_comments), _1 ) ]
+ - lit( one_line_comment_sign ) ) ];
+ simple_rule all = native % comments;
+ return factual_parse( s, all );
+ }
+
+ bool remove_multi_line_comments( const std::string& s, std::string& without_comments ) const {
+ using boost::spirit::qi::_1;
+ using boost::phoenix::push_back;
+ using boost::spirit::qi::lit;
+ using boost::spirit::qi::char_;
+ using boost::spirit::qi::lexeme;
+
+ simple_rule comments = lit( multi_line_comment_begin_sign )
+ >> *( char_ - lit( multi_line_comment_end_sign ) )
+ >> lit( multi_line_comment_end_sign );
+ simple_rule native =
+ lexeme[ *( char_[ push_back( boost::phoenix::ref(without_comments), _1 ) ]
+ - lit( multi_line_comment_begin_sign ) ) ];
+ simple_rule all = native % comments;
+ return factual_parse( s, all );
+ }
+
+ bool factual_parse( const std::string& s, const simple_rule& all ) const {
+ string_const_it first = s.begin();
+ string_const_it last = s.end();
 
- std::string get_line_number( const std::string& s, string_const_it it ) const {
- const size_t ln_quantity = (size_t)std::count( s.begin(), it, '\n' );
- return boost::lexical_cast< std::string >( ln_quantity + 1 );
+ bool parse_success = boost::spirit::qi::parse( first, last, all );
+ return parse_success && first == last;
     }
 };
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk