mirror of
https://github.com/geode-sdk/geode.git
synced 2024-12-04 05:01:06 -05:00
227 lines
8.6 KiB
C++
Executable file
227 lines
8.6 KiB
C++
Executable file
// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey
|
|
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/
|
|
|
|
#ifndef TAO_PEGTL_CONTRIB_TRACE_HPP
|
|
#define TAO_PEGTL_CONTRIB_TRACE_HPP
|
|
|
|
#include <cstddef>
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
#include <string_view>
|
|
#include <tuple>
|
|
|
|
#include "state_control.hpp"
|
|
|
|
#include "../apply_mode.hpp"
|
|
#include "../config.hpp"
|
|
#include "../demangle.hpp"
|
|
#include "../normal.hpp"
|
|
#include "../nothing.hpp"
|
|
#include "../parse.hpp"
|
|
#include "../rewind_mode.hpp"
|
|
|
|
namespace TAO_PEGTL_NAMESPACE
|
|
{
|
|
template< bool HideInternal = false, bool UseColor = true, std::size_t IndentIncrement = 2, std::size_t InitialIndent = 8 >
|
|
struct tracer_traits
|
|
{
|
|
template< typename Rule >
|
|
static constexpr bool enable = ( HideInternal ? normal< Rule >::enable : true );
|
|
|
|
static constexpr std::size_t initial_indent = InitialIndent;
|
|
static constexpr std::size_t indent_increment = IndentIncrement;
|
|
|
|
static constexpr std::string_view ansi_reset = UseColor ? "\033[m" : "";
|
|
static constexpr std::string_view ansi_rule = UseColor ? "\033[36m" : "";
|
|
static constexpr std::string_view ansi_hide = UseColor ? "\033[37m" : "";
|
|
|
|
static constexpr std::string_view ansi_position = UseColor ? "\033[1;34m" : "";
|
|
static constexpr std::string_view ansi_success = UseColor ? "\033[32m" : "";
|
|
static constexpr std::string_view ansi_failure = UseColor ? "\033[31m" : "";
|
|
static constexpr std::string_view ansi_raise = UseColor ? "\033[1;31m" : "";
|
|
static constexpr std::string_view ansi_unwind = UseColor ? "\033[31m" : "";
|
|
static constexpr std::string_view ansi_apply = UseColor ? "\033[1;36m" : "";
|
|
};
|
|
|
|
using standard_tracer_traits = tracer_traits< true >;
|
|
using complete_tracer_traits = tracer_traits< false >;
|
|
|
|
template< typename TracerTraits >
|
|
struct tracer
|
|
{
|
|
const std::ios_base::fmtflags m_flags;
|
|
std::size_t m_count = 0;
|
|
std::vector< std::size_t > m_stack;
|
|
position m_position;
|
|
|
|
template< typename Rule >
|
|
static constexpr bool enable = TracerTraits::template enable< Rule >;
|
|
|
|
template< typename ParseInput >
|
|
explicit tracer( const ParseInput& in )
|
|
: m_flags( std::cerr.flags() ),
|
|
m_position( in.position() )
|
|
{
|
|
std::cerr << std::left;
|
|
print_position();
|
|
}
|
|
|
|
tracer( const tracer& ) = delete;
|
|
tracer( tracer&& ) = delete;
|
|
|
|
~tracer()
|
|
{
|
|
std::cerr.flags( m_flags );
|
|
}
|
|
|
|
tracer& operator=( const tracer& ) = delete;
|
|
tracer& operator=( tracer&& ) = delete;
|
|
|
|
[[nodiscard]] std::size_t indent() const noexcept
|
|
{
|
|
return TracerTraits::initial_indent + TracerTraits::indent_increment * m_stack.size();
|
|
}
|
|
|
|
void print_position() const
|
|
{
|
|
std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_position << "position" << TracerTraits::ansi_reset << ' ' << m_position << '\n';
|
|
}
|
|
|
|
void update_position( const position& p )
|
|
{
|
|
if( m_position != p ) {
|
|
m_position = p;
|
|
print_position();
|
|
}
|
|
}
|
|
|
|
template< typename Rule, typename ParseInput, typename... States >
|
|
void start( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
|
{
|
|
std::cerr << '#' << std::setw( indent() - 1 ) << ++m_count << TracerTraits::ansi_rule << demangle< Rule >() << TracerTraits::ansi_reset << '\n';
|
|
m_stack.push_back( m_count );
|
|
}
|
|
|
|
template< typename Rule, typename ParseInput, typename... States >
|
|
void success( const ParseInput& in, States&&... /*unused*/ )
|
|
{
|
|
const auto prev = m_stack.back();
|
|
m_stack.pop_back();
|
|
std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_success << "success" << TracerTraits::ansi_reset;
|
|
if( m_count != prev ) {
|
|
std::cerr << " #" << prev << ' ' << TracerTraits::ansi_hide << demangle< Rule >() << TracerTraits::ansi_reset;
|
|
}
|
|
std::cerr << '\n';
|
|
update_position( in.position() );
|
|
}
|
|
|
|
template< typename Rule, typename ParseInput, typename... States >
|
|
void failure( const ParseInput& in, States&&... /*unused*/ )
|
|
{
|
|
const auto prev = m_stack.back();
|
|
m_stack.pop_back();
|
|
std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_failure << "failure" << TracerTraits::ansi_reset;
|
|
if( m_count != prev ) {
|
|
std::cerr << " #" << prev << ' ' << TracerTraits::ansi_hide << demangle< Rule >() << TracerTraits::ansi_reset;
|
|
}
|
|
std::cerr << '\n';
|
|
update_position( in.position() );
|
|
}
|
|
|
|
template< typename Rule, typename ParseInput, typename... States >
|
|
void raise( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
|
{
|
|
std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_raise << "raise" << TracerTraits::ansi_reset << ' ' << TracerTraits::ansi_rule << demangle< Rule >() << TracerTraits::ansi_reset << '\n';
|
|
}
|
|
|
|
template< typename Rule, typename ParseInput, typename... States >
|
|
void unwind( const ParseInput& in, States&&... /*unused*/ )
|
|
{
|
|
const auto prev = m_stack.back();
|
|
m_stack.pop_back();
|
|
std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_unwind << "unwind" << TracerTraits::ansi_reset;
|
|
if( m_count != prev ) {
|
|
std::cerr << " #" << prev << ' ' << TracerTraits::ansi_hide << demangle< Rule >() << TracerTraits::ansi_reset;
|
|
}
|
|
std::cerr << '\n';
|
|
update_position( in.position() );
|
|
}
|
|
|
|
template< typename Rule, typename ParseInput, typename... States >
|
|
void apply( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
|
{
|
|
std::cerr << std::setw( static_cast< int >( indent() - TracerTraits::indent_increment ) ) << ' ' << TracerTraits::ansi_apply << "apply" << TracerTraits::ansi_reset << '\n';
|
|
}
|
|
|
|
template< typename Rule, typename ParseInput, typename... States >
|
|
void apply0( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
|
{
|
|
std::cerr << std::setw( static_cast< int >( indent() - TracerTraits::indent_increment ) ) << ' ' << TracerTraits::ansi_apply << "apply0" << TracerTraits::ansi_reset << '\n';
|
|
}
|
|
|
|
template< typename Rule,
|
|
template< typename... > class Action = nothing,
|
|
template< typename... > class Control = normal,
|
|
typename ParseInput,
|
|
typename... States >
|
|
bool parse( ParseInput&& in, States&&... st )
|
|
{
|
|
return TAO_PEGTL_NAMESPACE::parse< Rule, Action, state_control< Control >::template type >( in, st..., *this );
|
|
}
|
|
};
|
|
|
|
template< typename Rule,
|
|
template< typename... > class Action = nothing,
|
|
template< typename... > class Control = normal,
|
|
typename ParseInput,
|
|
typename... States >
|
|
bool standard_trace( ParseInput&& in, States&&... st )
|
|
{
|
|
tracer< standard_tracer_traits > tr( in );
|
|
return tr.parse< Rule, Action, Control >( in, st... );
|
|
}
|
|
|
|
template< typename Rule,
|
|
template< typename... > class Action = nothing,
|
|
template< typename... > class Control = normal,
|
|
typename ParseInput,
|
|
typename... States >
|
|
bool complete_trace( ParseInput&& in, States&&... st )
|
|
{
|
|
tracer< complete_tracer_traits > tr( in );
|
|
return tr.parse< Rule, Action, Control >( in, st... );
|
|
}
|
|
|
|
template< typename Tracer >
|
|
struct trace
|
|
: maybe_nothing
|
|
{
|
|
template< typename Rule,
|
|
apply_mode A,
|
|
rewind_mode M,
|
|
template< typename... >
|
|
class Action,
|
|
template< typename... >
|
|
class Control,
|
|
typename ParseInput,
|
|
typename... States >
|
|
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
|
{
|
|
if constexpr( sizeof...( st ) == 0 ) {
|
|
return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, state_control< Control >::template type >( in, st..., Tracer( in ) );
|
|
}
|
|
else if constexpr( !std::is_same_v< std::tuple_element_t< sizeof...( st ) - 1, std::tuple< States... > >, Tracer& > ) {
|
|
return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, state_control< Control >::template type >( in, st..., Tracer( in ) );
|
|
}
|
|
else {
|
|
return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... );
|
|
}
|
|
}
|
|
};
|
|
|
|
using trace_standard = trace< tracer< standard_tracer_traits > >;
|
|
using trace_complete = trace< tracer< complete_tracer_traits > >;
|
|
|
|
} // namespace TAO_PEGTL_NAMESPACE
|
|
|
|
#endif
|