Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/spirit/doc/faq.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: 37.9 KB
RevLine 
[29]1<html>
2<head>
3<title>FAQ</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>FAQ</b></font></td>
14    <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td>
15  </tr>
16</table>
17<br>
18<table border="0">
19  <tr>
20    <td width="10"></td>
21    <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
22    <td width="30"><a href="techniques.html"><img src="theme/l_arr.gif" border="0"></a></td>
23    <td width="30"><a href="rationale.html"><img src="theme/r_arr.gif" border="0"></a></td>
24  </tr>
25</table>
26<ul>
27  <li><a href="#scanner_business">The Scanner Business</a></li>
28  <li><a href="#left_recursion">Eliminating Left Recursion</a> </li>
29  <li><a href="#lexeme_and_rules">The lexeme_d directive and rules</a></li>
30  <li><a href="#kleene_star">Kleene Star infinite loop</a></li>
31  <li><a href="#CVS">Boost CVS and Spirit CVS</a></li>
32  <li><a href="#compilation_times">How to reduce compilation times with complex
33    Spirit grammars</a></li>
34  <li><strong><a href="#frame_assertion">Closure frame assertion</a></strong></li>
35  <li><strong><a href="#greedy_rd">Greedy RD</a></strong></li>
36  <li><strong><a href="#referencing_a_rule_at_construction">Referencing a rule
37    at construction time</a></strong></li>
38  <li><strong><a href="#storing_rules">Storing Rules</a></strong></li>
39  <li><strong><a href="#parsing_ints_and_reals">Parsing ints and reals</a> </strong></li>
40  <li><strong><a href="#output_operator">BOOST_SPIRIT_DEBUG and missing <tt>operator&lt;&lt;</tt></a></strong></li>
41  <li><strong><a href="#repository">Applications that used to be part of spirit</a></strong></li>
42</ul>
43<p><b> <a name="scanner_business" id="scanner_business"></a> The Scanner Business</b></p>
44<p><font color="#FF0000">Question:</font> Why doesn't this compile?</p>
45<pre><code><font color="#000000"><span class=special>    </span><span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class=identifier>r </span><span class=special>= /*...*/;
46</span>    <span class=identifier>parse</span><span class=special>(</span><span class=string>"hello world"</span><span class=special>, </span><span class=identifier>r</span><span class=special>, </span><span class=identifier>space_p</span><span class=special>); </span><span class=comment>// BAD [attempts phrase level parsing]</span></font></code></pre>
47<p>But if I <font color="#000000">remove the skip-parser, everything goes back
48  to normal again:<code></code></font></p>
49<pre><code><font color="#000000">    <span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class=identifier>r </span><span class=special>= *</span><span class=identifier>anychar_p</span><span class=special>;
50    </span><span class=identifier>parse</span><span class=special>(</span><span class=string>"hello world"</span><span class=special>, </span><span class=identifier>r</span><span class=special>); </span><span class=comment>// OK [character level parsing]</span></font></code></pre>
51<p>Sometimes you'll want to pass in a rule to one of the functions parse functions
52  that Spirit provides. The problem is that the rule is a template class that
53  is parameterized by the scanner type. This is rather awkward but unavoidable:
54  <strong>the rule is tied to a scanner</strong>. What's not obvious is that this
55  scanner must be compatible with the scanner that is ultimately passed to the
56  rule's parse member function. Otherwise, the compiler will complain. </p>
57<p>Why does the first call to parse not compile? Because of scanner incompatibility.
58  Behind the scenes, the free parse function creates a scanner from the iterators
59  passed in. In the first call to parse, the scanner created is a plain vanilla
60  <tt>scanner&lt;&gt;</tt>. This is compatible with the default scanner type of
61  <tt>rule&lt;&gt;</tt> [see default template parameters of <a href="rule.html">the
62  rule</a>]. The second call creates a scanner of type <tt><a href="scanner.html#phrase_scanner_t">phrase_scanner_t</a></tt>.
63  Thus, in order for the second call to succeed, the rule must be parameterized
64  as <tt>rule&lt;phrase_scanner_t&gt;</tt>:</p>
65<pre><code><font color="#000000"><span class=comment>    </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>phrase_scanner_t</span><span class=special>&gt; </span><span class=identifier>r </span><span class=special>= </span><span class=special>*</span><span class=identifier>anychar_p</span><span class=special>;
66    </span><span class=identifier>parse</span><span class=special>(</span><span class=string>"hello world"</span><span class=special>, </span><span class=identifier>r</span><span class=special>, </span><span class=identifier>space_p</span><span class=special>);       </span><span class=comment>//  OK [phrase level parsing]</span></font></code></pre>
67<p>Take note however that <tt>phrase_scanner_t</tt> is compatible only when you
68  are using <tt>char const*</tt> iterators and <tt>space_p</tt> as the skip parser.
69  Other than that, you'll have to find the right type of scanner. This is tedious
70  to do correctly. In light of this issue, <strong>it is best to avoid rules as
71  arguments to the parse functions</strong>. Keep in mind that this happens only
72  with rules. The rule is the only parser that has to be tied to a particular
73  scanner type. For instance:</p>
74<pre><span class=comment>    </span><span class=identifier>parse</span><span class=special>(</span><span class=string>"hello world"</span><span class=special>, *</span><span class=identifier>anychar_p</span><span class=special>);           </span><span class=comment><code><font color="#000000"><span class=comment>//  OK  [character level parsing]</span></font></code>
75    </span><span class=identifier>parse</span><span class=special>(</span><span class=string>"hello world"</span><span class=special>, *</span><span class=identifier>anychar_p</span><span class=special>, </span><span class=identifier>space_p</span><span class=special>);  </span><span class="comment">//  OK  [phrase level parsing]</span></pre>
76<table width="80%" border="0" align="center">
77  <tr>
78    <td class="note_box"> <strong><img src="theme/note.gif" width="16" height="16">
79      Multiple Scanner Support</strong><br>
80      <br>
81      As of v1.8.0, rules can use one or more scanner types. There are cases,
82      for instance, where we need a rule that can work on the phrase and character
83      levels. Rule/scanner mismatch has been a source of confusion and is the
84      no. 1 <a href="faq.html#scanner_business">FAQ</a>. To address this issue,
85      we now have <a href="rule.html#multiple_scanner_support">multiple scanner
86      support</a>. <br>
87      <br>
88      <img src="theme/bulb.gif" width="13" height="18"> See the techniques section
89      for an <a href="techniques.html#multiple_scanner_support">example</a> of
90      a <a href="grammar.html">grammar</a> using a multiple scanner enabled rule,
91      <a href="scanner.html#lexeme_scanner">lexeme_scanner</a> and <a href="scanner.html#as_lower_scanner">as_lower_scanner.</a></td>
92  </tr>
93</table>
94<p><b> <a name="left_recursion"></a> Eliminating Left Recursion </b></p>
95<p><font color="#FF0000">Question:</font> I ported a grammar from YACC. It's &quot;kinda&quot;
96  working - the parser itself compiles with no errors. But when I try to parse,
97  it gives me an &quot;invalid page fault&quot;. I tracked down the problem to
98  this grammar snippet:</p>
99<pre>    <span class=identifier>or_expr </span><span class=special>= </span><span class=identifier>xor_expr </span><span class=special>| (</span><span class=identifier>or_expr </span><span class=special>&gt;&gt; </span><span class=identifier>VBAR </span><span class=special>&gt;&gt; </span><span class=identifier>xor_expr</span><span class=special>);</span></pre>
100<p>What you should do is to eliminate direct and indirect left-recursion. This
101  causes the invalid page fault because the program enters an infinite loop. The
102  code above is good for bottom up parsers such as YACC but not for LL parsers
103  such as Spirit.</p>
104<p>This is similar to a rule in Hartmut Kaiser's C
105  parser (this should be available for download from <a href="http://spirit.sf.net">Spirit's site</a> as soon as you read this).</p>
106<pre>
107    <span class=identifier>inclusive_or_expression
108    </span><span class=special>= </span><span class=identifier>exclusive_or_expression
109    </span><span class=special>| </span><span class=identifier>inclusive_or_expression </span><span class=special>&gt;&gt; </span><span class=identifier>OR </span><span class=special>&gt;&gt; </span><span class=identifier>exclusive_or_expression
110    </span><span class=special>;</span></pre>
111<p><span class=special></span>Transforming left recursion to right recursion,
112  we have:</p>
113<pre>    <span class=identifier>inclusive_or_expression
114    </span><span class=special>= </span><span class=identifier>exclusive_or_expression </span><span class=special>&gt;&gt; </span><span class=identifier>inclusive_or_expression_helper
115    </span><span class=special>;
116
117    </span><span class=identifier>inclusive_or_expression_helper
118    </span><span class=special>= </span><span class=identifier>OR </span><span class=special>&gt;&gt; </span><span class=identifier>exclusive_or_expression </span><span class=special>&gt;&gt; </span><span class=identifier>inclusive_or_expression_helper
119    </span><span class=special>| </span><span class=identifier>epsilon_p
120    </span><span class=special>;</span></pre>
121<p><span class=special></span>I'd go further. Since:</p>
122<pre>    <span class=identifier>r </span><span class=special>= </span><span class=identifier>a </span><span class=special>| </span><span class=identifier>epsilon_p</span><span class=special>;</span></pre>
123<p><span class=special></span>is equivalent to:<span class=special><br>
124  </span></p>
125<pre>    <span class=identifier>r </span><span class=special>= !</span><span class=identifier>a</span><span class=special>;</span></pre>
126<p>we can simplify <tt>inclusive_or_expression_helper</tt> thus:</p>
127<pre>    <span class=identifier>inclusive_or_expression_helper
128    </span><span class=special>= !(</span><span class=identifier>OR </span><span class=special>&gt;&gt; </span><span class=identifier>exclusive_or_expression </span><span class=special>&gt;&gt; </span><span class=identifier>inclusive_or_expression_helper</span><span class=special>)
129    ;</span></pre>
130<p><span class=special></span>Now, since:</p>
131<pre>    <span class=identifier>r </span><span class=special>= !(</span><span class=identifier>a </span><span class=special>&gt;&gt; </span><span class=identifier>r</span><span class=special>);</span></pre>
132<p><span class=special></span>is equivalent to:</p>
133<pre>    <span class=identifier>r </span><span class=special>= *</span><span class=identifier>a</span><span class=special>;</span></pre>
134<p><span class=special></span>we have:</p>
135<pre>    <span class=identifier>inclusive_or_expression_helper
136    </span><span class=special>= *(</span><span class=identifier>OR </span><span class=special>&gt;&gt; </span><span class=identifier>exclusive_or_expression</span><span class=special>)
137    ;</span></pre>
138<p><span class=special></span>Now simplifying <tt>inclusive_or_expression</tt>
139  fully, we have:</p>
140<pre>    <span class=identifier>inclusive_or_expression
141    </span><span class=special>= </span><span class=identifier>exclusive_or_expression </span><span class=special>&gt;&gt; *(</span><span class=identifier>OR </span><span class=special>&gt;&gt; </span><span class=identifier>exclusive_or_expression</span><span class=special>)
142    ;</span></pre>
143<p><span class=special></span>Reminds me of the calculators. So in short:</p>
144<pre>    <span class=identifier>a </span><span class=special>= </span><span class=identifier>b </span><span class=special>| </span><span class=identifier>a </span><span class=special>&gt;&gt; </span><span class=identifier>op </span><span class=special>&gt;&gt; </span><span class=identifier>b</span><span class=special>;</span></pre>
145<p><span class=special></span><span class=identifier>in </span><span class=identifier>pseudo-YACC
146  </span><span class=identifier>is</span><span class=special>:</span></p>
147<pre>    <span class=identifier>a </span><span class=special>= </span><span class=identifier>b </span><span class=special>&gt;&gt; *(</span><span class=identifier>op </span><span class=special>&gt;&gt; </span><span class=identifier>b</span><span class=special>);</span></pre>
148<p><span class=special></span>in Spirit. What could be simpler? Look Ma, no recursion,
149  just iteration.</p>
150<p><b> <a name="lexeme_and_rules" id="lexeme_and_rules"></a> The lexeme_d directive
151  and rules</b></p>
152<p> <font color="#FF0000">Question:</font> Does lexeme_d not support expressions
153  which include rules? In the example below, the definition of atomicRule compiles,
154</p>
155<pre>    <span class=identifier></span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>phrase_scanner_t</span><span class=special>&gt; </span><span class=identifier>atomicRule</span>
156        <span class=special>= </span><span class=identifier>lexeme_d</span><span class=special>[(</span><span class=identifier>alpha_p </span><span class=special>| </span><span class=literal>'_'</span><span class=special>) &gt;&gt; *(</span><span class=identifier>alnum_p </span><span class=special>| </span><span class=literal>'.' </span><span class=special>| </span><span class=literal>'-' </span><span class=special>| </span><span class=literal>'_'</span><span class=special>)];</span></pre>
157<p>but if I move <tt>alnum_p | '.' | '-' | '_'</tt> into its own rule, the compiler
158  complains about conversion from <tt>const scanner&lt;...&gt;</tt> to <tt>const
159  phrase_scaner_t&amp;</tt>. </p>
160<pre>    <span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>phrase_scanner_t</span><span class=special>&gt; </span><span class=identifier>ch </span><span class=special>
161        = </span><span class=identifier>alnum_p </span><span class=special>| </span><span class=literal>'.' </span><span class=special>| </span><span class=literal>'-' </span><span class=special>| </span><span class=literal>'_'</span><span class=special>;</span>
162
163<span class=identifier>    rule</span><span class=special>&lt;</span><span class=identifier>phrase_scanner_t</span><span class=special>&gt; </span><span class=identifier>compositeRule</span>
164        <span class=special>= </span><span class=identifier>lexeme_d</span><span class=special>[(</span><span class=identifier>alpha_p </span><span class=special>| </span><span class=literal>'_'</span><span class=special>) &gt;&gt; *(</span><span class=identifier>ch</span><span class=special>)]; </span><span class="comment">// &lt;- error source</span></pre>
165<p>You might get the impression that the <tt>lexeme_d</tt> directive and rules
166  do not mix. Actually, this problem is related to the first FAQ entry: The Scanner
167  Business. More precisely, the <tt>lexeme_d</tt> directive and rules with incompatible
168  scanner types do not mix. This problem is more subtle. What's causing the scanner
169  incompatibility is the directive itself. The <tt>lexeme_d</tt> directive transforms
170  the scanner it receives into something that disables the skip parser. This non-skipping
171  scanner, unfortunately, is incompatible with the original scanner before transformation
172  took place.</p>
173<p>The simplest solution is not to use rules in the <tt>lexeme_d</tt>. Instead,
174  you can definitely apply <tt>lexeme_d</tt> to subrules and grammars if you really
175  need more complex parsers inside the <tt>lexeme_d</tt>. If you really must use
176  a rule, you need to know the exact scanner used by the directive. The <tt>lexeme_scanner</tt>
177  metafunction is your friend here. The example above will work as expected once
178  we give the <tt>ch</tt> rule a correct scanner type:</p>
179<pre>    <span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>lexeme_scanner</span><span class="special">&lt;</span><span class=identifier>phrase_scanner_t</span><span class=special>&gt;::</span><span class="identifier">type</span><span class=special>&gt; </span><span class=identifier>ch </span><span class=special>
180        = </span><span class=identifier>alnum_p </span><span class=special>| </span><span class=literal>'.' </span><span class=special>| </span><span class=literal>'-' </span><span class=special>| </span><span class=literal>'_'</span><span class=special>;</span></pre>
181<p>Note: make sure to add &quot;<tt>typename</tt>&quot; before <tt>lexeme_scanner</tt>
182  when this is used inside a template class or function.</p>
183<p>The same thing happens when rules are used inside the <tt>as_lower_d</tt> directive.
184  In such cases, you can use the <tt>as_lower_scanner</tt>. See the <span class=identifier><tt><a href="scanner.html#lexeme_scanner">lexeme_scanner</a></tt></span>
185  and <tt><a href="scanner.html#as_lower_scanner">as_lower_scanner</a></tt>.</p>
186<table width="80%" border="0" align="center">
187  <tr>
188    <td class="note_box"><img src="theme/bulb.gif" width="13" height="18"> See
189      the techniques section for an <a href="techniques.html#multiple_scanner_support">example</a>
190      of a <a href="grammar.html">grammar</a> using a <a href="rule.html#multiple_scanner_support">multiple
191      scanner enabled rule,</a> <a href="scanner.html#lexeme_scanner">lexeme_scanner</a>
192      and <a href="scanner.html#as_lower_scanner">as_lower_scanner.</a></td>
193  </tr>
194</table>
195<p><strong><a name="kleene_star"></a>Kleene Star infinite loop</strong></p>
196<p><font color="#FF0000">Question</font>: Why Does This Loop Forever?</p>
197<pre>    <span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class=identifier>optional </span><span class=special>= !(</span>str_p<span class="special">(</span><span class="string">&quot;optional&quot;</span><span class="special">));
198    </span><span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class="identifier">list_of_optional </span><span class=special>= *</span><span class=identifier>optional</span><span class="special">;</span></pre>
199<p>The problem with this is that the kleene star will continue looping until it
200  gets a no-match from it's enclosed parser. Because the <tt>optional</tt> rule
201  is optional, it will always return a match. Even if the input doesn't match
202  &quot;optional&quot; it will return a zero length match. <tt>list_of_optional</tt>
203  will keep calling optional forever since optional will never return a no-match.
204  So in general, any rule that can be &quot;nullable&quot; (meaning it can return
205  a zero length match) must not be put inside a kleene star.</p>
206<p><strong><a name="CVS"></a>Boost CVS and Spirit CVS</strong></p>
207<p><font color="#FF0000">Question:</font> There is Boost CVS and Spirit CVS. Which
208  is used for further development of Spirit?</p>
209<p> Generally, development takes place in Spirit's CVS. However, from time to
210  time a new version of Spirit will be integrated in Boost. When this happens
211  development takes place in the Boost CVS. There will be announcements on the
212  Spirit mailing lists whenever the status of the Spirit CVS changes.<br>
213</p>
214<table width="80%" border="0" align="center">
215  <tr>
216    <td class="note_box"><img src="theme/alert.gif" width="16" height="16">
217    During development of Spirit v1.8.1 (released as part of boost-1.32.0) and
218    v1.6.2, Spirit's developers decided to stop maintaining Spirit CVS for
219    BRANCH_1_8 and BRANCH_1_6. This was necessary to reduce the added work of
220    maintaining and synch'ing two repositories. The maintenance of these branches
221    will take place on Boost CVS. At this time, new developments towards Spirit
222    v2 and other experimental developments are expected to happen in Spirit
223    CVS.</td>
224  </tr>
225</table>
226<p><strong><a name="compilation_times"></a>How to reduce compilation times with
227  complex Spirit grammars </strong></p>
228<p><font color="#FF0000">Question:</font> Are there any techniques to minimize
229  compile times using spirit? For simple parsers compile time doesn't seem to
230  be a big issue, but recently I created a parser with about 78 rules
231  and it took about 2 hours to compile. I would like to break the grammar up into
232  smaller chunks, but it is not as easy as I thought it would be because rules
233  in two grammar capsules are defined in terms of each other. Any thoughts?</p>
234<p> The only way to reduce compile times is </p>
235<ul>
236  <li> to split up your grammars into smaller chunks</li>
237  <li> prevent the compiler from seeing all grammar definitions at the same time
238    (in the same compilation unit)</li>
239</ul>
240<p>The first task is merely logistical, the second is rather a technical one. </p>
241<p>A good example of solving the first task is given in the Spirit cpp_lexer example
242  written by JCAB (you may find it on the <a href="http://spirit.sourceforge.net/repository/applications/show_contents.php">applications' repository</a>).
243</p>
244<p>The cross referencing problems may be solved by some kind of forward declaration,
245  or, if this does not work, by introducing some dummy template argument to the
246  non-templated grammars. Thus allows the instantiation time to be defered until the
247  compiler has seen all the defintions:</p>
248<pre>    <span class="keyword">template</span> &lt;<span class="keyword">typename</span> T = <span class="keyword">int</span>&gt;<br>    grammar2;</p>
249
250    <span class="keyword">template</span> &lt;<span class="keyword">typename</span> T = <span class="keyword">int</span>&gt;<br>    <span class="keyword">struct</span> grammar1 : <span class="keyword">public</span> grammar&lt;grammar1&gt;<br>    {
251    <span class="comment">// refers to grammar2&lt;&gt;</span>
252    };
253
254    <span class="keyword">template</span> &lt;typename T&gt;
255    <span class="keyword">struct</span> grammar2 : <span class="keyword">public</span> grammar&lt;grammar2&gt;
256    {
257    <span class="comment">// refers to grammar1&lt;&gt;</span>
258    };
259
260    //...
261    grammar1&lt;&gt; g; <span class="comment">// both grammars instantiated here</span>
262</pre>
263<p>The second task is slightly more complex. You must ensure that in the first
264  compilation unit the compiler sees only some function/template <strong>declaration</strong>
265  and in the second compilation unit the function/template <strong>definition</strong>.
266  Still no problem, if no templates are involved. If templates are involved,
267  you need to manually (explicitly) instantiate these templates with the correct
268  template parameters inside a separate compilation unit. This way the compilation
269  time is split between several compilation units, reducing the overall
270  required time drastically too. </p>
271<p>For a sample, showing how to achieve this, you may want to look at the <tt>Wave</tt>
272  preprocessor library, where this technique is used extensively.  (this should be available for download from <a href="http://spirit.sf.net">Spirit's site</a> as soon as you read this).</p>
273<p><strong><a name="frame_assertion" id="frame_assertion"></a>Closure frame assertion</strong></p>
274<p><font color="#FF0000">Question:</font> When I run the parser I get an assertion
275  <span class="string">&quot;frame.get() != 0 in file closures.hpp&quot;</span>.
276  What am I doing wrong?</p>
277<p>Basically, the assertion fires when you are accessing a closure variable that
278  is not constructed yet. Here's an example. We have three rules <tt>a</tt>, <tt>b</tt>
279  and <tt>c</tt>. Consider that the rule <tt>a</tt> has a closure member <tt>m</tt>.
280  Now:</p>
281<pre>    <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">b</span><span class="special">;</span>
282    <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">int_p</span><span class="special">[</span><span class="identifier">a</span><span class="special">.</span><span class="identifier">m</span> <span class="special">=</span> 123<span class="special">];</span>
283    <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">b</span><span class="special">;</span></pre>
284<p>When the rule <tt>a</tt> is invoked, its frame is set, along with its member
285  <tt>m</tt>. So, when <tt>b</tt> is called from <tt>a</tt>, the semantic action
286  <tt>[a.m = 123]</tt>will store <tt>123</tt> into <tt>a</tt>'s closure member
287  <tt>m</tt>. On the other hand, when <tt>c</tt> is invoked, and <tt>c</tt> attempts
288  to call <tt>b</tt>, no frame for <tt>a</tt> is set. Thus, when <tt>b</tt> is
289  called from <tt>c</tt>, the semantic action <tt>[a.m = 123]</tt>will fire the
290  <span class="string">&quot;frame.get() != 0 in file closures.hpp&quot;</span>
291  assertion.</p>
292<p><strong><a name="greedy_rd" id="greedy_rd"></a>Greedy RD</strong></p>
293<p><font color="#FF0000">Question:</font> I'm wondering why the this won't work
294  when parsed:</p>
295<pre>
296<span class="identifier">    a</span> <span class="special">= +</span><span class="identifier">anychar_p</span><span class="special">;</span>
297    <span class="identifier">b</span> = <span class="string">'('</span> <span class="special">&gt;&gt;</span> <span class="identifier">a</span> <span class="special">&gt;&gt;</span> <span class="string">')'</span><span class="special">;</span></pre>
298<p>Try this:</p>
299<pre>
300<span class="identifier">    a</span> <span class="special">= +(</span><span class="identifier">anychar_p - </span><span class="string">')'</span><span class="special">);</span>
301    <span class="identifier">b</span> <span class="special">=</span> <span class="string">'('</span> <span class="special">&gt;&gt;</span> <span class="identifier">a</span> <span class="special">&gt;&gt;</span> <span class="string">')'</span><span class="special">;</span></pre>
302<p>David Held writes: That's because it's like the langoliers--it eats everything
303  up. You usually want to say what it shouldn't eat up by subtracting the terminating
304  character from the parser. The moral being: Using <tt>*anychar_p</tt> or <tt>+anychar_p</tt>
305  all by itself is usually a <em>Bad Thing</em>&#8482;.</p>
306<p>In other words: Recursive Descent is inherently greedy (however, see <a href="rationale.html#exhaustive_rd">Exhaustive
307  backtracking and greedy RD</a>).</p>
308<p><span class="special"></span><strong><a name="referencing_a_rule_at_construction" id="referencing_a_rule_at_construction"></a>Referencing
309  a rule at construction time</strong></p>
310<p><font color="#FF0000">Question:</font> The code below terminates with a segmentation
311  fault, but I'm (obviously) confused about what I'm doing wrong.</p>
312<pre>    rule<span class="special">&lt;</span>ScannerT<span class="special">,</span> clos<span class="special">::</span>context_t<span class="special">&gt;</span> id <span class="special">=</span> int_p<span class="special">[</span>id<span class="special">.</span>i <span class="special">=</span> arg1<span class="special">];</span></pre>
313<p>You have a rule <tt>id</tt> being constructed. Before it is constructed, you
314  reference <tt>id.i</tt> in the RHS of the constructor. It's a chicken and egg
315  thing. The closure member <tt>id.i</tt> is not yet constructed at that point.
316  Using assignment will solve the problem. Try this instead:</p>
317<pre>    rule<span class="special">&lt;</span>ScannerT<span class="special">,</span> clos<span class="special">::</span>context_t<span class="special">&gt;</span> id<span class="special">;</span>
318    id <span class="special">=</span> int_p<span class="special">[</span>id<span class="special">.</span>i <span class="special">=</span> arg1<span class="special">];</span></pre>
319<p><span class="special"></span><strong><a name="storing_rules" id="storing_rules"></a>Storing
320  Rules </strong></p>
321<p><font color="#FF0000">Question:</font> Why can't I store rules in STL containers
322  for later use and why can't I pass and return rules to and from functions by
323  value? </p>
324<p>EBNF is primarily declarative. Like in functional programming, It's a static
325  recipe and there's no notion of do this then that. However, in Spirit, we managed
326  to coax imperative C++ to take in declarative EBNF. Hah! Fun!... We did that
327  by masquerading the C++ assignment operator to mimic EBNF's <tt>::=</tt>, among
328  other things (e.g. <tt>&gt;&gt;</tt>, <tt>|</tt>, <tt>&amp;</tt> etc.). We used
329  the rule class to let us do that by giving its assignment operator (and copy
330  constructor) a different meaning and semantics. Doing so made the rule unlike
331  any other C++ object. You can't copy it. You can't assign it. You can't place
332  it in a container (vector, stack, etc).Heck, you can't even return it from a
333  function *by value*.</p>
334<table width="80%" border="0" align="center">
335  <tr>
336    <td class="note_box"><img src="theme/alert.gif" width="16" height="16"> The
337      rule is a weird object, unlike any other C++ object. It does not have the
338      proper copy and assignment semantics and cannot be stored and passed around
339      by value.</td>
340  </tr>
341</table>
342<p>However nice declarative EBNF is, the dynamic nature of C++ can be an advantage.
343  We've seen this in action here and there. There are indeed some interesting
344  applications of dynamic parsers using Spirit. Yet, we haven't fully utilized
345  the power of dynamic parsing, unless(!), we have a rule that's not so alien
346  to C++ (i.e. behaves as a good C++ object). With such a beast, we can write
347  parsers that's defined at run time, as opposed to at compile time.</p>
348<p>Now that I started focusing on rules (hey, check out the hunky new rule features),
349  it might be a good time to implement the rule-holder. It is basically just a
350  rule, but with C++ object semantics. Yet it's not as simple. Without true garbage
351  collection, the implementation will be a bit tricky. We can't simply use reference
352  counting because a rule-holder (hey, anyone here has a better name?) *is-a*
353  rule, and rules are typically recursive and thus cyclic. The problem is which
354  will own which.</p>
355<p>Ok... this will do for now. You'll definitely see more of the rule-holder in
356  the coming days.</p>
357<p><strong><a name="parsing_ints_and_reals"></a>Parsing Ints and Reals</strong></p>
358<p> <font color="#FF0000">Question:</font>  I was trying to parse an int or float value with the <tt>longest_d</tt> directive and put some actors on the alternatives to visualize the results. When I parse &quot;123.456&quot;, the output reports:</p>
359<ol>
360  <li>(int) has been matched: full match = false</li>
361  <li> (double) has been matched: full match = true</li>
362</ol>
363<p>That is not what I expected. What am I missing? </p>
364<p> Actually, the problem is that both semantic actions of the int and real branch will be triggered because both branches will be tried. This doesn't buy us much. What actually wins in the end is what you expected. But there's no easy way to know which one wins. The problem stems from the ambiguity. </p>
365<blockquote>
366  <p>Case1: Consider this input: &quot;2&quot;. Is it an int or a real? They are both (strictly following the grammar of a real). </p>
367  <p>Case2 : Now how about &quot;1.0&quot;? Is it an int or a real? They are both, albeit the int part gets a partial match: &quot;1&quot;. That is why you are getting a (partial) match for your <em>int</em> rule (full match = false). </p>
368</blockquote>
369<p>  Instead of using the <tt>longest_d</tt> to parse ints and reals, what I suggest is to remove the ambiguity and use the plain short-circuiting alternatives. The first step is to use <tt><a href="numerics.html#strict_reals">strict_real_p</a> </tt>to make the first case unambiguous. Unlike
370
371
372  <tt>real_p</tt>, <tt>strict_real_p</tt> requires a dot to be present for a number to be considered a successful match.
373
374Your grammar can be written unambiguously as:</p>
375<pre>    strict_real_p<span class="special"> | </span>int_p</pre>
376<p> Note that because ambiguity is resolved, attaching actions to both branches is safe. Only one will be triggered:</p>
377<pre>    strict_real_p<span class="special">[</span>R<span class="special">] | </span>int_p<span class="special">[</span>I<span class="special">]</span></pre>
378<blockquote>
379  <p> &quot;1.0&quot; ---&gt; triggers R<br>
380&quot;2&quot; ---&gt; triggers I</p>
381</blockquote>
382<p> Again, as a rule of thumb, it is always best to resolve as much ambiguity as possible. The best grammars are those which involve no backtracking at all: an LL(1) grammar. Backtracking and semantic actions do not mix well.</p>
383<p><b><a name="output_operator" id="output_operator"></a>BOOST_SPIRIT_DEBUG and missing <tt>operator&lt;&lt;</tt></b></p>
384<p><font color="#FF0000">Question:</font> My code compiles fine in release mode but when I try to define <tt>BOOST_SPIRIT_DEBUG</tt> the compiler complains about a missing <tt><span class="keyword">operator</span><span class="special">&lt;&lt;</span></tt>.</p>
385<p>When <tt>BOOST_SPIRIT_DEBUG</tt> is defined debug output is generated for
386  spirit parsers. To this end it is expected that each closure member has the
387  default output operator defined.</p>
388<p>You may provide the operator overload either in the namespace where the
389  class is declared (will be found through Argument Dependent Lookup) or make it visible where it is
390  used, that is <tt><span class="keyword">namespace</span> <span
391  class="identifier">boost</span><span class="special">::</span><span
392  class="identifier">spirit</span></tt>. Here's an example for <tt><span
393  class="identifier">std</span><span class="special">::</span><span
394  class="identifier">pair</span></tt>:</p>
395<pre><code>
396    <span class="preprocessor">#include</span> <span class="string">&lt;iosfwd&gt;</span>
397    <span class="preprocessor">#include</span> <span class="string">&lt;utility&gt;</span>
398
399    <span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
400
401        <span class="keyword">template</span> <span class="special">&lt;</span>
402            <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">,</span>
403            <span class="keyword">typename</span> <span class="identifier">E</span><span class="special">,</span>
404            <span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">,</span>
405            <span class="keyword">typename</span> <span class="identifier">T2</span>
406        <span class="special">&gt;</span>
407        <span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">C</span><span class="special">,</span> <span class="identifier">E</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span>
408            <span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">C</span><span class="special">,</span> <span class="identifier">E</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">out</span><span class="special">,</span>
409            <span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">what</span><span class="special">)</span>
410        <span class="special">{</span>
411            <span class="keyword">return</span> <span class="identifier">out</span> <span class="special">&lt;&lt;</span> <span class="string">'('</span> <span class="special">&lt;&lt;</span> <span class="identifier">what</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">", "</span>
412                <span class="special">&lt;&lt;</span> <span class="identifier">what</span><span class="special">.</span><span class="identifier">second</span> <span class="special">&lt;&lt;</span> <span class="string">')'</span><span class="special">;</span>
413        <span class="special">}</span>
414
415    <span class="special">}</span>
416
417</code></pre>
418<p><b><a name="repository" id="repository"></a>Applications that used to be part of spirit</b></p>
419<p><font color="#FF0000">Question:</font> Where can I find <i>&lt;insert great application&gt;</i>, that used to be part of the Spirit distribution?</p>
420<p>Old versions of Spirit used to include applications built with it.
421  In order to streamline the distribution they were moved to a separate
422  <a href="http://spirit.sourceforge.net/repository/applications/show_contents.php">applications repository</a>.
423  In that page you'll find links to full applications that use the Spirit
424  parser framework. We encourage you to send in your own applications for
425  inclusion (see the page for instructions).</p>
426  <p>You may also check out the <a href="http://spirit.sourceforge.net/repository/grammars/show_contents.php">grammars' repository</a>.</p>
427<table width="80%" border="0" align="center">
428  <tr>
429    <td class="note_box">
430      <img src="theme/note.gif" width="16" height="16"> You'll still find the
431      example applications that complement (actually are part of) the
432      documentation in the usual place: <code>libs/spirit/example</code>.<br>
433      <br>
434      <img src="theme/alert.gif" width="16" height="16"> The applications and
435      grammars listed in the repositories are works of the respective authors.
436      It is the author's responsibility to provide support and maintenance.
437      Should you have any questions, please send the author an email.
438    </td>
439  </tr>
440</table>
441<br>
442<table border="0">
443  <tr>
444    <td width="10"></td>
445    <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
446    <td width="30"><a href="techniques.html"><img src="theme/l_arr.gif" border="0"></a></td>
447    <td width="30"><a href="rationale.html"><img src="theme/r_arr.gif" border="0"></a></td>
448  </tr>
449</table>
450<br>
451<hr size="1">
452<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
453<span class="copyright">Copyright &copy; 2002-2003 Hartmut Kaiser </span><br>
454  <br>
455  <font size="2">Use, modification and distribution is subject to the Boost Software
456      License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
457http://www.boost.org/LICENSE_1_0.txt)</font></p>
458<p class="copyright">&nbsp;</p>
459</body>
460</html>
Note: See TracBrowser for help on using the repository browser.