<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> <title>Semantic Actions</title> <link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> <meta name="generator" content="DocBook XSL Stylesheets V1.75.0"> <link rel="home" href="../../../index.html" title="Spirit 2.4"> <link rel="up" href="../tutorials.html" title="Tutorials"> <link rel="prev" href="warming_up.html" title="Warming up"> <link rel="next" href="karma_complex.html" title="Complex - A first more complex generator"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> <table cellpadding="2" width="100%"><tr> <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td> <td align="center"><a href="../../../../../../../index.html">Home</a></td> <td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td> <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> <td align="center"><a href="../../../../../../../more/index.htm">More</a></td> </tr></table> <hr> <div class="spirit-nav"> <a accesskey="p" href="warming_up.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_complex.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="spirit.karma.tutorials.semantic_actions"></a><a class="link" href="semantic_actions.html" title="Semantic Actions">Semantic Actions</a> </h4></div></div></div> <p> In the previous section we mentioned a very important difference between parsers and generators. While parsers may be used without 'producing' any data, generators always need data to generate the output from. We mentioned one way of passing data to the generator by supplying it as a parameter to one of the main API functions (for instance <code class="computeroutput"><span class="identifier">generate</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">generate_delimited</span><span class="special">()</span></code>). But sometimes this is not possible or not desireable. </p> <p> Very much like for <span class="emphasis"><em>Spirit.Qi</em></span> we have semantic actions in <span class="emphasis"><em>Spirit.Karma</em></span> as well. Semantic actions may be attached to any point in the grammar specification. These actions are C++ functions or function objects that are called whenever a part of the generator is about to be invoked. Say you have a generator <code class="computeroutput"><span class="identifier">G</span></code>, and a C++ function <code class="computeroutput"><span class="identifier">F</span></code>, you can make the generator call <code class="computeroutput"><span class="identifier">F</span></code> just before it gets invoked by attaching <code class="computeroutput"><span class="identifier">F</span></code>: </p> <pre class="programlisting"><span class="identifier">G</span><span class="special">[</span><span class="identifier">F</span><span class="special">]</span> </pre> <p> The expression above links <code class="computeroutput"><span class="identifier">F</span></code> to the generator, <code class="computeroutput"><span class="identifier">G</span></code>. </p> <p> Semantic actions in <span class="emphasis"><em>Spirit.Qi</em></span> are invoked after a parser successfully matches its input and the matched value is passed into the semantic action. In <span class="emphasis"><em>Spirit.Karma</em></span> the opposite happens. Semantic actions are called before its associated generator is invoked. They may provide the data required by the generator. </p> <p> The function/function object signature depends on the type of the generator to which it is attached. The generator <code class="computeroutput"><span class="identifier">double_</span></code> expects the number to generate. Thus, if we were to attach a function <code class="computeroutput"><span class="identifier">F</span></code> to <code class="computeroutput"><span class="identifier">double_</span></code>, we need <code class="computeroutput"><span class="identifier">F</span></code> to be declared as: </p> <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">F</span><span class="special">(</span><span class="keyword">double</span><span class="special">&</span> <span class="identifier">n</span><span class="special">);</span> </pre> <p> where the function is expected to initialize the parameter <code class="computeroutput"><span class="identifier">n</span></code> with the value to generate. </p> <div class="important"><table border="0" summary="Important"> <tr> <td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../images/important.png"></td> <th align="left">Important</th> </tr> <tr><td align="left" valign="top"> <p> Generally, and more formally, the semantic action <code class="computeroutput"><span class="identifier">F</span></code> attached to a generator <code class="computeroutput"><span class="identifier">G</span></code> needs to take a reference to the generator's attribute type as its first parameter. For more information about generator attributes please see the section Generator Attributes. </p> <p> In the example above the function F takes a <code class="computeroutput"><span class="keyword">double</span><span class="special">&</span></code> as its first parameter as the attribute of the <code class="computeroutput"><span class="identifier">double_</span></code> generator happens to be a <code class="computeroutput"><span class="keyword">double</span></code>. </p> </td></tr> </table></div> <p> There are actually 2 more arguments being passed (the generator context and a reference to a boolean 'pass' parameter). We don't need these, for now, but we'll see more on these other arguments later. <span class="emphasis"><em>Spirit.Karma</em></span> allows us to bind a single argument function, like above. The other arguments are simply ignored. </p> <p> To sum up, the possible signatures for semantic actions are: </p> <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Attrib</span><span class="special">&);</span> <span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Attrib</span><span class="special">&,</span> <span class="identifier">Context</span><span class="special">&);</span> <span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Attrib</span><span class="special">&,</span> <span class="identifier">Context</span><span class="special">&,</span> <span class="keyword">bool</span><span class="special">&);</span> </pre> <a name="spirit.karma.tutorials.semantic_actions.examples_of_semantic_actions"></a><h6> <a name="id997384"></a> <a class="link" href="semantic_actions.html#spirit.karma.tutorials.semantic_actions.examples_of_semantic_actions">Examples of Semantic Actions</a> </h6> <p> In the following example we present various ways to attach semantic actions: </p> <div class="itemizedlist"><ul class="itemizedlist" type="disc"> <li class="listitem"> Using a plain function pointer </li> <li class="listitem"> Using a simple function object </li> <li class="listitem"> Using <a href="../../../../../../../libs/bind/index.html" target="_top">Boost.Bind</a> with a plain function </li> <li class="listitem"> Using <a href="../../../../../../../libs/bind/index.html" target="_top">Boost.Bind</a> with a member function </li> <li class="listitem"> Using <a href="../../../../../../../libs/lambda/index.html" target="_top">Boost.Lambda</a> </li> </ul></div> <p> Let's assume we have: </p> <p> </p> <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">client</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">karma</span> <span class="special">=</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="comment">// A plain function </span> <span class="keyword">void</span> <span class="identifier">read_function</span><span class="special">(</span><span class="keyword">int</span><span class="special">&</span> <span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">42</span><span class="special">;</span> <span class="special">}</span> <span class="comment">// A member function </span> <span class="keyword">struct</span> <span class="identifier">reader</span> <span class="special">{</span> <span class="keyword">void</span> <span class="identifier">print</span><span class="special">(</span><span class="keyword">int</span><span class="special">&</span> <span class="identifier">i</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">42</span><span class="special">;</span> <span class="special">}</span> <span class="special">};</span> <span class="comment">// A function object </span> <span class="keyword">struct</span> <span class="identifier">read_action</span> <span class="special">{</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span><span class="special">&</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">unused_type</span><span class="special">,</span> <span class="identifier">unused_type</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">42</span><span class="special">;</span> <span class="special">}</span> <span class="special">};</span> <span class="special">}</span> </pre> <p> </p> <p> Take note that with function objects, we need to have an <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> with 3 arguments. Since we don't care about the other two, we can use <code class="computeroutput"><span class="identifier">unused_type</span></code> for these. We'll see more of <code class="computeroutput"><span class="identifier">unused_type</span></code> elsewhere. Get used to it. <code class="computeroutput"><span class="identifier">unused_type</span></code> is a Spirit supplied support class. Most of the time it stands for 'I don't care, just use the appropriate default'. </p> <p> All following examples generate outputs of the form: </p> <pre class="programlisting"><span class="string">"{integer}"</span> </pre> <p> An integer inside the curly braces. </p> <p> The first example shows how to attach a plain function: </p> <p> </p> <pre class="programlisting"><span class="identifier">generate</span><span class="special">(</span><span class="identifier">outiter</span><span class="special">,</span> <span class="char">'{'</span> <span class="special"><<</span> <span class="identifier">int_</span><span class="special">[&</span><span class="identifier">read_function</span><span class="special">]</span> <span class="special"><<</span> <span class="char">'}'</span><span class="special">);</span> </pre> <p> </p> <p> What's new? Well <code class="computeroutput"><span class="identifier">int_</span></code> is the sibbling of <code class="computeroutput"><span class="identifier">double_</span></code>. I'm sure you can guess what this generator does and what type of attribute it expects. </p> <p> The next example shows how to attach a simple function object: </p> <p> </p> <pre class="programlisting"><span class="identifier">generate</span><span class="special">(</span><span class="identifier">outiter</span><span class="special">,</span> <span class="char">'{'</span> <span class="special"><<</span> <span class="identifier">int_</span><span class="special">[</span><span class="identifier">read_action</span><span class="special">()]</span> <span class="special"><<</span> <span class="char">'}'</span><span class="special">);</span> </pre> <p> </p> <p> We can use <a href="../../../../../../../libs/bind/index.html" target="_top">Boost.Bind</a> to 'bind' member functions: </p> <p> </p> <pre class="programlisting"><span class="identifier">reader</span> <span class="identifier">r</span><span class="special">;</span> <span class="identifier">generate</span><span class="special">(</span><span class="identifier">outiter</span><span class="special">,</span> <span class="char">'{'</span> <span class="special"><<</span> <span class="identifier">int_</span><span class="special">[</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">reader</span><span class="special">::</span><span class="identifier">print</span><span class="special">,</span> <span class="special">&</span><span class="identifier">r</span><span class="special">,</span> <span class="identifier">_1</span><span class="special">)]</span> <span class="special"><<</span> <span class="char">'}'</span><span class="special">);</span> </pre> <p> </p> <p> Likewise, we can also use <a href="../../../../../../../libs/bind/index.html" target="_top">Boost.Bind</a> to 'bind' plain functions: </p> <p> </p> <pre class="programlisting"><span class="identifier">generate</span><span class="special">(</span><span class="identifier">outiter</span><span class="special">,</span> <span class="char">'{'</span> <span class="special"><<</span> <span class="identifier">int_</span><span class="special">[</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">read_function</span><span class="special">,</span> <span class="identifier">_1</span><span class="special">)]</span> <span class="special"><<</span> <span class="char">'}'</span><span class="special">);</span> </pre> <p> </p> <p> And last but not least, we can also use <a href="../../../../../../../libs/lambda/index.html" target="_top">Boost.Lambda</a>: </p> <p> </p> <pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">stringstream</span> <span class="identifier">strm</span><span class="special">(</span><span class="string">"42"</span><span class="special">);</span> <span class="identifier">generate</span><span class="special">(</span><span class="identifier">outiter</span><span class="special">,</span> <span class="char">'{'</span> <span class="special"><<</span> <span class="identifier">int_</span><span class="special">[</span><span class="identifier">strm</span> <span class="special">>></span> <span class="identifier">lambda</span><span class="special">::</span><span class="identifier">_1</span><span class="special">]</span> <span class="special"><<</span> <span class="char">'}'</span><span class="special">);</span> </pre> <p> </p> <p> There are more ways to bind semantic action functions, but the examples above are the most common. Attaching semantic actions is the first hurdle one has to tackle when getting started with generating with Spirit. If you didn't do so yet, it is probably a good idea to familiarize yourself with the tools behind it such as <a href="../../../../../../../libs/bind/index.html" target="_top">Boost.Bind</a> and <a href="../../../../../../../libs/lambda/index.html" target="_top">Boost.Lambda</a>. </p> <p> The examples above can be found here: <a href="../../../../../example/karma/actions.cpp" target="_top">actions.cpp</a> </p> <a name="spirit.karma.tutorials.semantic_actions.phoenix"></a><h6> <a name="id1000407"></a> <a class="link" href="semantic_actions.html#spirit.karma.tutorials.semantic_actions.phoenix">Phoenix</a> </h6> <p> <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a>, a companion library bundled with Spirit, is specifically suited for binding semantic actions. It is like <a href="../../../../../../../libs/lambda/index.html" target="_top">Boost.Lambda</a> on steroids, with special custom features that make it easy to integrate semantic actions with Spirit. If your requirements go beyond simple to moderate generation, I suggest you use this library. Examples presented henceforth shall be using the Phoenix library exclusively. </p> <div class="important"><table border="0" summary="Important"> <tr> <td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../images/important.png"></td> <th align="left">Important</th> </tr> <tr><td align="left" valign="top"> <p> There are different ways to write semantic actions for <span class="emphasis"><em>Spirit.Karma</em></span>: using plain functions, <a href="../../../../../../../libs/bind/index.html" target="_top">Boost.Bind</a>, <a href="../../../../../../../libs/lambda/index.html" target="_top">Boost.Lambda</a>, or <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a>. The latter three allow you to use special placeholders to control parameter placement (<code class="computeroutput"><span class="identifier">_1</span></code>, <code class="computeroutput"><span class="identifier">_2</span></code>, etc.). Each of those libraries has it's own implementation of the placeholders, all in different namespaces. You have to make sure not to mix placeholders with a library they don't belong to and not to use different libraries while writing a semantic action. </p> <p> Generally, for <a href="../../../../../../../libs/bind/index.html" target="_top">Boost.Bind</a>, use <code class="computeroutput"><span class="special">::</span><span class="identifier">_1</span></code>, <code class="computeroutput"><span class="special">::</span><span class="identifier">_2</span></code>, etc. (yes, these placeholders are defined in the globl namespace). </p> <p> For <a href="../../../../../../../libs/lambda/index.html" target="_top">Boost.Lambda</a> use the placeholders defined in the namespace <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span></code>. </p> <p> For semantic actions written using <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a> use the placeholders defined in the namespace <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span></code>. Please note that all existing placeholders for your convenience are also available from the namespace <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">karma</span></code>. </p> </td></tr> </table></div> </div> <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> <td align="left"></td> <td align="right"><div class="copyright-footer">Copyright © 2001-2010 Joel de Guzman, Hartmut Kaiser<p> Distributed under the Boost Software License, Version 1.0. (See accompanying 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>) </p> </div></td> </tr></table> <hr> <div class="spirit-nav"> <a accesskey="p" href="warming_up.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_complex.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> </div> </body> </html>