Imported existing code
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2009 Hartmut Kaiser
|
||||
Copyright (c) 2001-2007 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_HANDLER_NOV_12_2007_0926AM)
|
||||
#define BOOST_SPIRIT_DEBUG_HANDLER_NOV_12_2007_0926AM
|
||||
|
||||
#include <boost/spirit/home/qi/nonterminal/virtual_component_base.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace debug
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This class is to avoid linker problems and to ensure a real singleton
|
||||
// 'level' variable
|
||||
static int& get_trace_level()
|
||||
{
|
||||
static int level = 0;
|
||||
return level;
|
||||
}
|
||||
|
||||
struct trace_level
|
||||
{
|
||||
trace_level(int &level)
|
||||
: level(level)
|
||||
{
|
||||
++level;
|
||||
}
|
||||
~trace_level()
|
||||
{
|
||||
--level;
|
||||
}
|
||||
|
||||
int& level;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename Iterator, typename Context, typename Skipper,
|
||||
typename PreParseF, typename PostParseF
|
||||
>
|
||||
struct debug_handler
|
||||
: virtual_component_base<Iterator, Context, Skipper>
|
||||
{
|
||||
typedef
|
||||
virtual_component_base<Iterator, Context, Skipper>
|
||||
base_type;
|
||||
typedef intrusive_ptr<base_type> pointer_type;
|
||||
typedef typename base_type::skipper_type skipper_type;
|
||||
|
||||
debug_handler(pointer_type subject, std::string const& name,
|
||||
bool trace, PreParseF preF, PostParseF postF)
|
||||
: subject(subject), name(name), trace(trace),
|
||||
preF(preF), postF(postF)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Skipper_>
|
||||
bool parse_main(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Context& context
|
||||
, Skipper_ const& skipper)
|
||||
{
|
||||
// execute embedded parser if tracing is disabled or if the
|
||||
// pre-parse hook returns true
|
||||
bool r = false;
|
||||
if (!trace || preF(name, subject, get_trace_level(), first, last))
|
||||
{
|
||||
{
|
||||
trace_level level(get_trace_level());
|
||||
|
||||
// do the actual parsing
|
||||
Iterator i = first;
|
||||
r = subject->parse(i, last, context, skipper);
|
||||
if (r)
|
||||
first = i;
|
||||
}
|
||||
|
||||
// the post-parse hook gets executed only if tracing is enabled
|
||||
if (trace)
|
||||
postF(r, name, subject, get_trace_level(), first, last);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Context& context
|
||||
, skipper_type const& skipper)
|
||||
{
|
||||
return parse_main(first, last, context, skipper);
|
||||
}
|
||||
|
||||
virtual bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Context& context
|
||||
, no_skipper)
|
||||
{
|
||||
return parse_main(first, last, context, unused);
|
||||
}
|
||||
|
||||
pointer_type subject;
|
||||
std::string const& name;
|
||||
bool trace;
|
||||
PreParseF preF;
|
||||
PostParseF postF;
|
||||
};
|
||||
|
||||
}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,129 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2009 Hartmut Kaiser
|
||||
Copyright (c) 2001-2007 Joel de Guzman
|
||||
Copyright (c) 2003 Gustavo Guerra
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_PRINT_NODE_INFO_NOV_12_2007_1045AM)
|
||||
#define BOOST_SPIRIT_PRINT_NODE_INFO_NOV_12_2007_1045AM
|
||||
|
||||
#include <cctype> // iscntrl
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace debug
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct token_printer_aux_for_chars
|
||||
{
|
||||
template<typename Char>
|
||||
static void print(std::ostream& o, Char c)
|
||||
{
|
||||
using namespace std; // allow for ADL to find the proper iscntrl
|
||||
|
||||
if (c == static_cast<Char>('\a'))
|
||||
o << "\\a";
|
||||
|
||||
else if (c == static_cast<Char>('\b'))
|
||||
o << "\\b";
|
||||
|
||||
else if (c == static_cast<Char>('\f'))
|
||||
o << "\\f";
|
||||
|
||||
else if (c == static_cast<Char>('\n'))
|
||||
o << "\\n";
|
||||
|
||||
else if (c == static_cast<Char>('\r'))
|
||||
o << "\\r";
|
||||
|
||||
else if (c == static_cast<Char>('\t'))
|
||||
o << "\\t";
|
||||
|
||||
else if (c == static_cast<Char>('\v'))
|
||||
o << "\\v";
|
||||
|
||||
else if (iscntrl(c))
|
||||
o << "\\" << std::oct << static_cast<int>(c);
|
||||
|
||||
else
|
||||
o << static_cast<char>(c);
|
||||
}
|
||||
};
|
||||
|
||||
// for token types where the comparison with char constants wouldn't work
|
||||
struct token_printer_aux_for_other_types
|
||||
{
|
||||
template<typename Char>
|
||||
static void print(std::ostream& o, Char c)
|
||||
{
|
||||
o << c;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct token_printer_aux
|
||||
: mpl::if_<
|
||||
mpl::and_<
|
||||
is_convertible<Char, char>,
|
||||
is_convertible<char, Char>
|
||||
>,
|
||||
token_printer_aux_for_chars,
|
||||
token_printer_aux_for_other_types
|
||||
>::type
|
||||
{};
|
||||
|
||||
template<typename Char>
|
||||
inline void token_printer(std::ostream& o, Char c)
|
||||
{
|
||||
// allow to customize the token printer routine
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_TOKEN_PRINTER)
|
||||
token_printer_aux<Char>::print(o, c);
|
||||
#else
|
||||
BOOST_SPIRIT_DEBUG_TOKEN_PRINTER(o, c);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator>
|
||||
inline void
|
||||
print_node_info(bool hit, int level, bool close, std::string const& name,
|
||||
Iterator /*first*/, Iterator const& /*last*/)
|
||||
{
|
||||
if (!name.empty())
|
||||
{
|
||||
for (int i = 0; i < level; ++i)
|
||||
BOOST_SPIRIT_DEBUG_OUT << " ";
|
||||
|
||||
if (close) {
|
||||
if (hit)
|
||||
BOOST_SPIRIT_DEBUG_OUT << "/";
|
||||
else
|
||||
BOOST_SPIRIT_DEBUG_OUT << "#";
|
||||
}
|
||||
|
||||
// BOOST_SPIRIT_DEBUG_OUT << name << ":\t\"";
|
||||
// for (int j = 0; j < BOOST_SPIRIT_DEBUG_PRINT_SOME; ++j)
|
||||
// {
|
||||
// if (first == last)
|
||||
// break;
|
||||
//
|
||||
// token_printer(BOOST_SPIRIT_DEBUG_OUT, *first);
|
||||
// ++first;
|
||||
// }
|
||||
// BOOST_SPIRIT_DEBUG_OUT << "\"\n";
|
||||
BOOST_SPIRIT_DEBUG_OUT << name << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2009 Hartmut Kaiser
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_MINIMAL_MACROS_NOV_12_2007_1047AM)
|
||||
#define BOOST_SPIRIT_MINIMAL_MACROS_NOV_12_2007_1047AM
|
||||
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_NOV_12_2007_0827AM)
|
||||
#error "You must include boost/spirit/home/qi/debug.hpp, not this file"
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Minimum debugging tools support
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_OUT)
|
||||
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Empty implementations of the debug macros above, if no debug support is
|
||||
// required
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
|
||||
#define BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(r, n, t)
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
|
||||
#define BOOST_SPIRIT_DEBUG_TRACE_NODE(r, t)
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_NODE)
|
||||
#define BOOST_SPIRIT_DEBUG_NODE(r)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2009 Hartmut Kaiser
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SIMPLE_DEBUG_NOV_12_2007_1155AM)
|
||||
#define BOOST_SPIRIT_SIMPLE_DEBUG_NOV_12_2007_1155AM
|
||||
|
||||
#include <boost/spirit/home/qi/debug/detail/debug_handler.hpp>
|
||||
#include <boost/spirit/home/qi/debug/detail/print_node_info.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
|
||||
#include <string>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace qi { namespace debug
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Simple pre-parse hook allowing to print the context before a rule is
|
||||
// parsed.
|
||||
template <typename Subject, typename Iterator>
|
||||
inline bool
|
||||
simple_pre_parse(std::string const& name, Subject subject,
|
||||
unsigned level, Iterator first, Iterator const& last)
|
||||
{
|
||||
detail::print_node_info(false, level, false, name, first, last);
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Simple post-parse hook allowing to print the context after a rule is
|
||||
// parsed.
|
||||
template <typename Subject, typename Iterator>
|
||||
inline void
|
||||
simple_post_parse(bool hit, std::string const& name, Subject subject,
|
||||
unsigned level, Iterator first, Iterator const& last)
|
||||
{
|
||||
detail::print_node_info(hit, level, true, name, first, last);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Nonterminal>
|
||||
inline void
|
||||
enable_simple_debug_support(Nonterminal& r, bool trace)
|
||||
{
|
||||
typedef typename Nonterminal::iterator_type iterator_type;
|
||||
typedef typename Nonterminal::pointer_type pointer_type;
|
||||
|
||||
typedef bool (*pre_parse_functor_type)(std::string const&,
|
||||
pointer_type, unsigned, iterator_type, iterator_type const&);
|
||||
typedef void (*post_parse_functor_type)(bool, std::string const&,
|
||||
pointer_type, unsigned, iterator_type, iterator_type const&);
|
||||
|
||||
typedef
|
||||
detail::debug_handler<
|
||||
iterator_type,
|
||||
typename Nonterminal::base_type::context_type,
|
||||
typename Nonterminal::skipper_type,
|
||||
pre_parse_functor_type,
|
||||
post_parse_functor_type>
|
||||
simple_debug_handler;
|
||||
|
||||
pre_parse_functor_type pre =
|
||||
&simple_pre_parse<pointer_type, iterator_type>;
|
||||
post_parse_functor_type post =
|
||||
&simple_post_parse<pointer_type, iterator_type>;
|
||||
decorate<simple_debug_handler>(r, r.name(), trace, pre, post);
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2009 Hartmut Kaiser
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SIMPLE_DEBUG_MACROS_NOV_12_2007_0828AM)
|
||||
#define BOOST_SPIRIT_SIMPLE_DEBUG_MACROS_NOV_12_2007_0828AM
|
||||
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_NOV_12_2007_0827AM)
|
||||
#error "You must include boost/spirit/home/qi/debug.hpp, not this file"
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Make sure all required debug helper macros are defined properly
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
|
||||
#define BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(r, n, t) \
|
||||
r.name(n); \
|
||||
boost::spirit::qi::debug::enable_simple_debug_support(r, t) \
|
||||
/**/
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
|
||||
#define BOOST_SPIRIT_DEBUG_TRACE_NODE(r, t) \
|
||||
if (r.name().empty()) r.name(#r); \
|
||||
boost::spirit::qi::debug::enable_simple_debug_support(r, t) \
|
||||
/**/
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_NODE)
|
||||
#define BOOST_SPIRIT_DEBUG_NODE(r) \
|
||||
BOOST_SPIRIT_DEBUG_TRACE_NODE(r, true) \
|
||||
/**/
|
||||
#endif
|
||||
|
||||
// number of input tokens to print while debugging
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME)
|
||||
#define BOOST_SPIRIT_DEBUG_PRINT_SOME 20
|
||||
#endif
|
||||
|
||||
// The stream to use for debug output
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_OUT)
|
||||
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user