@@ -50,16 +50,32 @@ using NodeVariant =
50
50
51
51
using TokenIterator = std::vector<lexer::Token>::const_iterator;
52
52
53
+ // Trait to check for the presence of the stringify method
54
+ template <typename T, typename = void >
55
+ struct has_stringify : std::false_type {};
56
+
57
+ template <typename T>
58
+ struct has_stringify <T, std::void_t <decltype (std::declval<T>().stringify())>>
59
+ : std::true_type {};
60
+
61
+ // Placeholder value
62
+ constexpr const char *placeholder = " <no stringify>" ;
63
+
53
64
static int indent_level (int modify) {
54
65
static int indent = 0 ;
55
66
indent += modify;
56
- for (int i = 0 ; i < indent; ++i) {
57
- std::cerr << ' ' ;
58
- }
59
- std::cerr << ' (' << indent << " ) " ;
60
67
return indent;
61
68
}
62
69
70
+ static std::string indent_str () {
71
+ std::stringstream r;
72
+ for (int i = 0 ; i < indent_level (0 ); ++i) {
73
+ r << ' ' ;
74
+ }
75
+ r << " (" << indent_level (0 ) << " )" ;
76
+ return r.str ();
77
+ }
78
+
63
79
static bool trace_enabled () {
64
80
static bool r = getenv (" GRAMMAR_TRACER" ) != nullptr ;
65
81
return r;
@@ -69,12 +85,23 @@ static bool trace_enabled() {
69
85
70
86
template <typename ParserContext> class Tracer {
71
87
public:
72
- static void output_tokens ( const TokenIterator begin,
73
- const TokenIterator end) {
88
+ using TokenIterator = ParserContext:: TokenIterator;
89
+ static void output_tokens (TokenIterator begin, TokenIterator end) {
74
90
int max = 10 ;
91
+ std::cerr << " (" << &begin << " -" << &end << " ) " ;
92
+ std::cerr << " [" << std::distance (begin, end) << " ]:" ;
75
93
TokenIterator b = begin;
76
94
while (max > 0 && b != end) {
77
- std::cerr << " " << std::visit ([&](auto t) { return t.stringify (); }, *b);
95
+ std::cerr << " "
96
+ << std::visit (
97
+ [&](auto t) {
98
+ if constexpr (has_stringify<decltype (t)>::value) {
99
+ return t.stringify ();
100
+ } else {
101
+ return placeholder;
102
+ }
103
+ },
104
+ *b);
78
105
b++;
79
106
max--;
80
107
}
@@ -83,37 +110,39 @@ template <typename ParserContext> class Tracer {
83
110
}
84
111
}
85
112
86
- using TokenIterator = ParserContext::TokenIterator;
87
113
template <typename ... Args>
88
- static void trace_start (const char *attempt_type, const TokenIterator & begin,
89
- const TokenIterator & end, Args... args) {
114
+ static void trace_start (const char *attempt_type, TokenIterator begin,
115
+ TokenIterator end, Args... args) {
90
116
if (!trace_enabled ())
91
117
return ;
92
- indent_level (1 );
93
- std::cerr << " > " << attempt_type << " " << ParserContext::name << " ("
94
- << sizeof ...(args) << " ):" ;
118
+ std::cerr << indent_str () << " > " << attempt_type << " "
119
+ << ParserContext::name << " (" << sizeof ...(args) << " ):" ;
95
120
output_tokens (begin, end);
96
- std::cerr << std::endl;
121
+ std::cerr << std::endl << std::flush;
122
+ indent_level (1 );
97
123
}
98
124
template <typename ... Args>
99
- static void trace_success (const TokenIterator & begin,
100
- const TokenIterator & end, Args... args) {
125
+ static void trace_success (const char *attempt_type, TokenIterator begin,
126
+ TokenIterator end, Args... args) {
101
127
if (!trace_enabled ())
102
128
return ;
103
129
indent_level (-1 );
104
- std::cerr << " < " << ParserContext::name << " [SUCCESS]" ;
130
+ std::cerr << indent_str () << " < " << attempt_type << " "
131
+ << ParserContext::name << " [SUCCESS]" ;
105
132
output_tokens (begin, end);
106
- std::cerr << std::endl;
133
+ std::cerr << std::endl << std::flush;
134
+ ;
107
135
}
108
136
template <typename ... Args>
109
- static void trace_fail (const TokenIterator &begin, const TokenIterator &end ,
110
- Args... args) {
137
+ static void trace_fail (const char *attempt_type, TokenIterator begin ,
138
+ TokenIterator end, Args... args) {
111
139
if (!trace_enabled ())
112
140
return ;
113
141
indent_level (-1 );
114
- std::cerr << " < " << ParserContext::name << " [FAIL]" ;
142
+ std::cerr << indent_str () << " < " << attempt_type << " "
143
+ << ParserContext::name << " [FAIL]" ;
115
144
output_tokens (begin, end);
116
- std::cerr << std::endl;
145
+ std::cerr << std::endl << std::flush ;
117
146
}
118
147
};
119
148
0 commit comments