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"><</span><span class="keyword">typename</span> <span class="identifier">OutputIterator</span><span class="special">></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"><</span><span class="keyword">double</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</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"><<</span> <span class="char">'('</span> <span class="special"><<</span> <span class="identifier">double_</span> <span class="special"><<</span> <span class="string">", "</span> <span class="special"><<</span> <span class="identifier">double_</span> <span class="special"><<</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"><<</span> <span class="identifier">double_</span> <span class="special"><<</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 (&a)">And 123 predicate (unary <code class="computeroutput"><span class="special">&</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">&</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"><<</span> <span class="char">'('</span> <span class="special"><<</span> <span class="identifier">double_</span> <span class="special"><<</span> <span class="string">", "</span> <span class="special"><<</span> <span class="identifier">double_</span> <span class="special"><<</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"><</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">></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"><<</span> <span class="identifier">double_</span> <span class="special"><<</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"><</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">></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