Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/spirit/doc/debugging.html @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 14.6 KB
Line 
1<html>
2<head>
3<title>Debugging</title>
4<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
5<link rel="stylesheet" href="theme/style.css" type="text/css">
6</head>
7
8<body>
9<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
10  <tr>
11    <td width="10">
12    </td>
13    <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Debugging</b></font>
14    </td>
15    <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td>
16  </tr>
17</table>
18<br>
19<table border="0">
20  <tr>
21    <td width="10"></td>
22    <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
23    <td width="30"><a href="position_iterator.html"><img src="theme/l_arr.gif" border="0"></a></td>
24    <td width="30"><a href="error_handling.html"><img src="theme/r_arr.gif" border="0"></a></td>
25  </tr>
26</table>
27<p>The top-down nature of Spirit makes the generated parser easy to micro- debug
28  using the standard debugger bundled with the C++ compiler we are using. With
29  recursive-descent, the parse traversal utilizes the hardware stack through C++
30  function call mechanisms. There are no difficult to debug tables or state machines
31  that obscure the parsing logic flow. The stack trace we see in the debugger
32  follows faithfully the hierarchical grammar structure.</p>
33<p> Since any production rule can initiate a parse traversal , it is a lot easier
34  to pinpoint the bugs by focusing on one or a few rules. For relatively complex
35  parsing tasks, the same way we write robust C++ programs, it is advisable to
36  develop a grammar iteratively on a per-module basis where each module is a small
37  subset of the complete grammar. That way, we can stress-test individual modules
38  piecemeal until we reach the top-most module. For instance, when developing
39  a scripting language, we can start with expressions, then move on to statements,
40  then functions, upwards until we have a complete grammar. </p>
41<p> At some point when the grammar gets quite complicated, it is desirable to
42  visualize the parse traversal and see what's happening. There are some facilities
43  in the framework that aid in the visualisation of the parse traversal for the
44  purpose of debugging. The following macros enable these features.</p>
45<a name="debugging_macros"></a>
46<h2>Debugging Macros</h2>
47<a name="spirit_assert_exception"></a>
48<h3>BOOST_SPIRIT_ASSERT_EXCEPTION</h3>
49<p> Spirit contains assertions that may activate when spirit is used incorrectly.
50  By default these assertions use the assert macro from the standard library.
51  If you want spirit to throw an exception instead, define <tt>BOOST_SPIRIT_ASSERT_EXCEPTION</tt>
52  to the name of the class that you want to be thrown. This class's constructor
53  will be passed a <tt>const char*</tt> stringified version of the file, line,
54  and assertion condition, when it is thrown. If you want to totally disable the
55  assertion, <tt>#define NDEBUG</tt>.</p>
56<a name="spirit_debug"></a>
57<h3>BOOST_SPIRIT_DEBUG</h3>
58<p>Define this to enable debugging.</p>
59<p>With debugging enabled, special output is generated at key points of the
60  parse process, using the standard output operator (<tt><span class="keyword">operator</span><span class="special">&lt;&lt;</span></tt>)
61  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>,
62  see below) as its left operand.</p>
63<table width="80%" border="0" align="center">
64  <tr>
65    <td class="note_box"><img src="theme/note.gif"> In order to use spirit's
66    debugging support you must ensure that appropriate overloads of
67    <tt><span class="identifier">operator</span><span class="special">&lt;&lt;</span></tt>
68    taking <tt>BOOST_SPIRIT_DEBUG_OUT</tt> as its left operand are available.
69    The expected semantics are those of the standard output operator.<br>
70    <br>
71    These overloads may be provided either within the namespace where the
72    corresponding class is declared (will be found through Argument Dependent Lookup) or [within an
73    anonymous namespace] within <tt><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span></tt>,
74    so it is visible where it is called.<br>
75    <br>
76    <img src="theme/alert.gif"> Note in particular that when <tt>BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES</tt>
77    is set, overloads of <tt><span class="identifier">operator</span><span class="special">&lt;&lt;</span></tt>
78    taking instances of the types used in closures as their right operands are required.<br>
79    <br>
80    You may find an example of overloading the output operator for
81    <tt><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></tt>
82    in a <a href="faq.html#output_operator">related FAQ entry</a>.</td>
83  </tr>
84</table>
85
86<p>By default, if the <tt>BOOST_SPIRIT_DEBUG</tt> macro is defined, all available
87  debug output is generated. To fine tune the amount of generated text you can
88  define the <tt>BOOST_SPIRIT_DEBUG_FLAGS</tt> constant to be equal of a combination
89  of the following flags:</p>
90<table width="90%" border="0" align="center">
91  <tr>
92    <td colspan="2" class="table_title"><b>Available flags to fine tune debug
93      output </b></td>
94  </tr>
95  <tr>
96    <td width="29%" height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_NODES</tt></td>
97    <td width="71%" class="table_cells"><p>print information about nodes (general
98        for all parsers)</p></td>
99  </tr>
100  <tr>
101    <td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_TREES</tt></td>
102    <td class="table_cells"><p>print information about parse trees and AST's (general
103        for all tree parsers)</p></td>
104  </tr>
105  <tr>
106    <td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES</tt></td>
107    <td class="table_cells">print information about closures (general for all
108      parsers with closures)</td>
109  </tr>
110  <tr>
111    <td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_ESCAPE_CHAR</tt></td>
112    <td class="table_cells"><p>print information out of the <tt>esc_char_parser</tt></p></td>
113  </tr>
114  <tr>
115    <td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_SLEX</tt></td>
116    <td class="table_cells">print information out of the <tt>SLEX</tt> parser</td>
117  </tr>
118</table>
119<p><a name="spirit_debug_out"></a> </p>
120<h3>BOOST_SPIRIT_DEBUG_OUT</h3>
121<p> Define this to redirect the debugging diagnostics printout to somewhere else
122  (e.g. a file or stream). Defaults to <tt>std::cout</tt>.</p>
123<a name="spirit_debug_token printer"></a>
124<h3>BOOST_SPIRIT_DEBUG_TOKEN_PRINTER</h3>
125<p> The <tt>BOOST_SPIRIT_DEBUG_TOKEN_PRINTER</tt> macro allows you to redefine the way characters are printed on the stream. </p>
126<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
127  defined to <tt>foo</tt>, it must be compatible with this usage:</p>
128<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>
129<p>The default printer requires <tt>operator&lt;&lt;(StreamT, CharT)</tt>  to
130  be defined. Additionaly, if <tt>CharT</tt> is convertible to a normal character
131  type (<tt>char</tt>, <tt>wchar_t</tt> or <tt>int</tt>), it prints control
132  characters in a friendly manner (e.g., when it receives <span class=special>'\n'</span> it
133  actually prints the <span class=special>\</span> and <span class=special>n</span> charactes,
134instead of a newline).</p>
135<a name="spirit_debug_print_some"></a>
136<h3>BOOST_SPIRIT_DEBUG_PRINT_SOME</h3>
137<p> The <tt>BOOST_SPIRIT_DEBUG_PRINT_SOME</tt> constant defines the number of
138  characters from the stream to be printed for diagnosis. This defaults to the
139  first 20 characters.</p>
140<p><a name="spirit_debug_tracenode"></a> </p>
141<h3>BOOST_SPIRIT_DEBUG_TRACENODE</h3>
142<p> By default all parser nodes are traced. This constant may be used to redefine
143  this default. If this is <tt>1</tt> (<tt>true</tt>), then tracing is enabled
144  by default, if this constant is <tt>0</tt> (<tt>false</tt>), the tracing is
145  disabled by default. This preprocessor constant is set to <tt>1 </tt>(<tt>true</tt>)
146  by default.</p>
147<p>Please note, that the following <tt>BOOST_SPIRIT_DEBUG_...() </tt>macros are
148  to be used at function scope only.</p>
149<a name="spirit_debug_node_p_"></a>
150<h3>BOOST_SPIRIT_DEBUG_NODE(p)</h3>
151<p> Define this to print some debugging diagnostics for parser p. This macro</p>
152<ul>
153  <li>Registers the parser name for debugging</li>
154  <li>Enables/disables the tracing for parser depending on <tt>BOOST_SPIRIT_DEBUG_TRACENODE</tt></li>
155</ul>
156<p> <b>Pre-parse</b>: Before entering the rule, the rule name followed by a peek
157  into the data at the current iterator position is printed.</p>
158<p> <b>Post-parse</b>: After parsing the rule, the rule name followed by a peek
159  into the data at the current iterator position is printed. Here, <tt>'/'</tt>
160  before the rule name flags a succesful match while <tt>'#'</tt> before the rule
161  name flags an unsuccesful match.</p>
162<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_NODE</tt></p>
163<ol>
164  <li>BOOST_SPIRIT_DEBUG_RULE</li>
165  <li>BOOST_SPIRIT_DEBUG_GRAMMAR</li>
166</ol>
167<a name="spirit_trace_node_p__flag_"></a>
168<h3>BOOST_SPIRIT_DEBUG_TRACE_NODE(p, flag)</h3>
169<p> Similar to <tt>BOOST_SPIRIT_DEBUG_NODE</tt>. Additionally allows selective debugging.
170  This is useful in situations where we want to debug just a hand picked set of
171  nodes.</p>
172<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_TRACE_NODE</tt></p>
173<ol>
174  <li>BOOST_SPIRIT_DEBUG_TRACE_RULE</li>
175  <li>BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR</li>
176</ol>
177<p><a name="spirit_trace_node_p__flag__name_"></a> </p>
178<h3>BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(p, name, flag)</h3>
179<p> Similar to <tt>BOOST_SPIRIT_DEBUG_NODE</tt>. Additionally allows selective
180  debugging and allows to specify the name used during debug printout. This is
181  useful in situations where we want to debug just a hand picked set of nodes.
182  The <tt>name</tt> may be redefined in situations, where the parser parameter does not reflect the name of the parser to debug.</p>
183<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_TRACE_NODE</tt></p>
184<ol>
185  <li>BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME</li>
186  <li>BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME</li>
187</ol>
188<hr>
189<p>Here's the original calculator with debugging features enabled:</p>
190<pre>
191    <code><span class=preprocessor>#define </span><span class=identifier>BOOST_SPIRIT_DEBUG  </span><span class=comment>///$$$ DEFINE THIS BEFORE ANYTHING ELSE $$$///
192    </span><span class=preprocessor>#include </span><span class=string>&quot;boost/spirit.hpp&quot;
193
194    </span><span class=comment>/***/
195
196    /*** CALCULATOR GRAMMAR DEFINITIONS HERE ***/
197
198    </span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>integer</span><span class=special>);
199    </span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>group</span><span class=special>);
200    </span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>factor</span><span class=special>);
201    </span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>term</span><span class=special>);
202    </span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>expr</span><span class=special>);
203</span></code></pre>
204<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>
205
206<pre><code>    <span class="preprocessor">Type an expression...or [q or Q] to quit</span>
207
208    <span class="preprocessor">1 + 2</span>
209
210    grammar(calc):      "1 + 2"
211      rule(expression): "1 + 2"
212        rule(term):     "1 + 2"
213          rule(factor): "1 + 2"
214            rule(integer):      "1 + 2"
215    <span class="preprocessor">push     1</span>
216            /rule(integer):     " + 2"
217          /rule(factor):        " + 2"
218        /rule(term):    " + 2"
219        rule(term):     "2"
220          rule(factor): "2"
221            rule(integer):      "2"
222    <span class="preprocessor">push     2</span>
223            /rule(integer):     ""
224          /rule(factor):        ""
225        /rule(term):    ""
226    <span class="preprocessor">popped 1 and 2 from the stack. pushing 3 onto the stack.</span>
227      /rule(expression):        ""
228    /grammar(calc):     ""
229    <span class="preprocessor">-------------------------
230    Parsing succeeded
231    result = 3
232    -------------------------</span></code></pre>
233
234<p> We typed in &quot;1 + 2&quot;. Notice that there are two successful branches
235  from the top rule <tt>expr</tt>. The text in red is generated by the parser's
236  semantic actions while the others are generated by the debug-diagnostics of
237  our rules. Notice how the first <tt>integer</tt> rule took &quot;1&quot;, the
238  first <tt>term</tt> rule took &quot;+&quot; and finally the second <tt>integer</tt>
239  rule took &quot;2&quot;.</p>
240<p>Please note the special meaning of the first characters appearing on the printed
241  lines:</p>
242<ul>
243  <li>a single <span class="literal">'/'</span> starts a line containing the information
244    about a successfully matched parser node (<tt>rule&lt;&gt;</tt>, <tt>grammar&lt;&gt;</tt>
245    or <tt>subrule&lt;&gt;</tt>)</li>
246  <li>a single <span class="literal">'#'</span> starts a line containing the information
247    about a failed parser node</li>
248  <li>a single <span class="literal">'^'</span> starts a line containing the first member (return value/synthesised
249    attribute) of the closure of a successfully matched parser node.</li>
250</ul>
251<p>Check out  <a href="../example/fundamental/calc_debug.cpp">calc_debug.cpp</a> to see debugging in action. </p>
252<table border="0">
253  <tr>
254    <td width="10"></td>
255    <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
256    <td width="30"><a href="position_iterator.html"><img src="theme/l_arr.gif" border="0"></a></td>
257    <td width="30"><a href="error_handling.html"><img src="theme/r_arr.gif" border="0"></a></td>
258  </tr>
259</table>
260<br>
261<hr size="1">
262<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
263  Copyright &copy; 2003 Hartmut Kaiser<br>
264  <br>
265<font size="2">Use, modification and distribution is subject to the Boost Software
266    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
267    http://www.boost.org/LICENSE_1_0.txt)</font></p>
268<p class="copyright">&nbsp;</p>
269</body>
270</html>
Note: See TracBrowser for help on using the repository browser.