1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
// Copyright (c) 2019-2020 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/
#ifndef TAO_JSON_PEGTL_CONTRIB_PARSE_TREE_TO_DOT_HPP
#define TAO_JSON_PEGTL_CONTRIB_PARSE_TREE_TO_DOT_HPP
#include <cassert>
#include <ostream>
#include <string>
#include "parse_tree.hpp"
namespace TAO_JSON_PEGTL_NAMESPACE::parse_tree
{
namespace internal
{
inline void escape( std::ostream& os, const std::string_view s )
{
static const char* h = "0123456789abcdef";
const char* p = s.data();
const char* l = p;
const char* const e = s.data() + s.size();
while( p != e ) {
const unsigned char c = *p;
if( c == '\\' ) {
os.write( l, p - l );
l = ++p;
os << "\\\\\\\\";
}
else if( c == '"' ) {
os.write( l, p - l );
l = ++p;
os << "\\\\\\\"";
}
else if( c < 32 ) {
os.write( l, p - l );
l = ++p;
switch( c ) {
case '\b':
os << "\\\\b";
break;
case '\f':
os << "\\\\f";
break;
case '\n':
os << "\\\\n";
break;
case '\r':
os << "\\\\r";
break;
case '\t':
os << "\\\\t";
break;
default:
os << "\\\\u00" << h[ ( c & 0xf0 ) >> 4 ] << h[ c & 0x0f ];
}
}
else if( c == 127 ) {
os.write( l, p - l );
l = ++p;
os << "\\\\u007f";
}
else {
++p;
}
}
os.write( l, p - l );
}
template< typename Node >
void print_dot_node( std::ostream& os, const Node& n, const std::string_view s )
{
os << " x" << &n << " [ label=\"";
escape( os, s );
if( n.has_content() ) {
os << "\\n\\\"";
escape( os, n.string_view() );
os << "\\\"";
}
os << "\" ]\n";
if( !n.children.empty() ) {
os << " x" << &n << " -> { ";
for( auto& up : n.children ) {
os << "x" << up.get() << ( ( up == n.children.back() ) ? " }\n" : ", " );
}
for( auto& up : n.children ) {
print_dot_node( os, *up, up->type );
}
}
}
} // namespace internal
template< typename Node >
void print_dot( std::ostream& os, const Node& n )
{
os << "digraph parse_tree\n{\n";
internal::print_dot_node( os, n, n.is_root() ? "ROOT" : n.type );
os << "}\n";
}
} // namespace TAO_JSON_PEGTL_NAMESPACE::parse_tree
#endif
|