e0115eea5a
[SVN r53537]
271 lines
15 KiB
HTML
271 lines
15 KiB
HTML
<html>
|
|
<head>
|
|
<title>Debugging</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
|
</head>
|
|
|
|
<body>
|
|
<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
|
|
<tr>
|
|
<td width="10">
|
|
</td>
|
|
<td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Debugging</b></font>
|
|
</td>
|
|
<td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table border="0">
|
|
<tr>
|
|
<td width="10"></td>
|
|
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
|
<td width="30"><a href="position_iterator.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
|
<td width="30"><a href="error_handling.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
|
</tr>
|
|
</table>
|
|
<p>The top-down nature of Spirit makes the generated parser easy to micro- debug
|
|
using the standard debugger bundled with the C++ compiler we are using. With
|
|
recursive-descent, the parse traversal utilizes the hardware stack through C++
|
|
function call mechanisms. There are no difficult to debug tables or state machines
|
|
that obscure the parsing logic flow. The stack trace we see in the debugger
|
|
follows faithfully the hierarchical grammar structure.</p>
|
|
<p> Since any production rule can initiate a parse traversal , it is a lot easier
|
|
to pinpoint the bugs by focusing on one or a few rules. For relatively complex
|
|
parsing tasks, the same way we write robust C++ programs, it is advisable to
|
|
develop a grammar iteratively on a per-module basis where each module is a small
|
|
subset of the complete grammar. That way, we can stress-test individual modules
|
|
piecemeal until we reach the top-most module. For instance, when developing
|
|
a scripting language, we can start with expressions, then move on to statements,
|
|
then functions, upwards until we have a complete grammar. </p>
|
|
<p> At some point when the grammar gets quite complicated, it is desirable to
|
|
visualize the parse traversal and see what's happening. There are some facilities
|
|
in the framework that aid in the visualisation of the parse traversal for the
|
|
purpose of debugging. The following macros enable these features.</p>
|
|
<a name="debugging_macros"></a>
|
|
<h2>Debugging Macros</h2>
|
|
<a name="spirit_assert_exception"></a>
|
|
<h3>BOOST_SPIRIT_ASSERT_EXCEPTION</h3>
|
|
<p> Spirit contains assertions that may activate when spirit is used incorrectly.
|
|
By default these assertions use the assert macro from the standard library.
|
|
If you want spirit to throw an exception instead, define <tt>BOOST_SPIRIT_ASSERT_EXCEPTION</tt>
|
|
to the name of the class that you want to be thrown. This class's constructor
|
|
will be passed a <tt>const char*</tt> stringified version of the file, line,
|
|
and assertion condition, when it is thrown. If you want to totally disable the
|
|
assertion, <tt>#define NDEBUG</tt>.</p>
|
|
<a name="spirit_debug"></a>
|
|
<h3>BOOST_SPIRIT_DEBUG</h3>
|
|
<p>Define this to enable debugging.</p>
|
|
<p>With debugging enabled, special output is generated at key points of the
|
|
parse process, using the standard output operator (<tt><span class="keyword">operator</span><span class="special"><<</span></tt>)
|
|
with <tt>BOOST_SPIRIT_DEBUG_OUT</tt> (default is <tt><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></tt>,
|
|
see below) as its left operand.</p>
|
|
<table width="80%" border="0" align="center">
|
|
<tr>
|
|
<td class="note_box"><img src="theme/note.gif"> In order to use spirit's
|
|
debugging support you must ensure that appropriate overloads of
|
|
<tt><span class="identifier">operator</span><span class="special"><<</span></tt>
|
|
taking <tt>BOOST_SPIRIT_DEBUG_OUT</tt> as its left operand are available.
|
|
The expected semantics are those of the standard output operator.<br>
|
|
<br>
|
|
These overloads may be provided either within the namespace where the
|
|
corresponding class is declared (will be found through Argument Dependent Lookup) or [within an
|
|
anonymous namespace] within <tt><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span></tt>,
|
|
so it is visible where it is called.<br>
|
|
<br>
|
|
<img src="theme/alert.gif"> Note in particular that when <tt>BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES</tt>
|
|
is set, overloads of <tt><span class="identifier">operator</span><span class="special"><<</span></tt>
|
|
taking instances of the types used in closures as their right operands are required.<br>
|
|
<br>
|
|
You may find an example of overloading the output operator for
|
|
<tt><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></tt>
|
|
in a <a href="faq.html#output_operator">related FAQ entry</a>.</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p>By default, if the <tt>BOOST_SPIRIT_DEBUG</tt> macro is defined, all available
|
|
debug output is generated. To fine tune the amount of generated text you can
|
|
define the <tt>BOOST_SPIRIT_DEBUG_FLAGS</tt> constant to be equal of a combination
|
|
of the following flags:</p>
|
|
<table width="90%" border="0" align="center">
|
|
<tr>
|
|
<td colspan="2" class="table_title"><b>Available flags to fine tune debug
|
|
output </b></td>
|
|
</tr>
|
|
<tr>
|
|
<td width="29%" height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_NODES</tt></td>
|
|
<td width="71%" class="table_cells"><p>print information about nodes (general
|
|
for all parsers)</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_TREES</tt></td>
|
|
<td class="table_cells"><p>print information about parse trees and AST's (general
|
|
for all tree parsers)</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES</tt></td>
|
|
<td class="table_cells">print information about closures (general for all
|
|
parsers with closures)</td>
|
|
</tr>
|
|
<tr>
|
|
<td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_ESCAPE_CHAR</tt></td>
|
|
<td class="table_cells"><p>print information out of the <tt>esc_char_parser</tt></p></td>
|
|
</tr>
|
|
<tr>
|
|
<td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_SLEX</tt></td>
|
|
<td class="table_cells">print information out of the <tt>SLEX</tt> parser</td>
|
|
</tr>
|
|
</table>
|
|
<p><a name="spirit_debug_out"></a> </p>
|
|
<h3>BOOST_SPIRIT_DEBUG_OUT</h3>
|
|
<p> Define this to redirect the debugging diagnostics printout to somewhere else
|
|
(e.g. a file or stream). Defaults to <tt>std::cout</tt>.</p>
|
|
<a name="spirit_debug_token printer"></a>
|
|
<h3>BOOST_SPIRIT_DEBUG_TOKEN_PRINTER</h3>
|
|
<p> The <tt>BOOST_SPIRIT_DEBUG_TOKEN_PRINTER</tt> macro allows you to redefine the way characters are printed on the stream. </p>
|
|
<p>If <tt>BOOST_SPIRIT_DEBUG_OUT</tt> is of type <tt>StreamT</tt>, the character type is <tt>CharT</tt> and <tt>BOOST_SPIRIT_DEBUG_TOKEN_PRINTER</tt> is
|
|
defined to <tt>foo</tt>, it must be compatible with this usage:</p>
|
|
<pre><code><span class=identifier> foo</span><span class=special>(</span><span class=identifier>StreamT</span><span class=special>, </span><span class=identifier>CharT</span><span class=special>)</span></code></pre>
|
|
<p>The default printer requires <tt>operator<<(StreamT, CharT)</tt> to
|
|
be defined. Additionaly, if <tt>CharT</tt> is convertible to a normal character
|
|
type (<tt>char</tt>, <tt>wchar_t</tt> or <tt>int</tt>), it prints control
|
|
characters in a friendly manner (e.g., when it receives <span class=special>'\n'</span> it
|
|
actually prints the <span class=special>\</span> and <span class=special>n</span> charactes,
|
|
instead of a newline).</p>
|
|
<a name="spirit_debug_print_some"></a>
|
|
<h3>BOOST_SPIRIT_DEBUG_PRINT_SOME</h3>
|
|
<p> The <tt>BOOST_SPIRIT_DEBUG_PRINT_SOME</tt> constant defines the number of
|
|
characters from the stream to be printed for diagnosis. This defaults to the
|
|
first 20 characters.</p>
|
|
<p><a name="spirit_debug_tracenode"></a> </p>
|
|
<h3>BOOST_SPIRIT_DEBUG_TRACENODE</h3>
|
|
<p> By default all parser nodes are traced. This constant may be used to redefine
|
|
this default. If this is <tt>1</tt> (<tt>true</tt>), then tracing is enabled
|
|
by default, if this constant is <tt>0</tt> (<tt>false</tt>), the tracing is
|
|
disabled by default. This preprocessor constant is set to <tt>1 </tt>(<tt>true</tt>)
|
|
by default.</p>
|
|
<p>Please note, that the following <tt>BOOST_SPIRIT_DEBUG_...() </tt>macros are
|
|
to be used at function scope only.</p>
|
|
<a name="spirit_debug_node_p_"></a>
|
|
<h3>BOOST_SPIRIT_DEBUG_NODE(p)</h3>
|
|
<p> Define this to print some debugging diagnostics for parser p. This macro</p>
|
|
<ul>
|
|
<li>Registers the parser name for debugging</li>
|
|
<li>Enables/disables the tracing for parser depending on <tt>BOOST_SPIRIT_DEBUG_TRACENODE</tt></li>
|
|
</ul>
|
|
<p> <b>Pre-parse</b>: Before entering the rule, the rule name followed by a peek
|
|
into the data at the current iterator position is printed.</p>
|
|
<p> <b>Post-parse</b>: After parsing the rule, the rule name followed by a peek
|
|
into the data at the current iterator position is printed. Here, <tt>'/'</tt>
|
|
before the rule name flags a succesful match while <tt>'#'</tt> before the rule
|
|
name flags an unsuccesful match.</p>
|
|
<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_NODE</tt></p>
|
|
<ol>
|
|
<li>BOOST_SPIRIT_DEBUG_RULE</li>
|
|
<li>BOOST_SPIRIT_DEBUG_GRAMMAR</li>
|
|
</ol>
|
|
<a name="spirit_trace_node_p__flag_"></a>
|
|
<h3>BOOST_SPIRIT_DEBUG_TRACE_NODE(p, flag)</h3>
|
|
<p> Similar to <tt>BOOST_SPIRIT_DEBUG_NODE</tt>. Additionally allows selective debugging.
|
|
This is useful in situations where we want to debug just a hand picked set of
|
|
nodes.</p>
|
|
<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_TRACE_NODE</tt></p>
|
|
<ol>
|
|
<li>BOOST_SPIRIT_DEBUG_TRACE_RULE</li>
|
|
<li>BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR</li>
|
|
</ol>
|
|
<p><a name="spirit_trace_node_p__flag__name_"></a> </p>
|
|
<h3>BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(p, name, flag)</h3>
|
|
<p> Similar to <tt>BOOST_SPIRIT_DEBUG_NODE</tt>. Additionally allows selective
|
|
debugging and allows to specify the name used during debug printout. This is
|
|
useful in situations where we want to debug just a hand picked set of nodes.
|
|
The <tt>name</tt> may be redefined in situations, where the parser parameter does not reflect the name of the parser to debug.</p>
|
|
<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_TRACE_NODE</tt></p>
|
|
<ol>
|
|
<li>BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME</li>
|
|
<li>BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME</li>
|
|
</ol>
|
|
<hr>
|
|
<p>Here's the original calculator with debugging features enabled:</p>
|
|
<pre>
|
|
<code><span class=preprocessor>#define </span><span class=identifier>BOOST_SPIRIT_DEBUG </span><span class=comment>///$$$ DEFINE THIS BEFORE ANYTHING ELSE $$$///
|
|
</span><span class=preprocessor>#include </span><span class=string>"boost/spirit/include/classic.hpp"
|
|
|
|
</span><span class=comment>/***/
|
|
|
|
/*** CALCULATOR GRAMMAR DEFINITIONS HERE ***/
|
|
|
|
</span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>integer</span><span class=special>);
|
|
</span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>group</span><span class=special>);
|
|
</span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>factor</span><span class=special>);
|
|
</span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>term</span><span class=special>);
|
|
</span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>expr</span><span class=special>);
|
|
</span></code></pre>
|
|
<p> <img src="theme/note.gif" width="16" height="16"> Be sure to add the macros <strong>inside</strong> the grammar definition's constructor. Now here's a sample session with the calculator.</p>
|
|
|
|
<pre><code> <span class="preprocessor">Type an expression...or [q or Q] to quit</span>
|
|
|
|
<span class="preprocessor">1 + 2</span>
|
|
|
|
grammar(calc): "1 + 2"
|
|
rule(expression): "1 + 2"
|
|
rule(term): "1 + 2"
|
|
rule(factor): "1 + 2"
|
|
rule(integer): "1 + 2"
|
|
<span class="preprocessor">push 1</span>
|
|
/rule(integer): " + 2"
|
|
/rule(factor): " + 2"
|
|
/rule(term): " + 2"
|
|
rule(term): "2"
|
|
rule(factor): "2"
|
|
rule(integer): "2"
|
|
<span class="preprocessor">push 2</span>
|
|
/rule(integer): ""
|
|
/rule(factor): ""
|
|
/rule(term): ""
|
|
<span class="preprocessor">popped 1 and 2 from the stack. pushing 3 onto the stack.</span>
|
|
/rule(expression): ""
|
|
/grammar(calc): ""
|
|
<span class="preprocessor">-------------------------
|
|
Parsing succeeded
|
|
result = 3
|
|
-------------------------</span></code></pre>
|
|
|
|
<p> We typed in "1 + 2". Notice that there are two successful branches
|
|
from the top rule <tt>expr</tt>. The text in red is generated by the parser's
|
|
semantic actions while the others are generated by the debug-diagnostics of
|
|
our rules. Notice how the first <tt>integer</tt> rule took "1", the
|
|
first <tt>term</tt> rule took "+" and finally the second <tt>integer</tt>
|
|
rule took "2".</p>
|
|
<p>Please note the special meaning of the first characters appearing on the printed
|
|
lines:</p>
|
|
<ul>
|
|
<li>a single <span class="literal">'/'</span> starts a line containing the information
|
|
about a successfully matched parser node (<tt>rule<></tt>, <tt>grammar<></tt>
|
|
or <tt>subrule<></tt>)</li>
|
|
<li>a single <span class="literal">'#'</span> starts a line containing the information
|
|
about a failed parser node</li>
|
|
<li>a single <span class="literal">'^'</span> starts a line containing the first member (return value/synthesised
|
|
attribute) of the closure of a successfully matched parser node.</li>
|
|
</ul>
|
|
<p>Check out <a href="../example/fundamental/calc_debug.cpp">calc_debug.cpp</a> to see debugging in action. </p>
|
|
<table border="0">
|
|
<tr>
|
|
<td width="10"></td>
|
|
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
|
<td width="30"><a href="position_iterator.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
|
<td width="30"><a href="error_handling.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<hr size="1">
|
|
<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br>
|
|
Copyright © 2003 Hartmut Kaiser<br>
|
|
<br>
|
|
<font size="2">Use, modification and distribution is subject to 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)</font></p>
|
|
<p class="copyright"> </p>
|
|
</body>
|
|
</html>
|