Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / spirit / doc / html / spirit / karma / tutorials / karma_complex.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Complex - A first more complex generator</title>
5 <link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
7 <link rel="home" href="../../../index.html" title="Spirit 2.5.2">
8 <link rel="up" href="../tutorials.html" title="Tutorials">
9 <link rel="prev" href="semantic_actions.html" title="Generator Semantic Actions">
10 <link rel="next" href="karma_easier_complex.html" title="Complex - Made easier">
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="semantic_actions.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_easier_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_complex"></a><a class="link" href="karma_complex.html" title="Complex - A first more complex generator">Complex - A first
28         more complex generator</a>
29 </h4></div></div></div>
30 <p>
31           In this section we will develop a generator for complex numbers, allowing
32           to represent a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span></code> either as <code class="computeroutput"><span class="special">(</span><span class="identifier">real</span><span class="special">,</span> <span class="identifier">imag</span><span class="special">)</span></code>
33           (where <code class="computeroutput"><span class="identifier">real</span></code> and <code class="computeroutput"><span class="identifier">imag</span></code> are the real and imaginary parts
34           of the complex number) or as a simple <code class="computeroutput"><span class="identifier">real</span></code>
35           if the imaginary part happens to be equal to zero. This example will highlight
36           the power of <span class="emphasis"><em>Spirit.Karma</em></span> allowing to combine compile
37           time definition of formatting rules with runtime based decisions which
38           of the rules to apply. Also this time, we're using <a href="../../../../../../../libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a>
39           to do the semantic actions.
40         </p>
41 <p>
42           Our goal is to allow for two different output formats to be applied depending
43           on whether the imaginary part of the complex number is zero or not. Let's
44           write both as a set of alternatives:
45         </p>
46 <pre class="programlisting">    <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>
47 <span class="special">|</span>   <span class="identifier">double_</span>
48 </pre>
49 <p>
50           where the first alternative should be used for numbers having a non-zero
51           imaginary part, while the second is for real numbers. Generally, alternatives
52           are tried in the sequence of their definition as long until one of the
53           expressions (as delimited by <code class="computeroutput"><span class="char">'|'</span></code>)
54           succeeds. If no generator expression succeeds the whole alternative fails.
55         </p>
56 <p>
57           If we left this formatting grammar as is our generator would always choose
58           the first alternative. We need to add some additional rules allowing to
59           make the first alternative fail. So, if the first alternative fails the
60           second one will be chosen instead. The decision about whether to choose
61           the first alternative has to be made at runtime as only then we actually
62           know the value of the imaginary part of the complex number. <span class="emphasis"><em>Spirit.Karma</em></span>
63           provides us with with a primitive generator <code class="computeroutput"><span class="identifier">eps</span><span class="special">()</span></code>, which is usable as a semantic predicate.
64           It has the property to 'succeed' generating only if its argument is true
65           (while it never generates any output on its own).
66         </p>
67 <pre class="programlisting"><span class="keyword">double</span> <span class="identifier">imag</span> <span class="special">=</span> <span class="special">...;</span>     <span class="comment">// imaginary part</span>
68
69     <span class="identifier">eps</span><span class="special">(</span><span class="identifier">imag</span> <span class="special">!=</span> <span class="number">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>
70 <span class="special">|</span>   <span class="identifier">double_</span>
71 </pre>
72 <p>
73           If one of the generator elements of a sequence fails the whole sequence
74           will fail. This is exactly what we need, forcing the second alternative
75           to be chosen for complex numbers with imaginary parts equal to zero.
76         </p>
77 <p>
78           Now on to the full example, this time with the proper semantic actions
79           (the complete cpp file for this example can be found here: <a href="../../../../../example/karma/complex_number.cpp" target="_top">complex_number.cpp</a>).
80         </p>
81 <p>
82           We will use the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span></code> type for this and all subsequent
83           related examples. And here you can see the full code of the generator allowing
84           to output a complex number either as a pair of numbers (if the imaginary
85           part is non-zero) or as a single number (if the complex is a real number):
86         </p>
87 <p>
88 </p>
89 <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>
90 <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>
91 <span class="special">{</span>
92     <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">eps</span><span class="special">;</span>
93     <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>
94     <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">_1</span><span class="special">;</span>
95     <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>
96
97     <span class="keyword">return</span> <span class="identifier">generate</span><span class="special">(</span><span class="identifier">sink</span><span class="special">,</span>
98         <span class="comment">//  Begin grammar</span>
99         <span class="special">(</span>
100             <span class="identifier">eps</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="special">!=</span> <span class="number">0</span><span class="special">)</span> <span class="special">&lt;&lt;</span>
101             <span class="char">'('</span> <span class="special">&lt;&lt;</span> <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> <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <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">imag</span><span class="special">()]</span> <span class="special">&lt;&lt;</span> <span class="char">')'</span>
102         <span class="special">|</span>   <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>
103         <span class="special">)</span>
104         <span class="comment">//  End grammar</span>
105     <span class="special">);</span>
106 <span class="special">}</span>
107 </pre>
108 <p>
109         </p>
110 <p>
111           The <code class="computeroutput"><span class="identifier">double_</span></code> generators
112           have this semantic action attached:
113         </p>
114 <pre class="programlisting"><span class="identifier">_1</span> <span class="special">=</span> <span class="identifier">n</span>
115 </pre>
116 <p>
117           which passes <code class="computeroutput"><span class="identifier">n</span></code> to the first
118           element of the s generator's attached semantic action. Remember, semantic
119           actions in <span class="emphasis"><em>Spirit.Karma</em></span> are called before the corresponding
120           generator is invoked and they are expected to provide the generator with
121           the data to be used. The semantic action above assigns the value to be
122           generated (<code class="computeroutput"><span class="identifier">n</span></code>) to the generator
123           (actually, the attribute of <code class="computeroutput"><span class="identifier">double_</span></code>).
124           <code class="computeroutput"><span class="identifier">_1</span></code> is a Phoenix placeholder
125           referring to the attribute of the semantic action's attached generator.
126           If you need more information about semantic actions, you may want to read
127           about them in this section: <a class="link" href="semantic_actions.html" title="Generator Semantic Actions">Semantic
128           Actions</a>.
129         </p>
130 <p>
131           These semantic actions are easy to understand but have the unexpected side
132           effect of being slightly less efficient than it could be. In addition they
133           tend to make the formatting grammar less readable. We will see in one of
134           the next sections how it is possible to use other, built-in features of
135           <span class="emphasis"><em>Spirit.Karma</em></span> to get rid of the semantic actions altogether.
136           When writing your grammars in Spirit you should always try to avoid semantic
137           actions which is often possible. Semantic actions are really powerful tools
138           but grammars tend to be more efficient and readable without them.
139         </p>
140 </div>
141 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
142 <td align="left"></td>
143 <td align="right"><div class="copyright-footer">Copyright &#169; 2001-2011 Joel de Guzman, Hartmut Kaiser<p>
144         Distributed under the Boost Software License, Version 1.0. (See accompanying
145         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>)
146       </p>
147 </div></td>
148 </tr></table>
149 <hr>
150 <div class="spirit-nav">
151 <a accesskey="p" href="semantic_actions.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_easier_complex.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
152 </div>
153 </body>
154 </html>