| <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> |