• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Complex - Made easier</title>
5<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../../../index.html" title="Spirit 2.5.8">
8<link rel="up" href="../tutorials.html" title="Tutorials">
9<link rel="prev" href="karma_complex.html" title="Complex - A first more complex generator">
10<link rel="next" href="karma_adapted_complex.html" title="Complex - Fully Integrated">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="karma_complex.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorials.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="karma_adapted_complex.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h4 class="title">
27<a name="spirit.karma.tutorials.karma_easier_complex"></a><a class="link" href="karma_easier_complex.html" title="Complex - Made easier">Complex
28        - Made easier</a>
29</h4></div></div></div>
30<p>
31          In the previous section we showed how to format a complex number (i.e.
32          a pair of doubles). In this section we will build on this example with
33          the goal to avoid using semantic actions in the format specification. Let's
34          have a look at the resulting code first, trying to understand it afterwards
35          (the full source file for this example can be found here: <a href="../../../../../example/karma/complex_number_easier.cpp" target="_top">complex_number_easier.cpp</a>):
36        </p>
37<p>
38</p>
39<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">OutputIterator</span><span class="special">&gt;</span>
40<span class="keyword">bool</span> <span class="identifier">generate_complex</span><span class="special">(</span><span class="identifier">OutputIterator</span> <span class="identifier">sink</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">c</span><span class="special">)</span>
41<span class="special">{</span>
42    <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">karma</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span>
43    <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">karma</span><span class="special">::</span><span class="identifier">omit</span><span class="special">;</span>
44    <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">karma</span><span class="special">::</span><span class="identifier">generate</span><span class="special">;</span>
45
46    <span class="keyword">return</span> <span class="identifier">generate</span><span class="special">(</span><span class="identifier">sink</span><span class="special">,</span>
47
48        <span class="comment">//  Begin grammar</span>
49        <span class="special">(</span>
50           <span class="special">!</span><span class="identifier">double_</span><span class="special">(</span><span class="number">0.0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="char">'('</span> <span class="special">&lt;&lt;</span> <span class="identifier">double_</span> <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="identifier">double_</span> <span class="special">&lt;&lt;</span> <span class="char">')'</span>
51        <span class="special">|</span>   <span class="identifier">omit</span><span class="special">[</span><span class="identifier">double_</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">double_</span> <span class="special">&lt;&lt;</span> <span class="identifier">omit</span><span class="special">[</span><span class="identifier">double_</span><span class="special">]</span>
52        <span class="special">),</span>
53        <span class="comment">//  End grammar</span>
54
55        <span class="identifier">c</span><span class="special">.</span><span class="identifier">imag</span><span class="special">(),</span> <span class="identifier">c</span><span class="special">.</span><span class="identifier">real</span><span class="special">(),</span> <span class="identifier">c</span><span class="special">.</span><span class="identifier">imag</span><span class="special">()</span>     <span class="comment">//  Data to output</span>
56    <span class="special">);</span>
57<span class="special">}</span>
58</pre>
59<p>
60        </p>
61<p>
62          Let's cover some basic library features first.
63        </p>
64<h6>
65<a name="spirit.karma.tutorials.karma_easier_complex.h0"></a>
66          <span class="phrase"><a name="spirit.karma.tutorials.karma_easier_complex.making_numeric_generators_fail"></a></span><a class="link" href="karma_easier_complex.html#spirit.karma.tutorials.karma_easier_complex.making_numeric_generators_fail">Making
67          Numeric Generators Fail</a>
68        </h6>
69<p>
70          All <a class="link" href="../reference/numeric.html" title="Numeric Generators">Numeric Generators</a>
71          (such as <code class="computeroutput"><span class="identifier">double_</span></code>, et.al.)
72          take the value to emit from an attached attribute.
73        </p>
74<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">1.5</span><span class="special">;</span>
75<span class="identifier">generate</span><span class="special">(</span><span class="identifier">out</span><span class="special">,</span> <span class="identifier">double_</span><span class="special">,</span> <span class="identifier">d</span><span class="special">);</span>       <span class="comment">// will emit '1.5' (without the quotes)</span>
76</pre>
77<p>
78          Alternatively, they may be initialized from a literal value. For instance,
79          to emit a constant <code class="computeroutput"><span class="number">1.5</span></code> you
80          may write:
81        </p>
82<pre class="programlisting"><span class="identifier">generate</span><span class="special">(</span><span class="identifier">out</span><span class="special">,</span> <span class="identifier">double_</span><span class="special">(</span><span class="number">1.5</span><span class="special">));</span>     <span class="comment">// will emit '1.5' as well (without the quotes)</span>
83</pre>
84<p>
85          The difference to a simple <code class="computeroutput"><span class="number">1.5</span></code>
86          or <code class="computeroutput"><span class="identifier">lit</span><span class="special">(</span><span class="number">1.5</span><span class="special">)</span></code> is that
87          the <code class="computeroutput"><span class="identifier">double_</span><span class="special">(</span><span class="number">1.5</span><span class="special">)</span></code> consumes
88          an attribute if one is available. Additionally, it compares its immediate
89          value to the value of the supplied attribute, and fails if those are not
90          equal.
91        </p>
92<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">1.5</span><span class="special">;</span>
93<span class="identifier">generate</span><span class="special">(</span><span class="identifier">out</span><span class="special">,</span> <span class="identifier">double_</span><span class="special">(</span><span class="number">1.5</span><span class="special">),</span> <span class="identifier">d</span><span class="special">);</span>  <span class="comment">// will emit '1.5' as long as d == 1.5</span>
94</pre>
95<p>
96          This feature, namely to succeed generating only if the attribute matches
97          the immediate value, enables numeric generators to be used to dynamically
98          control the way output is generated.
99        </p>
100<div class="note"><table border="0" summary="Note">
101<tr>
102<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td>
103<th align="left">Note</th>
104</tr>
105<tr><td align="left" valign="top"><p>
106            Quite a few generators will fail if their immediate value is not equal
107            to the supplied attribute. Among those are all <a class="link" href="../reference/char.html" title="Char Generators">Character
108            Generators</a> and all <a class="link" href="../reference/string.html" title="String Generators">String
109            Generators</a>. Generally, all generators having a sibling created
110            by a variant of <code class="computeroutput"><span class="identifier">lit</span><span class="special">()</span></code>
111            belong into this category.
112          </p></td></tr>
113</table></div>
114<h6>
115<a name="spirit.karma.tutorials.karma_easier_complex.h1"></a>
116          <span class="phrase"><a name="spirit.karma.tutorials.karma_easier_complex.predicates___the_conditionals_for_output_generators"></a></span><a class="link" href="karma_easier_complex.html#spirit.karma.tutorials.karma_easier_complex.predicates___the_conditionals_for_output_generators">Predicates
117          - The Conditionals for Output Generators</a>
118        </h6>
119<p>
120          In addition to the <a class="link" href="../reference/auxiliary/eps.html" title="Epsilon Generator (eps)"><code class="computeroutput"><span class="identifier">eps</span></code></a> generator mentioned earlier
121          <span class="emphasis"><em>Spirit.Karma</em></span> provides two special operators enabling
122          dynamic flow control: the <a class="link" href="../reference/operator/and_predicate.html" title="And-Predicate Generator (&amp;a)">And
123          predicate (unary <code class="computeroutput"><span class="special">&amp;</span></code>)</a>
124          and the <a class="link" href="../reference/operator/not_predicate.html" title="Not-Predicate Generator (!a)">Not
125          predicate (unary <code class="computeroutput"><span class="special">!</span></code>)</a>.
126          The main property of both predicates is to discard all output emitted by
127          the attached generator. This is equivalent to the behavior of predicates
128          used for parsing. There the predicates do not consume any input allowing
129          to look ahead in the input stream. In Karma, the and predicate succeeds
130          as long as its associated generator succeeds, while the not predicate succeeds
131          only if its associated generator fails.
132        </p>
133<div class="note"><table border="0" summary="Note">
134<tr>
135<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td>
136<th align="left">Note</th>
137</tr>
138<tr><td align="left" valign="top"><p>
139            The generator predicates in <span class="emphasis"><em>Spirit.Karma</em></span> consume
140            an attribute, if available. This makes them behave differently from predicates
141            in <span class="emphasis"><em>Spirit.Qi</em></span>, where they do not expose any attribute.
142            This is because predicates allow to make decisions based on data available
143            only at runtime. While in <span class="emphasis"><em>Spirit.Qi</em></span> during parsing
144            the decision is made based on looking ahead a few more input tokens,
145            in <span class="emphasis"><em>Spirit.Karma</em></span> the criteria has to be supplied
146            by the user. The simplest way to do this is by providing an attribute.
147          </p></td></tr>
148</table></div>
149<p>
150          As an example, the following generator succeeds generating
151        </p>
152<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">1.0</span><span class="special">;</span>
153<span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">generate</span><span class="special">(</span><span class="identifier">out</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">double_</span><span class="special">(</span><span class="number">1.0</span><span class="special">),</span> <span class="identifier">d</span><span class="special">));</span>    <span class="comment">// succeeds as d == 1.0</span>
154</pre>
155<p>
156          while this one will fail:
157        </p>
158<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">1.0</span><span class="special">;</span>
159<span class="identifier">BOOST_ASSERT</span><span class="special">(!</span><span class="identifier">generate</span><span class="special">(</span><span class="identifier">out</span><span class="special">,</span> <span class="special">!</span><span class="identifier">double_</span><span class="special">(</span><span class="number">1.0</span><span class="special">),</span> <span class="identifier">d</span><span class="special">));</span>   <span class="comment">// fails as d == 1.0</span>
160</pre>
161<p>
162          Neither of these will emit any output. The predicates discard everything
163          emitted by the generators to which they are applied.
164        </p>
165<h6>
166<a name="spirit.karma.tutorials.karma_easier_complex.h2"></a>
167          <span class="phrase"><a name="spirit.karma.tutorials.karma_easier_complex.ignoring_supplied_attributes"></a></span><a class="link" href="karma_easier_complex.html#spirit.karma.tutorials.karma_easier_complex.ignoring_supplied_attributes">Ignoring
168          Supplied Attributes</a>
169        </h6>
170<p>
171          Sometimes it is desirable to 'skip' (i.e. ignore) a provided attribute.
172          This happens for instance in alternative generators, where some of the
173          alternatives need to extract only part of the overall attribute passed
174          to the alternative generator. <span class="emphasis"><em>Spirit.Karma</em></span> has a special
175          pseudo generator for that: the directive <a class="link" href="../reference/directive/omit.html" title="Generator Directives Consuming Attributes (omit[] and skip[])"><code class="computeroutput"><span class="identifier">omit</span></code></a><code class="computeroutput"><span class="special">[]</span></code>.
176          This directive consumes an attribute of the type defined by its embedded
177          generator but it does not emit any output.
178        </p>
179<div class="note"><table border="0" summary="Note">
180<tr>
181<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td>
182<th align="left">Note</th>
183</tr>
184<tr><td align="left" valign="top"><p>
185            The <span class="emphasis"><em>Spirit.Karma</em></span> <a class="link" href="../reference/directive/omit.html" title="Generator Directives Consuming Attributes (omit[] and skip[])"><code class="computeroutput"><span class="identifier">omit</span></code></a> directive does the 'opposite'
186            of the directive of the same name in <span class="emphasis"><em>Spirit.Qi</em></span>.
187            While the <a class="link" href="../../qi/reference/directive/omit.html" title="Parser Directive Ignoring Attribute (omit[])"><code class="computeroutput"><span class="identifier">omit</span></code></a> in <span class="emphasis"><em>Spirit.Qi</em></span>
188            consumes input without exposing an attribute, its <span class="emphasis"><em>Spirit.Karma</em></span>
189            counterpart consumes an attribute without emitting any output.
190          </p></td></tr>
191</table></div>
192<h6>
193<a name="spirit.karma.tutorials.karma_easier_complex.h3"></a>
194          <span class="phrase"><a name="spirit.karma.tutorials.karma_easier_complex.putting_everything_together"></a></span><a class="link" href="karma_easier_complex.html#spirit.karma.tutorials.karma_easier_complex.putting_everything_together">Putting
195          everything together</a>
196        </h6>
197<p>
198          Very similar to our first example earlier we use two alternatives to allow
199          for the two different output formats depending on whether the imaginary
200          part of the complex number is equal to zero or not. The first alternative
201          is executed if the imaginary part is not zero, the second alternative otherwise.
202          This time we make the decision during runtime using the <a class="link" href="../reference/operator/not_predicate.html" title="Not-Predicate Generator (!a)">Not
203          predicate (unary <code class="computeroutput"><span class="special">!</span></code>)</a>
204          combined with the feature of many Karma primitive generators to <span class="emphasis"><em>fail</em></span>
205          under certain conditions. Here is the first alternative again for your
206          reference:
207        </p>
208<pre class="programlisting"><span class="special">!</span><span class="identifier">double_</span><span class="special">(</span><span class="number">0.0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="char">'('</span> <span class="special">&lt;&lt;</span> <span class="identifier">double_</span> <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="identifier">double_</span> <span class="special">&lt;&lt;</span> <span class="char">')'</span>
209</pre>
210<p>
211          The generator <code class="computeroutput"><span class="special">!</span><span class="identifier">double_</span><span class="special">(</span><span class="number">0.0</span><span class="special">)</span></code>
212          does several things. First, because of the <a class="link" href="../reference/operator/not_predicate.html" title="Not-Predicate Generator (!a)">Not
213          predicate (unary <code class="computeroutput"><span class="special">!</span></code>)</a>,
214          it succeeds only if the <code class="computeroutput"><span class="identifier">double_</span><span class="special">(</span><span class="number">0.0</span><span class="special">)</span></code>
215          generator <span class="emphasis"><em>fails</em></span>, making the whole first alternative
216          fail otherwise. Second, the <code class="computeroutput"><span class="identifier">double_</span><span class="special">(</span><span class="number">0.0</span><span class="special">)</span></code>
217          generator succeeds only if the value of its attribute is equal to its immediate
218          parameter (i.e. in this case <code class="computeroutput"><span class="number">0.0</span></code>).
219          And third, the not predicate does not emit any output (regardless whether
220          it succeeds or fails), discarding any possibly emitted output from the
221          <code class="computeroutput"><span class="identifier">double_</span><span class="special">(</span><span class="number">0.0</span><span class="special">)</span></code>.
222        </p>
223<p>
224          As we pass the imaginary part of the complex number as the attribute value
225          for the <code class="computeroutput"><span class="special">!</span><span class="identifier">double_</span><span class="special">(</span><span class="number">0.0</span><span class="special">)</span></code>,
226          the overall first alternative will be chosen only if it is not equal to
227          zero (the <code class="computeroutput"><span class="special">!</span><span class="identifier">double_</span><span class="special">(</span><span class="number">0.0</span><span class="special">)</span></code>
228          does not fail). That is exactly what we need!
229        </p>
230<p>
231          Now, the second alternative has to emit the real part of the complex number
232          only. In order to simplify the overall grammar we strive to unify the attribute
233          types of all alternatives. As the attribute type exposed by the first alternative
234          is <code class="computeroutput"><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span></code>,
235          we need to skip the first and last element of the attribute (remember,
236          we pass the real part as the second attribute element). We achieve this
237          by using the <code class="computeroutput"><span class="identifier">omit</span><span class="special">[]</span></code>
238          directive:
239        </p>
240<pre class="programlisting"><span class="identifier">omit</span><span class="special">[</span><span class="identifier">double_</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">double_</span> <span class="special">&lt;&lt;</span> <span class="identifier">omit</span><span class="special">[</span><span class="identifier">double_</span><span class="special">]</span>
241</pre>
242<p>
243          The overall attribute of this expression is <code class="computeroutput"><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span></code>, but the <code class="computeroutput"><span class="identifier">omit</span><span class="special">[]</span></code> 'eats up' the first and the last element.
244          The output emitted by this expression consist of a single generated double
245          representing the second element of the tuple, i.e. the real part of our
246          complex number.
247        </p>
248<div class="important"><table border="0" summary="Important">
249<tr>
250<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../images/important.png"></td>
251<th align="left">Important</th>
252</tr>
253<tr><td align="left" valign="top"><p>
254            Generally, it is preferable to use generator constructs not requiring
255            semantic actions. The reason is that semantic actions often use constructs
256            like: <code class="computeroutput"><span class="identifier">double_</span><span class="special">[</span><span class="identifier">_1</span> <span class="special">=</span> <span class="identifier">c</span><span class="special">.</span><span class="identifier">real</span><span class="special">()]</span></code>.
257            But this assignment is a real one! The data is in fact <span class="emphasis"><em>copied</em></span>
258            to the attribute value of the generator attached to the action. On the
259            other hand, grammars without any semantic actions usually don't have
260            to copy the attributes, making them more efficient.
261          </p></td></tr>
262</table></div>
263</div>
264<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
265<td align="left"></td>
266<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p>
267        Distributed under the Boost Software License, Version 1.0. (See accompanying
268        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
269      </p>
270</div></td>
271</tr></table>
272<hr>
273<div class="spirit-nav">
274<a accesskey="p" href="karma_complex.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorials.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="karma_adapted_complex.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
275</div>
276</body>
277</html>
278