Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r54699 - trunk/libs/spirit/doc/html/spirit/karma/tutorials
From: hartmut.kaiser_at_[hidden]
Date: 2009-07-05 22:13:17


Author: hkaiser
Date: 2009-07-05 22:13:16 EDT (Sun, 05 Jul 2009)
New Revision: 54699
URL: http://svn.boost.org/trac/boost/changeset/54699

Log:
Spirit: added missing file
Added:
   trunk/libs/spirit/doc/html/spirit/karma/tutorials/semantic_actions.html (contents, props changed)

Added: trunk/libs/spirit/doc/html/spirit/karma/tutorials/semantic_actions.html
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/html/spirit/karma/tutorials/semantic_actions.html 2009-07-05 22:13:16 EDT (Sun, 05 Jul 2009)
@@ -0,0 +1,277 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Semantic Actions</title>
+<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.75.0">
+<link rel="home" href="../../../index.html" title="Spirit 2.1">
+<link rel="up" href="../tutorials.html" title="Tutorials">
+<link rel="prev" href="warming_up.html" title="Warming up">
+<link rel="next" href="../quick_reference.html" title="Quick Reference">
+</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">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="warming_up.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorials.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="../quick_reference.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+<div class="section" title="Semantic Actions">
+<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 alsways 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 provide the data to be generated to 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">&amp;</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>
+<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>
+ We present various ways to attach semantic actions:
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ Using plain function pointer
+ </li>
+<li class="listitem">
+ Using simple function object
+ </li>
+<li class="listitem">
+ Using Boost.Bind
+ with a plain function
+ </li>
+<li class="listitem">
+ Using Boost.Bind
+ with a member function
+ </li>
+<li class="listitem">
+ Using Boost.Lambda
+</li>
+</ul></div>
+<p>
+ Let's assume we have:
+ </p>
+<p>
+ </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">&amp;</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">&amp;</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">&amp;</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>
+ </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.
+ </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>
+<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">&lt;&lt;</span> <span class="identifier">int_</span><span class="special">[&amp;</span><span class="identifier">read_function</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="char">'}'</span><span class="special">);</span>
+</pre>
+<p>
+ </p>
+<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.
+ </p>
+<p>
+ The next example shows how to attach a simple function object:
+ </p>
+<p>
+ </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">&lt;&lt;</span> <span class="identifier">int_</span><span class="special">[</span><span class="identifier">read_action</span><span class="special">()]</span> <span class="special">&lt;&lt;</span> <span class="char">'}'</span><span class="special">);</span>
+</pre>
+<p>
+ </p>
+<p>
+ </p>
+<p>
+ We can use Boost.Bind
+ to 'bind' member functions:
+ </p>
+<p>
+ </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">&lt;&lt;</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">(&amp;</span><span class="identifier">reader</span><span class="special">::</span><span class="identifier">print</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">r</span><span class="special">,</span> <span class="identifier">_1</span><span class="special">)]</span> <span class="special">&lt;&lt;</span> <span class="char">'}'</span><span class="special">);</span>
+</pre>
+<p>
+ </p>
+<p>
+ </p>
+<p>
+ Likewise, we can also use Boost.Bind
+ to 'bind' plain functions:
+ </p>
+<p>
+ </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">&lt;&lt;</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">(&amp;</span><span class="identifier">read_function</span><span class="special">,</span> <span class="identifier">_1</span><span class="special">)]</span> <span class="special">&lt;&lt;</span> <span class="char">'}'</span><span class="special">);</span>
+</pre>
+<p>
+ </p>
+<p>
+ </p>
+<p>
+ And last but not least, we can also use Boost.Lambda:
+ </p>
+<p>
+ </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">&lt;&lt;</span> <span class="identifier">int_</span><span class="special">[</span><span class="identifier">strm</span> <span class="special">&gt;&gt;</span> <span class="identifier">lambda</span><span class="special">::</span><span class="identifier">_1</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="char">'}'</span><span class="special">);</span>
+</pre>
+<p>
+ </p>
+<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 Boost.Bind
+ and Boost.Lambda.
+ </p>
+<p>
+ The examples above can be found here: actions.cpp
+ </p>
+<a name="spirit.karma.tutorials.semantic_actions.phoenix"></a><h6>
+<a name="id1074998"></a>
+ <a class="link" href="semantic_actions.html#spirit.karma.tutorials.semantic_actions.phoenix">Phoenix</a>
+ </h6>
+<p>
+ Phoenix, a companion
+ library bundled with Spirit, is specifically suited for binding semantic
+ actions. It is like Boost.Lambda
+ 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>
+<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-2009 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 http://www.boost.org/LICENSE_1_0.txt)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="warming_up.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorials.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="../quick_reference.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk