Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #if (defined(_DEBUG) && !defined(MBLQI_DONT_DEBUG_RULES)) || defined(MBLQI_DEBUG_RULES)
- # define MBL_QI_DEBUG_PARSER( pdbg, pname, ppos ) \
- ::mbl::debug_position( pdbg, pname, ppos )
- # define MBL_QI_DEBUG_PARSER_( pdbg, pname, ppos ) MBL_QI_DEBUG_PARSER( pdbg, pname, ppos ) >>
- # define _MBL_QI_DEBUG_PARSER( pdbg, pname, ppos ) >> MBL_QI_DEBUG_PARSER( pdbg, pname, ppos )
- #else
- # define MBL_QI_DEBUG_PARSER( pdbg, pname, ppos )
- # define MBL_QI_DEBUG_PARSER_( pdbg, pname, ppos )
- # define _MBL_QI_DEBUG_PARSER( pdbg, pname, ppos )
- #endif
- #define MBL_QI_DEBUG_MSG_START "<START>"
- #define MBL_QI_DEBUG_MSG_END "<END>"
- #define MBL_QI_DEBUG_PARSER_START( pdbg, pname ) MBL_QI_DEBUG_PARSER_( pdbg, pname, MBL_QI_DEBUG_MSG_START )
- #define MBL_QI_DEBUG_PARSER_END( pdbg, pname ) _MBL_QI_DEBUG_PARSER( pdbg, pname, MBL_QI_DEBUG_MSG_END )
- namespace mbl {
- struct parser_debugger {
- // could be virtual, but I want my type to be POD
- bool (*report)( parser_debugger*, char const* parserName, char const* msg,
- std::string const& pos );
- };
- static bool report_impl_base( parser_debugger*, char const* pname,
- char const* msg, std::string const& pos, std::ostream& os, size_t line_size,
- size_t pname_len, size_t msg_len )
- {
- size_t n = strlen( msg );
- std::string pad;
- if( n < msg_len ) pad.assign( (msg_len - n) / 2, ' ' );
- std::ios_base::fmtflags f = os.flags();
- os.flags( f | std::ios_base::left );
- os << std::setw(pname_len) << pname
- << '(' << pad << std::setw(msg_len - pad.size()) << msg << "): ";
- os.flags( f );
- bool sp = false;
- std::size_t cnt = (std::max<size_t>)(strlen(pname), pname_len) +
- (std::max<size_t>)(n, msg_len) + 4;
- for( auto i = pos.begin(); i != pos.end(); i++ ) {
- char c = *i;
- if( ::isspace(c) ) {
- if( sp ) continue;
- sp = true;
- c = ' ';
- } else {
- sp = false;
- }
- if( cnt++ >= line_size ) {
- os << "...";
- break;
- } else {
- os << c;
- }
- }
- os << std::endl;
- return true;
- }
- static bool report_impl( parser_debugger* pd, char const* pname, char const* msg,
- std::string const& pos )
- {
- return report_impl_base( pd, pname, msg, pos, std::clog, 100, 20, 10 );
- }
- static parser_debugger& default_parser_debugger() {
- static parser_debugger res = { {&report_impl} };
- return res;
- }
- BOOST_SPIRIT_TERMINAL_EX( debug_position );
- struct debug_position_parser : qi::primitive_parser<debug_position_parser> {
- debug_position_parser( parser_debugger* pdebugger, char const* pname, char const* msg )
- : pdebugger_( pdebugger ), pname_( pname ), msg_( msg ) {}
- template< typename ContextT, typename IteratorT >
- struct attribute { typedef spirit::unused_type type; };
- template< typename IteratorT, typename ContextT, typename SkipperT, typename AttributeT >
- bool parse( IteratorT& first, IteratorT const& last, ContextT& context,
- SkipperT const& skipper, AttributeT& attr ) const
- {
- typedef std::iterator_traits<IteratorT>::value_type char_type;
- typedef std::basic_string<char_type> string_type;
- qi::skip_over( first, last, skipper );
- if( !pdebugger_ ) return true;
- pdebugger_->report( pdebugger_, pname_, msg_,
- boost::locale::conv::utf_to_utf<char>(string_type(first, last)) );
- return true;
- }
- template< class ContextT >
- spirit::info what( ContextT& context ) const {
- return spirit::info( "debug_position", expression_ );
- }
- char const* pname_;
- char const* msg_;
- parser_debugger* pdebugger_;
- };
- }
- namespace boost { namespace spirit {
- template<>
- struct use_terminal<qi::domain, mbl::tag::debug_position>
- : mpl::true_ {}; // enable debug_position
- template< typename A0, typename A1, typename A2 >
- struct use_terminal<qi::domain,
- terminal_ex<mbl::tag::debug_position, fusion::vector3<A0, A1, A2> >
- > : is_convertible<A0, mbl::parser_debugger*> {}; // enable debug_position( debugger, name, pos )
- template<>
- struct use_lazy_terminal<qi::domain, mbl::tag::debug_position, 3 /*arity*/>
- : mpl::true_ {}; // enable lazy support for debug_position
- namespace qi {
- template< typename A0, typename A1, typename A2, typename ModifiersT >
- struct make_primitive<
- terminal_ex<mbl::tag::debug_position, fusion::vector3<A0, A1, A2> >, ModifiersT >
- {
- typedef mbl::debug_position_parser result_type;
- template< typename TerminalT >
- result_type operator()( TerminalT const& term, unused_type ) const {
- return result_type( fusion::at_c<0>(term.args),
- fusion::at_c<1>(term.args), fusion::at_c<2>(term.args) );
- }
- };
- }
- } }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement