diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /libs/spirit/doc/html/spirit/qi/tutorials | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'libs/spirit/doc/html/spirit/qi/tutorials')
12 files changed, 3050 insertions, 0 deletions
diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/complex___our_first_complex_parser.html b/libs/spirit/doc/html/spirit/qi/tutorials/complex___our_first_complex_parser.html new file mode 100755 index 0000000000..528ea13152 --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/complex___our_first_complex_parser.html @@ -0,0 +1,155 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Complex - Our first complex parser</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="semantic_actions.html" title="Parser Semantic Actions"> +<link rel="next" href="sum___adding_numbers.html" title="Sum - adding numbers"> +</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="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="sum___adding_numbers.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.qi.tutorials.complex___our_first_complex_parser"></a><a class="link" href="complex___our_first_complex_parser.html" title="Complex - Our first complex parser">Complex + - Our first complex parser</a> +</h4></div></div></div> +<p> + Well, not really a complex parser, but a parser that parses complex numbers. + This time, we're using <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a> + to do the semantic actions. + </p> +<p> + Here's a simple parser expression for complex numbers: + </p> +<pre class="programlisting"> <span class="char">'('</span> <span class="special">>></span> <span class="identifier">double_</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="special">>></span> <span class="char">')'</span> +<span class="special">|</span> <span class="identifier">double_</span> +</pre> +<p> + What's new? Well, we have: + </p> +<div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + Alternates: e.g. <code class="computeroutput"><span class="identifier">a</span> <span class="special">|</span> <span class="identifier">b</span></code>. + Try <code class="computeroutput"><span class="identifier">a</span></code> first. If it + succeeds, good. If not, try the next alternative, <code class="computeroutput"><span class="identifier">b</span></code>. + </li> +<li class="listitem"> + Optionals: e.g. -p. Match the parser p zero or one time. + </li> +</ol></div> +<p> + The complex parser presented above reads as: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + One or two real numbers in parentheses, separated by comma (the second + number is optional) + </li> +<li class="listitem"> + <span class="bold"><strong>OR</strong></span> a single real number. + </li> +</ul></div> +<p> + This parser can parse complex numbers of the form: + </p> +<pre class="programlisting"><span class="special">(</span><span class="number">123.45</span><span class="special">,</span> <span class="number">987.65</span><span class="special">)</span> +<span class="special">(</span><span class="number">123.45</span><span class="special">)</span> +<span class="number">123.45</span> +</pre> +<p> + Here goes, this time with actions: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">client</span> +<span class="special">{</span> + <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> + <span class="keyword">bool</span> <span class="identifier">parse_complex</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">last</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="identifier">c</span><span class="special">)</span> + <span class="special">{</span> + <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">qi</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span> + <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">qi</span><span class="special">::</span><span class="identifier">_1</span><span class="special">;</span> + <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">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">;</span> + <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">ascii</span><span class="special">::</span><span class="identifier">space</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">ref</span><span class="special">;</span> + + <span class="keyword">double</span> <span class="identifier">rN</span> <span class="special">=</span> <span class="number">0.0</span><span class="special">;</span> + <span class="keyword">double</span> <span class="identifier">iN</span> <span class="special">=</span> <span class="number">0.0</span><span class="special">;</span> + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">phrase_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> + + <span class="comment">// Begin grammar</span> + <span class="special">(</span> + <span class="char">'('</span> <span class="special">>></span> <span class="identifier">double_</span><span class="special">[</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">rN</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</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="identifier">ref</span><span class="special">(</span><span class="identifier">iN</span><span class="special">)</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> <span class="identifier">double_</span><span class="special">[</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">rN</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">),</span> + <span class="comment">// End grammar</span> + + <span class="identifier">space</span><span class="special">);</span> + + <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">r</span> <span class="special">||</span> <span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">)</span> <span class="comment">// fail if we did not get a full match</span> + <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span> + <span class="identifier">c</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="identifier">rN</span><span class="special">,</span> <span class="identifier">iN</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">r</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + The full cpp file for this example can be found here: <a href="../../../../../example/qi/complex_number.cpp" target="_top">../../example/qi/complex_number.cpp</a> + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + Those with experience using <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a> + might be confused with the placeholders that we are using (i.e. <code class="computeroutput"><span class="identifier">_1</span></code>, <code class="computeroutput"><span class="identifier">_2</span></code>, + etc.). Please be aware that we are not using the same placeholders supplied + by Phoenix. Take note that we are pulling in the placeholders from 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">qi</span></code>. These placeholders are specifically + tailored for Spirit. + </p></td></tr> +</table></div> +<p> + The <code class="computeroutput"><span class="identifier">double_</span></code> parser attaches + this action: + </p> +<pre class="programlisting"><span class="identifier">ref</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">_1</span> +</pre> +<p> + This assigns the parsed result (actually, the attribute of <code class="computeroutput"><span class="identifier">double_</span></code>) to n. <code class="computeroutput"><span class="identifier">ref</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span></code> + tells Phoenix that <code class="computeroutput"><span class="identifier">n</span></code> is + a mutable reference. <code class="computeroutput"><span class="identifier">_1</span></code> + is a Phoenix placeholder for the parsed result attribute. + </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-2011 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="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="sum___adding_numbers.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/employee___parsing_into_structs.html b/libs/spirit/doc/html/spirit/qi/tutorials/employee___parsing_into_structs.html new file mode 100755 index 0000000000..9ae9f3286d --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/employee___parsing_into_structs.html @@ -0,0 +1,437 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Employee - Parsing into structs</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="roman_numerals.html" title="Roman Numerals"> +<link rel="next" href="mini_xml___asts_.html" title="Mini XML - ASTs!"> +</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="roman_numerals.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="mini_xml___asts_.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.qi.tutorials.employee___parsing_into_structs"></a><a class="link" href="employee___parsing_into_structs.html" title="Employee - Parsing into structs">Employee + - Parsing into structs</a> +</h4></div></div></div> +<p> + It's a common question in the <a href="http://www.nabble.com/The-Spirit-Parser-Library-f3430.html" target="_top">Spirit + General List</a>: How do I parse and place the results into a C++ struct? + Of course, at this point, you already know various ways to do it, using + semantic actions. There are many ways to skin a cat. Spirit2, being fully + attributed, makes it even easier. The next example demonstrates some features + of Spirit2 that make this easy. In the process, you'll learn about: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + More about attributes + </li> +<li class="listitem"> + Auto rules + </li> +<li class="listitem"> + Some more built-in parsers + </li> +<li class="listitem"> + Directives + </li> +</ul></div> +<p> + First, let's create a struct representing an employee: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">employee</span> +<span class="special">{</span> + <span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">surname</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">forename</span><span class="special">;</span> + <span class="keyword">double</span> <span class="identifier">salary</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + Then, we need to tell <a href="../../../../../../../libs/fusion/doc/html/index.html" target="_top">Boost.Fusion</a> + about our employee struct to make it a first-class fusion citizen that + the grammar can utilize. If you don't know fusion yet, it is a <a href="http://www.boost.org/" target="_top">Boost</a> + library for working with heterogeneous collections of data, commonly referred + to as tuples. Spirit uses fusion extensively as part of its infrastructure. + </p> +<p> + In fusion's view, a struct is just a form of a tuple. You can adapt any + struct to be a fully conforming fusion tuple: + </p> +<p> +</p> +<pre class="programlisting"><span class="identifier">BOOST_FUSION_ADAPT_STRUCT</span><span class="special">(</span> + <span class="identifier">client</span><span class="special">::</span><span class="identifier">employee</span><span class="special">,</span> + <span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">age</span><span class="special">)</span> + <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">surname</span><span class="special">)</span> + <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">forename</span><span class="special">)</span> + <span class="special">(</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">salary</span><span class="special">)</span> +<span class="special">)</span> +</pre> +<p> + </p> +<p> + Now we'll write a parser for our employee. Inputs will be of the form: + </p> +<pre class="programlisting"><span class="identifier">employee</span><span class="special">{</span> <span class="identifier">age</span><span class="special">,</span> <span class="string">"surname"</span><span class="special">,</span> <span class="string">"forename"</span><span class="special">,</span> <span class="identifier">salary</span> <span class="special">}</span> +</pre> +<p> + Here goes: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">employee_parser</span> <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">grammar</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">employee</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">employee_parser</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">employee_parser</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">start</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> + + <span class="identifier">quoted_string</span> <span class="special">%=</span> <span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">>></span> <span class="char">'"'</span><span class="special">];</span> + + <span class="identifier">start</span> <span class="special">%=</span> + <span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span> + <span class="special">>></span> <span class="char">'{'</span> + <span class="special">>></span> <span class="identifier">int_</span> <span class="special">>></span> <span class="char">','</span> + <span class="special">>></span> <span class="identifier">quoted_string</span> <span class="special">>></span> <span class="char">','</span> + <span class="special">>></span> <span class="identifier">quoted_string</span> <span class="special">>></span> <span class="char">','</span> + <span class="special">>></span> <span class="identifier">double_</span> + <span class="special">>></span> <span class="char">'}'</span> + <span class="special">;</span> + <span class="special">}</span> + + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">quoted_string</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">employee</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">start</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + The full cpp file for this example can be found here: <a href="../../../../../example/qi/employee.cpp" target="_top">../../example/qi/employee.cpp</a> + </p> +<p> + Let's walk through this one step at a time (not necessarily from top to + bottom). + </p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">employee_parser</span> <span class="special">:</span> <span class="identifier">grammar</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">employee</span><span class="special">(),</span> <span class="identifier">space_type</span><span class="special">></span> +</pre> +<p> + <code class="computeroutput"><span class="identifier">employee_parser</span></code> is a grammar. + Like before, we make it a template so that we can reuse it for different + iterator types. The grammar's signature is: + </p> +<pre class="programlisting"><span class="identifier">employee</span><span class="special">()</span> +</pre> +<p> + meaning, the parser generates employee structs. <code class="computeroutput"><span class="identifier">employee_parser</span></code> + skips white spaces using <code class="computeroutput"><span class="identifier">space_type</span></code> + as its skip parser. + </p> +<pre class="programlisting"><span class="identifier">employee_parser</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">employee_parser</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">start</span><span class="special">)</span> +</pre> +<p> + Initializes the base class. + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">space_type</span><span class="special">></span> <span class="identifier">quoted_string</span><span class="special">;</span> +<span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">employee</span><span class="special">(),</span> <span class="identifier">space_type</span><span class="special">></span> <span class="identifier">start</span><span class="special">;</span> +</pre> +<p> + Declares two rules: <code class="computeroutput"><span class="identifier">quoted_string</span></code> + and <code class="computeroutput"><span class="identifier">start</span></code>. <code class="computeroutput"><span class="identifier">start</span></code> has the same template parameters + as the grammar itself. <code class="computeroutput"><span class="identifier">quoted_string</span></code> + has a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> attribute. + </p> +<h6> +<a name="spirit.qi.tutorials.employee___parsing_into_structs.h0"></a> + <span><a name="spirit.qi.tutorials.employee___parsing_into_structs.lexeme"></a></span><a class="link" href="employee___parsing_into_structs.html#spirit.qi.tutorials.employee___parsing_into_structs.lexeme">Lexeme</a> + </h6> +<pre class="programlisting"><span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">>></span> <span class="char">'"'</span><span class="special">];</span> +</pre> +<p> + <code class="computeroutput"><span class="identifier">lexeme</span></code> inhibits space skipping + from the open brace to the closing brace. The expression parses quoted + strings. + </p> +<pre class="programlisting"><span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> +</pre> +<p> + parses one or more chars, except the double quote. It stops when it sees + a double quote. + </p> +<h6> +<a name="spirit.qi.tutorials.employee___parsing_into_structs.h1"></a> + <span><a name="spirit.qi.tutorials.employee___parsing_into_structs.difference"></a></span><a class="link" href="employee___parsing_into_structs.html#spirit.qi.tutorials.employee___parsing_into_structs.difference">Difference</a> + </h6> +<p> + The expression: + </p> +<pre class="programlisting"><span class="identifier">a</span> <span class="special">-</span> <span class="identifier">b</span> +</pre> +<p> + parses <code class="computeroutput"><span class="identifier">a</span></code> but not <code class="computeroutput"><span class="identifier">b</span></code>. Its attribute is just <code class="computeroutput"><span class="identifier">A</span></code>; the attribute of <code class="computeroutput"><span class="identifier">a</span></code>. + <code class="computeroutput"><span class="identifier">b</span></code>'s attribute is ignored. + Hence, the attribute of: + </p> +<pre class="programlisting"><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span> +</pre> +<p> + is just <code class="computeroutput"><span class="keyword">char</span></code>. + </p> +<h6> +<a name="spirit.qi.tutorials.employee___parsing_into_structs.h2"></a> + <span><a name="spirit.qi.tutorials.employee___parsing_into_structs.plus"></a></span><a class="link" href="employee___parsing_into_structs.html#spirit.qi.tutorials.employee___parsing_into_structs.plus">Plus</a> + </h6> +<pre class="programlisting"><span class="special">+</span><span class="identifier">a</span> +</pre> +<p> + is similar to Kleene star. Rather than match everything, <code class="computeroutput"><span class="special">+</span><span class="identifier">a</span></code> matches + one or more. Like it's related function, the Kleene star, its attribute + is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span></code> + where <code class="computeroutput"><span class="identifier">A</span></code> is the attribute + of <code class="computeroutput"><span class="identifier">a</span></code>. So, putting all these + together, the attribute of + </p> +<pre class="programlisting"><span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> +</pre> +<p> + is then: + </p> +<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> +</pre> +<h6> +<a name="spirit.qi.tutorials.employee___parsing_into_structs.h3"></a> + <span><a name="spirit.qi.tutorials.employee___parsing_into_structs.sequence_attribute"></a></span><a class="link" href="employee___parsing_into_structs.html#spirit.qi.tutorials.employee___parsing_into_structs.sequence_attribute">Sequence + Attribute</a> + </h6> +<p> + Now what's the attribute of + </p> +<pre class="programlisting"><span class="char">'"'</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">>></span> <span class="char">'"'</span> +</pre> +<p> + ? + </p> +<p> + Well, typically, the attribute of: + </p> +<pre class="programlisting"><span class="identifier">a</span> <span class="special">>></span> <span class="identifier">b</span> <span class="special">>></span> <span class="identifier">c</span> +</pre> +<p> + is: + </p> +<pre class="programlisting"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">,</span> <span class="identifier">C</span><span class="special">></span> +</pre> +<p> + where <code class="computeroutput"><span class="identifier">A</span></code> is the attribute + of <code class="computeroutput"><span class="identifier">a</span></code>, <code class="computeroutput"><span class="identifier">B</span></code> + is the attribute of <code class="computeroutput"><span class="identifier">b</span></code> and + <code class="computeroutput"><span class="identifier">C</span></code> is the attribute of + <code class="computeroutput"><span class="identifier">c</span></code>. What is <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span></code>? - a tuple. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + If you don't know what I am talking about, see: <a href="http://tinyurl.com/6xun4j" target="_top">Fusion + Vector</a>. It might be a good idea to have a look into <a href="../../../../../../../libs/fusion/doc/html/index.html" target="_top">Boost.Fusion</a> + at this point. You'll definitely see more of it in the coming pages. + </p></td></tr> +</table></div> +<h6> +<a name="spirit.qi.tutorials.employee___parsing_into_structs.h4"></a> + <span><a name="spirit.qi.tutorials.employee___parsing_into_structs.attribute_collapsing"></a></span><a class="link" href="employee___parsing_into_structs.html#spirit.qi.tutorials.employee___parsing_into_structs.attribute_collapsing">Attribute + Collapsing</a> + </h6> +<p> + Some parsers, especially those very little literal parsers you see, like + <code class="computeroutput"><span class="char">'"'</span></code>, do not have attributes. + </p> +<p> + Nodes without attributes are disregarded. In a sequence, like above, all + nodes with no attributes are filtered out of the <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span></code>. + So, since <code class="computeroutput"><span class="char">'"'</span></code> has no attribute, + and <code class="computeroutput"><span class="special">+(</span><span class="identifier">char_</span> + <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span></code> has a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span></code> attribute, the whole expression's attribute + should have been: + </p> +<pre class="programlisting"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> <span class="special">></span> +</pre> +<p> + But wait, there's one more collapsing rule: If the attribute is followed + by a single element <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span></code>, + The element is stripped naked from its container. To make a long story + short, the attribute of the expression: + </p> +<pre class="programlisting"><span class="char">'"'</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">>></span> <span class="char">'"'</span> +</pre> +<p> + is: + </p> +<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> +</pre> +<h6> +<a name="spirit.qi.tutorials.employee___parsing_into_structs.h5"></a> + <span><a name="spirit.qi.tutorials.employee___parsing_into_structs.auto_rules"></a></span><a class="link" href="employee___parsing_into_structs.html#spirit.qi.tutorials.employee___parsing_into_structs.auto_rules">Auto + Rules</a> + </h6> +<p> + It is typical to see rules like: + </p> +<pre class="programlisting"><span class="identifier">r</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">[</span><span class="identifier">_val</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">];</span> +</pre> +<p> + If you have a rule definition such as the above, where the attribute of + the RHS (right hand side) of the rule is compatible with the attribute + of the LHS (left hand side), then you can rewrite it as: + </p> +<pre class="programlisting"><span class="identifier">r</span> <span class="special">%=</span> <span class="identifier">p</span><span class="special">;</span> +</pre> +<p> + The attribute of <code class="computeroutput"><span class="identifier">p</span></code> automatically + uses the attribute of <code class="computeroutput"><span class="identifier">r</span></code>. + </p> +<p> + So, going back to our <code class="computeroutput"><span class="identifier">quoted_string</span></code> + rule: + </p> +<pre class="programlisting"><span class="identifier">quoted_string</span> <span class="special">%=</span> <span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">>></span> <span class="char">'"'</span><span class="special">];</span> +</pre> +<p> + is a simplified version of: + </p> +<pre class="programlisting"><span class="identifier">quoted_string</span> <span class="special">=</span> <span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">>></span> <span class="char">'"'</span><span class="special">][</span><span class="identifier">_val</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">];</span> +</pre> +<p> + The attribute of the <code class="computeroutput"><span class="identifier">quoted_string</span></code> + rule: <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> <span class="bold"><strong>is compatible</strong></span> + with the attribute of the RHS: <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span></code>. The RHS extracts the parsed attribute + directly into the rule's attribute, in-situ. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + <code class="computeroutput"><span class="identifier">r</span> <span class="special">%=</span> + <span class="identifier">p</span></code> and <code class="computeroutput"><span class="identifier">r</span> + <span class="special">=</span> <span class="identifier">p</span></code> + are equivalent if there are no semantic actions associated with <code class="computeroutput"><span class="identifier">p</span></code>. + </p></td></tr> +</table></div> +<h6> +<a name="spirit.qi.tutorials.employee___parsing_into_structs.h6"></a> + <span><a name="spirit.qi.tutorials.employee___parsing_into_structs.finally"></a></span><a class="link" href="employee___parsing_into_structs.html#spirit.qi.tutorials.employee___parsing_into_structs.finally">Finally</a> + </h6> +<p> + We're down to one rule, the start rule: + </p> +<pre class="programlisting"><span class="identifier">start</span> <span class="special">%=</span> + <span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span> + <span class="special">>></span> <span class="char">'{'</span> + <span class="special">>></span> <span class="identifier">int_</span> <span class="special">>></span> <span class="char">','</span> + <span class="special">>></span> <span class="identifier">quoted_string</span> <span class="special">>></span> <span class="char">','</span> + <span class="special">>></span> <span class="identifier">quoted_string</span> <span class="special">>></span> <span class="char">','</span> + <span class="special">>></span> <span class="identifier">double_</span> + <span class="special">>></span> <span class="char">'}'</span> + <span class="special">;</span> +</pre> +<p> + Applying our collapsing rules above, the RHS has an attribute of: + </p> +<pre class="programlisting"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">></span> +</pre> +<p> + These nodes do not have an attribute: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span></code> + </li> +<li class="listitem"> + <code class="computeroutput"><span class="char">'{'</span></code> + </li> +<li class="listitem"> + <code class="computeroutput"><span class="char">','</span></code> + </li> +<li class="listitem"> + <code class="computeroutput"><span class="char">'}'</span></code> + </li> +</ul></div> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + In case you are wondering, <code class="computeroutput"><span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span></code> is the same as "employee". + We had to wrap it inside <code class="computeroutput"><span class="identifier">lit</span></code> + because immediately after it is <code class="computeroutput"><span class="special">>></span> + <span class="char">'{'</span></code>. You can't right-shift a <code class="computeroutput"><span class="keyword">char</span><span class="special">[]</span></code> + and a <code class="computeroutput"><span class="keyword">char</span></code> - you know, C++ + syntax rules. + </p></td></tr> +</table></div> +<p> + Recall that the attribute of <code class="computeroutput"><span class="identifier">start</span></code> + is the <code class="computeroutput"><span class="identifier">employee</span></code> struct: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">employee</span> +<span class="special">{</span> + <span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">surname</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">forename</span><span class="special">;</span> + <span class="keyword">double</span> <span class="identifier">salary</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + Now everything is clear, right? The <code class="computeroutput"><span class="keyword">struct</span> + <span class="identifier">employee</span></code> <span class="bold"><strong>IS</strong></span> + compatible with <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">></span></code>. So, the RHS of <code class="computeroutput"><span class="identifier">start</span></code> + uses start's attribute (a <code class="computeroutput"><span class="keyword">struct</span> + <span class="identifier">employee</span></code>) in-situ when it does + its work. + </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-2011 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="roman_numerals.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="mini_xml___asts_.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/mini_xml___asts_.html b/libs/spirit/doc/html/spirit/qi/tutorials/mini_xml___asts_.html new file mode 100755 index 0000000000..9e592f075b --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/mini_xml___asts_.html @@ -0,0 +1,501 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Mini XML - ASTs!</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="employee___parsing_into_structs.html" title="Employee - Parsing into structs"> +<link rel="next" href="mini_xml___error_handling.html" title="Mini XML - Error Handling"> +</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="employee___parsing_into_structs.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="mini_xml___error_handling.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.qi.tutorials.mini_xml___asts_"></a><a class="link" href="mini_xml___asts_.html" title="Mini XML - ASTs!">Mini XML - ASTs!</a> +</h4></div></div></div> +<p> + Stop and think about it... We've come very close to generating an AST (abstract + syntax tree) in our last example. We parsed a single structure and generated + an in-memory representation of it in the form of a struct: the <code class="computeroutput"><span class="keyword">struct</span> <span class="identifier">employee</span></code>. + If we changed the implementation to parse one or more employees, the result + would be a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">employee</span><span class="special">></span></code>. + We can go on and add more hierarchy: teams, departments, corporations. + Then we'll have an AST representation of it all. + </p> +<p> + In this example (actually two examples), we'll now explore how to create + ASTs. We will parse a minimalistic XML-like language and compile the results + into our data structures in the form of a tree. + </p> +<p> + Along the way, we'll see new features: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + Inherited attributes + </li> +<li class="listitem"> + Variant attributes + </li> +<li class="listitem"> + Local Variables + </li> +<li class="listitem"> + Not Predicate + </li> +<li class="listitem"> + Lazy Lit + </li> +</ul></div> +<p> + The full cpp files for these examples can be found here: <a href="../../../../../example/qi/mini_xml1.cpp" target="_top">../../example/qi/mini_xml1.cpp</a> + and here: <a href="../../../../../example/qi/mini_xml2.cpp" target="_top">../../example/qi/mini_xml2.cpp</a> + </p> +<p> + There are a couple of sample toy-xml files in the mini_xml_samples subdirectory: + <a href="../../../../../example/qi/mini_xml_samples/1.toyxml" target="_top">../../example/qi/mini_xml_samples/1.toyxml</a>, + <a href="../../../../../example/qi/mini_xml_samples/2.toyxml" target="_top">../../example/qi/mini_xml_samples/2.toyxml</a>, + and <a href="../../../../../example/qi/mini_xml_samples/3.toyxml" target="_top">../../example/qi/mini_xml_samples/3.toyxml</a> + for testing purposes. The example <a href="../../../../../example/qi/mini_xml_samples/4.toyxml" target="_top">../../example/qi/mini_xml_samples/4.toyxml</a> + has an error in it. + </p> +<h6> +<a name="spirit.qi.tutorials.mini_xml___asts_.h0"></a> + <span><a name="spirit.qi.tutorials.mini_xml___asts_.first_cut"></a></span><a class="link" href="mini_xml___asts_.html#spirit.qi.tutorials.mini_xml___asts_.first_cut">First + Cut</a> + </h6> +<p> + Without further delay, here's the first version of the XML grammar: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">mini_xml_grammar</span> <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">grammar</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">mini_xml_grammar</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">mini_xml_grammar</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">xml</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">string</span><span class="special">;</span> + <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">labels</span><span class="special">;</span> + + <span class="keyword">using</span> <span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">at_c</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">push_back</span><span class="special">;</span> + + <span class="identifier">text</span> <span class="special">=</span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'<'</span><span class="special">)</span> <span class="special">[</span><span class="identifier">_val</span> <span class="special">+=</span> <span class="identifier">_1</span><span class="special">]];</span> + <span class="identifier">node</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">xml</span> <span class="special">|</span> <span class="identifier">text</span><span class="special">)</span> <span class="special">[</span><span class="identifier">_val</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">];</span> + + <span class="identifier">start_tag</span> <span class="special">=</span> + <span class="char">'<'</span> + <span class="special">>></span> <span class="special">!</span><span class="identifier">lit</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span> + <span class="special">>></span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'>'</span><span class="special">)</span> <span class="special">[</span><span class="identifier">_val</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> + + <span class="identifier">end_tag</span> <span class="special">=</span> + <span class="string">"</"</span> + <span class="special">>></span> <span class="identifier">string</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span> + <span class="special">>></span> <span class="char">'>'</span> + <span class="special">;</span> + + <span class="identifier">xml</span> <span class="special">=</span> + <span class="identifier">start_tag</span> <span class="special">[</span><span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">>></span> <span class="special">*</span><span class="identifier">node</span> <span class="special">[</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">at_c</span><span class="special"><</span><span class="number">1</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">),</span> <span class="identifier">_1</span><span class="special">)]</span> + <span class="special">>></span> <span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">))</span> + <span class="special">;</span> + <span class="special">}</span> + + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">xml</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml_node</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">node</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">text</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">start_tag</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">end_tag</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + Going bottom up, let's examine the <code class="computeroutput"><span class="identifier">text</span></code> + rule: + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">space_type</span><span class="special">></span> <span class="identifier">text</span><span class="special">;</span> +</pre> +<p> + and its definition: + </p> +<pre class="programlisting"><span class="identifier">text</span> <span class="special">=</span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'<'</span><span class="special">)</span> <span class="special">[</span><span class="identifier">_val</span> <span class="special">+=</span> <span class="identifier">_1</span><span class="special">]];</span> +</pre> +<p> + The semantic action collects the chars and appends them (via +=) to the + <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> attribute of the rule (represented + by the placeholder <code class="computeroutput"><span class="identifier">_val</span></code>). + </p> +<h6> +<a name="spirit.qi.tutorials.mini_xml___asts_.h1"></a> + <span><a name="spirit.qi.tutorials.mini_xml___asts_.alternates"></a></span><a class="link" href="mini_xml___asts_.html#spirit.qi.tutorials.mini_xml___asts_.alternates">Alternates</a> + </h6> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml_node</span><span class="special">(),</span> <span class="identifier">space_type</span><span class="special">></span> <span class="identifier">node</span><span class="special">;</span> +</pre> +<p> + and its definition: + </p> +<pre class="programlisting"><span class="identifier">node</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">xml</span> <span class="special">|</span> <span class="identifier">text</span><span class="special">)</span> <span class="special">[</span><span class="identifier">_val</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">];</span> +</pre> +<p> + We'll see a <code class="computeroutput"><span class="identifier">mini_xml_node</span></code> + structure later. Looking at the rule definition, we see some alternation + going on here. An xml <code class="computeroutput"><span class="identifier">node</span></code> + is either an <code class="computeroutput"><span class="identifier">xml</span></code> OR <code class="computeroutput"><span class="identifier">text</span></code>. Hmmm... hold on to that thought... + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">space_type</span><span class="special">></span> <span class="identifier">start_tag</span><span class="special">;</span> +</pre> +<p> + Again, with an attribute of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>. + Then, it's definition: + </p> +<pre class="programlisting"><span class="identifier">start_tag</span> <span class="special">=</span> + <span class="char">'<'</span> + <span class="special">>></span> <span class="special">!</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span> + <span class="special">>></span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'>'</span><span class="special">)</span> <span class="special">[</span><span class="identifier">_val</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> +<h6> +<a name="spirit.qi.tutorials.mini_xml___asts_.h2"></a> + <span><a name="spirit.qi.tutorials.mini_xml___asts_.not_predicate"></a></span><a class="link" href="mini_xml___asts_.html#spirit.qi.tutorials.mini_xml___asts_.not_predicate">Not Predicate</a> + </h6> +<p> + <code class="computeroutput"><span class="identifier">start_tag</span></code> is similar to + the <code class="computeroutput"><span class="identifier">text</span></code> rule apart from + the added <code class="computeroutput"><span class="char">'<'</span></code> and <code class="computeroutput"><span class="char">'>'</span></code>. But wait, to make sure that the <code class="computeroutput"><span class="identifier">start_tag</span></code> does not parse <code class="computeroutput"><span class="identifier">end_tag</span></code>s too, we add: <code class="computeroutput"><span class="special">!</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span></code>. This + is a "Not Predicate": + </p> +<pre class="programlisting"><span class="special">!</span><span class="identifier">p</span> +</pre> +<p> + It will try the parser, <code class="computeroutput"><span class="identifier">p</span></code>. + If it is successful, fail; otherwise, pass. In other words, it negates + the result of <code class="computeroutput"><span class="identifier">p</span></code>. Like the + <code class="computeroutput"><span class="identifier">eps</span></code>, it does not consume + any input though. It will always rewind the iterator position to where + it was upon entry. So, the expression: + </p> +<pre class="programlisting"><span class="special">!</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span> +</pre> +<p> + basically says: we should not have a <code class="computeroutput"><span class="char">'/'</span></code> + at this point. + </p> +<h6> +<a name="spirit.qi.tutorials.mini_xml___asts_.h3"></a> + <span><a name="spirit.qi.tutorials.mini_xml___asts_.inherited_attribute"></a></span><a class="link" href="mini_xml___asts_.html#spirit.qi.tutorials.mini_xml___asts_.inherited_attribute">Inherited + Attribute</a> + </h6> +<p> + The <code class="computeroutput"><span class="identifier">end_tag</span></code>: + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">),</span> <span class="identifier">space_type</span><span class="special">></span> <span class="identifier">end_tag</span><span class="special">;</span> +</pre> +<p> + Ohh! Now we see an inherited attribute there: <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>. + The <code class="computeroutput"><span class="identifier">end_tag</span></code> does not have + a synthesized attribute. Let's see its definition: + </p> +<pre class="programlisting"><span class="identifier">end_tag</span> <span class="special">=</span> + <span class="string">"</"</span> + <span class="special">>></span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span> + <span class="special">>></span> <span class="char">'>'</span> +<span class="special">;</span> +</pre> +<p> + <code class="computeroutput"><span class="identifier">_r1</span></code> is yet another <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a> placeholder for + the first inherited attribute (we have only one, use <code class="computeroutput"><span class="identifier">_r2</span></code>, + <code class="computeroutput"><span class="identifier">_r3</span></code>, etc. if you have more). + </p> +<h6> +<a name="spirit.qi.tutorials.mini_xml___asts_.h4"></a> + <span><a name="spirit.qi.tutorials.mini_xml___asts_.a_lazy_lit"></a></span><a class="link" href="mini_xml___asts_.html#spirit.qi.tutorials.mini_xml___asts_.a_lazy_lit">A + Lazy Lit</a> + </h6> +<p> + Check out how we used <code class="computeroutput"><span class="identifier">lit</span></code> + here, this time, not with a literal string, but with the value of the first + inherited attribute, which is specified as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> + in our rule declaration. + </p> +<p> + Finally, our <code class="computeroutput"><span class="identifier">xml</span></code> rule: + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">space_type</span><span class="special">></span> <span class="identifier">xml</span><span class="special">;</span> +</pre> +<p> + <code class="computeroutput"><span class="identifier">mini_xml</span></code> is our attribute + here. We'll see later what it is. Let's see its definition: + </p> +<pre class="programlisting"><span class="identifier">xml</span> <span class="special">=</span> + <span class="identifier">start_tag</span> <span class="special">[</span><span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">>></span> <span class="special">*</span><span class="identifier">node</span> <span class="special">[</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">at_c</span><span class="special"><</span><span class="number">1</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">),</span> <span class="identifier">_1</span><span class="special">)]</span> + <span class="special">>></span> <span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">))</span> +<span class="special">;</span> +</pre> +<p> + Those who know <a href="../../../../../../../libs/fusion/doc/html/index.html" target="_top">Boost.Fusion</a> + now will notice <code class="computeroutput"><span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">></span></code> and + <code class="computeroutput"><span class="identifier">at_c</span><span class="special"><</span><span class="number">1</span><span class="special">></span></code>. This + gives us a hint that <code class="computeroutput"><span class="identifier">mini_xml</span></code> + is a sort of a tuple - a fusion sequence. <code class="computeroutput"><span class="identifier">at_c</span><span class="special"><</span><span class="identifier">N</span><span class="special">></span></code> here is a lazy version of the tuple + accessors, provided by <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a>. + </p> +<h6> +<a name="spirit.qi.tutorials.mini_xml___asts_.h5"></a> + <span><a name="spirit.qi.tutorials.mini_xml___asts_.how_it_all_works"></a></span><a class="link" href="mini_xml___asts_.html#spirit.qi.tutorials.mini_xml___asts_.how_it_all_works">How it + all works</a> + </h6> +<p> + So, what's happening? + </p> +<div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + Upon parsing <code class="computeroutput"><span class="identifier">start_tag</span></code>, + the parsed start-tag string is placed in <code class="computeroutput"><span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)</span></code>. + </li> +<li class="listitem"> + Then we parse zero or more <code class="computeroutput"><span class="identifier">node</span></code>s. + At each step, we <code class="computeroutput"><span class="identifier">push_back</span></code> + the result into <code class="computeroutput"><span class="identifier">at_c</span><span class="special"><</span><span class="number">1</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)</span></code>. + </li> +<li class="listitem"> + Finally, we parse the <code class="computeroutput"><span class="identifier">end_tag</span></code> + giving it an inherited attribute: <code class="computeroutput"><span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)</span></code>. This is the string we obtained from + the <code class="computeroutput"><span class="identifier">start_tag</span></code>. Investigate + <code class="computeroutput"><span class="identifier">end_tag</span></code> above. It will + fail to parse if it gets something different from what we got from + the <code class="computeroutput"><span class="identifier">start_tag</span></code>. This + ensures that our tags are balanced. + </li> +</ol></div> +<p> + To give the last item some more light, what happens is this: + </p> +<pre class="programlisting"><span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">))</span> +</pre> +<p> + calls: + </p> +<pre class="programlisting"><span class="identifier">end_tag</span> <span class="special">=</span> + <span class="string">"</"</span> + <span class="special">>></span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span> + <span class="special">>></span> <span class="char">'>'</span> +<span class="special">;</span> +</pre> +<p> + passing in <code class="computeroutput"><span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)</span></code>, the string from start tag. This is referred + to in the <code class="computeroutput"><span class="identifier">end_tag</span></code> body + as <code class="computeroutput"><span class="identifier">_r1</span></code>. + </p> +<h6> +<a name="spirit.qi.tutorials.mini_xml___asts_.h6"></a> + <span><a name="spirit.qi.tutorials.mini_xml___asts_.the_structures"></a></span><a class="link" href="mini_xml___asts_.html#spirit.qi.tutorials.mini_xml___asts_.the_structures">The Structures</a> + </h6> +<p> + Let's see our structures. It will definitely be hierarchical: xml is hierarchical. + It will also be recursive: xml is recursive. + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">mini_xml</span><span class="special">;</span> + +<span class="keyword">typedef</span> + <span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special"><</span> + <span class="identifier">boost</span><span class="special">::</span><span class="identifier">recursive_wrapper</span><span class="special"><</span><span class="identifier">mini_xml</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> + <span class="special">></span> +<span class="identifier">mini_xml_node</span><span class="special">;</span> + +<span class="keyword">struct</span> <span class="identifier">mini_xml</span> +<span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">;</span> <span class="comment">// tag name</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">mini_xml_node</span><span class="special">></span> <span class="identifier">children</span><span class="special">;</span> <span class="comment">// children</span> +<span class="special">};</span> +</pre> +<p> + </p> +<h6> +<a name="spirit.qi.tutorials.mini_xml___asts_.h7"></a> + <span><a name="spirit.qi.tutorials.mini_xml___asts_.of_alternates_and_variants"></a></span><a class="link" href="mini_xml___asts_.html#spirit.qi.tutorials.mini_xml___asts_.of_alternates_and_variants">Of + Alternates and Variants</a> + </h6> +<p> + So that's what a <code class="computeroutput"><span class="identifier">mini_xml_node</span></code> + looks like. We had a hint that it is either a <code class="computeroutput"><span class="identifier">string</span></code> + or a <code class="computeroutput"><span class="identifier">mini_xml</span></code>. For this, + we use <a href="http://www.boost.org/doc/html/variant.html" target="_top">Boost.Variant</a>. + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">recursive_wrapper</span></code> wraps <code class="computeroutput"><span class="identifier">mini_xml</span></code>, making it a recursive data + structure. + </p> +<p> + Yep, you got that right: the attribute of an alternate: + </p> +<pre class="programlisting"><span class="identifier">a</span> <span class="special">|</span> <span class="identifier">b</span> +</pre> +<p> + is a + </p> +<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">></span> +</pre> +<p> + where <code class="computeroutput"><span class="identifier">A</span></code> is the attribute + of <code class="computeroutput"><span class="identifier">a</span></code> and <code class="computeroutput"><span class="identifier">B</span></code> is the attribute of <code class="computeroutput"><span class="identifier">b</span></code>. + </p> +<h6> +<a name="spirit.qi.tutorials.mini_xml___asts_.h8"></a> + <span><a name="spirit.qi.tutorials.mini_xml___asts_.adapting_structs_again"></a></span><a class="link" href="mini_xml___asts_.html#spirit.qi.tutorials.mini_xml___asts_.adapting_structs_again">Adapting + structs again</a> + </h6> +<p> + <code class="computeroutput"><span class="identifier">mini_xml</span></code> is no brainier. + It is a plain ol' struct. But as we've seen in our employee example, we + can adapt that to be a <a href="../../../../../../../libs/fusion/doc/html/index.html" target="_top">Boost.Fusion</a> + sequence: + </p> +<p> +</p> +<pre class="programlisting"><span class="identifier">BOOST_FUSION_ADAPT_STRUCT</span><span class="special">(</span> + <span class="identifier">client</span><span class="special">::</span><span class="identifier">mini_xml</span><span class="special">,</span> + <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">name</span><span class="special">)</span> + <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">client</span><span class="special">::</span><span class="identifier">mini_xml_node</span><span class="special">>,</span> <span class="identifier">children</span><span class="special">)</span> +<span class="special">)</span> +</pre> +<p> + </p> +<h6> +<a name="spirit.qi.tutorials.mini_xml___asts_.h9"></a> + <span><a name="spirit.qi.tutorials.mini_xml___asts_.one_more_take"></a></span><a class="link" href="mini_xml___asts_.html#spirit.qi.tutorials.mini_xml___asts_.one_more_take">One More Take</a> + </h6> +<p> + Here's another version. The AST structure remains the same, but this time, + you'll see that we make use of auto-rules making the grammar semantic-action-less. + Here it is: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">mini_xml_grammar</span> + <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">grammar</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">locals</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>,</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">mini_xml_grammar</span><span class="special">()</span> + <span class="special">:</span> <span class="identifier">mini_xml_grammar</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">xml</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">string</span><span class="special">;</span> + <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">labels</span><span class="special">;</span> + + <span class="identifier">text</span> <span class="special">%=</span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'<'</span><span class="special">)];</span> + <span class="identifier">node</span> <span class="special">%=</span> <span class="identifier">xml</span> <span class="special">|</span> <span class="identifier">text</span><span class="special">;</span> + + <span class="identifier">start_tag</span> <span class="special">%=</span> + <span class="char">'<'</span> + <span class="special">>></span> <span class="special">!</span><span class="identifier">lit</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span> + <span class="special">>></span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'>'</span><span class="special">)]</span> + <span class="special">>></span> <span class="char">'>'</span> + <span class="special">;</span> + + <span class="identifier">end_tag</span> <span class="special">=</span> + <span class="string">"</"</span> + <span class="special">>></span> <span class="identifier">string</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span> + <span class="special">>></span> <span class="char">'>'</span> + <span class="special">;</span> + + <span class="identifier">xml</span> <span class="special">%=</span> + <span class="identifier">start_tag</span><span class="special">[</span><span class="identifier">_a</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">>></span> <span class="special">*</span><span class="identifier">node</span> + <span class="special">>></span> <span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">_a</span><span class="special">)</span> + <span class="special">;</span> + <span class="special">}</span> + + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">locals</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>,</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">xml</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml_node</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">node</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">text</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">start_tag</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">end_tag</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + This one shouldn't be any more difficult to understand after going through + the first xml parser example. The rules are almost the same, except that, + we got rid of semantic actions and used auto-rules (see the employee example + if you missed that). There is some new stuff though. It's all in the <code class="computeroutput"><span class="identifier">xml</span></code> rule: + </p> +<h6> +<a name="spirit.qi.tutorials.mini_xml___asts_.h10"></a> + <span><a name="spirit.qi.tutorials.mini_xml___asts_.local_variables"></a></span><a class="link" href="mini_xml___asts_.html#spirit.qi.tutorials.mini_xml___asts_.local_variables">Local Variables</a> + </h6> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">locals</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>,</span> <span class="identifier">space_type</span><span class="special">></span> <span class="identifier">xml</span><span class="special">;</span> +</pre> +<p> + Wow, we have four template parameters now. What's that <code class="computeroutput"><span class="identifier">locals</span></code> + guy doing there? Well, it declares that the rule <code class="computeroutput"><span class="identifier">xml</span></code> + will have one local variable: a <code class="computeroutput"><span class="identifier">string</span></code>. + Let's see how this is used in action: + </p> +<pre class="programlisting"><span class="identifier">xml</span> <span class="special">%=</span> + <span class="identifier">start_tag</span><span class="special">[</span><span class="identifier">_a</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">>></span> <span class="special">*</span><span class="identifier">node</span> + <span class="special">>></span> <span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">_a</span><span class="special">)</span> +<span class="special">;</span> +</pre> +<div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + Upon parsing <code class="computeroutput"><span class="identifier">start_tag</span></code>, + the parsed start-tag string is placed in the local variable specified + by (yet another) <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a> + placeholder: <code class="computeroutput"><span class="identifier">_a</span></code>. We + have only one local variable. If we had more, these are designated + by <code class="computeroutput"><span class="identifier">_b</span></code>..<code class="computeroutput"><span class="identifier">_z</span></code>. + </li> +<li class="listitem"> + Then we parse zero or more <code class="computeroutput"><span class="identifier">node</span></code>s. + </li> +<li class="listitem"> + Finally, we parse the <code class="computeroutput"><span class="identifier">end_tag</span></code> + giving it an inherited attribute: <code class="computeroutput"><span class="identifier">_a</span></code>, + our local variable. + </li> +</ol></div> +<p> + There are no actions involved in stuffing data into our <code class="computeroutput"><span class="identifier">xml</span></code> + attribute. It's all taken care of thanks to the auto-rule. + </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-2011 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="employee___parsing_into_structs.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="mini_xml___error_handling.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/mini_xml___error_handling.html b/libs/spirit/doc/html/spirit/qi/tutorials/mini_xml___error_handling.html new file mode 100755 index 0000000000..1938949cfd --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/mini_xml___error_handling.html @@ -0,0 +1,366 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Mini XML - Error Handling</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="mini_xml___asts_.html" title="Mini XML - ASTs!"> +<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"><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="mini_xml___asts_.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="../quick_reference.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.qi.tutorials.mini_xml___error_handling"></a><a class="link" href="mini_xml___error_handling.html" title="Mini XML - Error Handling">Mini + XML - Error Handling</a> +</h4></div></div></div> +<p> + A parser will not be complete without error handling. Spirit2 provides + some facilities to make it easy to adapt a grammar for error handling. + We'll wrap up the Qi tutorial with another version of the mini xml parser, + this time, with error handling. + </p> +<p> + The full cpp file for this example can be found here: <a href="../../../../../example/qi/mini_xml3.cpp" target="_top">../../example/qi/mini_xml3.cpp</a> + </p> +<p> + Here's the grammar: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">mini_xml_grammar</span> + <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">grammar</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">locals</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>,</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">mini_xml_grammar</span><span class="special">()</span> + <span class="special">:</span> <span class="identifier">mini_xml_grammar</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">xml</span><span class="special">,</span> <span class="string">"xml"</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">on_error</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">fail</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">string</span><span class="special">;</span> + <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">labels</span><span class="special">;</span> + + <span class="keyword">using</span> <span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">construct</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">val</span><span class="special">;</span> + + <span class="identifier">text</span> <span class="special">%=</span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'<'</span><span class="special">)];</span> + <span class="identifier">node</span> <span class="special">%=</span> <span class="identifier">xml</span> <span class="special">|</span> <span class="identifier">text</span><span class="special">;</span> + + <span class="identifier">start_tag</span> <span class="special">%=</span> + <span class="char">'<'</span> + <span class="special">>></span> <span class="special">!</span><span class="identifier">lit</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span> + <span class="special">></span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'>'</span><span class="special">)]</span> + <span class="special">></span> <span class="char">'>'</span> + <span class="special">;</span> + + <span class="identifier">end_tag</span> <span class="special">=</span> + <span class="string">"</"</span> + <span class="special">></span> <span class="identifier">string</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span> + <span class="special">></span> <span class="char">'>'</span> + <span class="special">;</span> + + <span class="identifier">xml</span> <span class="special">%=</span> + <span class="identifier">start_tag</span><span class="special">[</span><span class="identifier">_a</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">></span> <span class="special">*</span><span class="identifier">node</span> + <span class="special">></span> <span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">_a</span><span class="special">)</span> + <span class="special">;</span> + + <span class="identifier">xml</span><span class="special">.</span><span class="identifier">name</span><span class="special">(</span><span class="string">"xml"</span><span class="special">);</span> + <span class="identifier">node</span><span class="special">.</span><span class="identifier">name</span><span class="special">(</span><span class="string">"node"</span><span class="special">);</span> + <span class="identifier">text</span><span class="special">.</span><span class="identifier">name</span><span class="special">(</span><span class="string">"text"</span><span class="special">);</span> + <span class="identifier">start_tag</span><span class="special">.</span><span class="identifier">name</span><span class="special">(</span><span class="string">"start_tag"</span><span class="special">);</span> + <span class="identifier">end_tag</span><span class="special">.</span><span class="identifier">name</span><span class="special">(</span><span class="string">"end_tag"</span><span class="special">);</span> + + <span class="identifier">on_error</span><span class="special"><</span><span class="identifier">fail</span><span class="special">></span> + <span class="special">(</span> + <span class="identifier">xml</span> + <span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> + <span class="special"><<</span> <span class="identifier">val</span><span class="special">(</span><span class="string">"Error! Expecting "</span><span class="special">)</span> + <span class="special"><<</span> <span class="identifier">_4</span> <span class="comment">// what failed?</span> + <span class="special"><<</span> <span class="identifier">val</span><span class="special">(</span><span class="string">" here: \""</span><span class="special">)</span> + <span class="special"><<</span> <span class="identifier">construct</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>(</span><span class="identifier">_3</span><span class="special">,</span> <span class="identifier">_2</span><span class="special">)</span> <span class="comment">// iterators to error-pos, end</span> + <span class="special"><<</span> <span class="identifier">val</span><span class="special">(</span><span class="string">"\""</span><span class="special">)</span> + <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span> + <span class="special">);</span> + <span class="special">}</span> + + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">locals</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>,</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">xml</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml_node</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">node</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">text</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">start_tag</span><span class="special">;</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">end_tag</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + What's new? + </p> +<h6> +<a name="spirit.qi.tutorials.mini_xml___error_handling.h0"></a> + <span><a name="spirit.qi.tutorials.mini_xml___error_handling.readable_names"></a></span><a class="link" href="mini_xml___error_handling.html#spirit.qi.tutorials.mini_xml___error_handling.readable_names">Readable + Names</a> + </h6> +<p> + First, when we call the base class, we give the grammar a name: + </p> +<pre class="programlisting"><span class="special">:</span> <span class="identifier">mini_xml_grammar</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">xml</span><span class="special">,</span> <span class="string">"xml"</span><span class="special">)</span> +</pre> +<p> + Then, we name all our rules: + </p> +<pre class="programlisting"><span class="identifier">xml</span><span class="special">.</span><span class="identifier">name</span><span class="special">(</span><span class="string">"xml"</span><span class="special">);</span> +<span class="identifier">node</span><span class="special">.</span><span class="identifier">name</span><span class="special">(</span><span class="string">"node"</span><span class="special">);</span> +<span class="identifier">text</span><span class="special">.</span><span class="identifier">name</span><span class="special">(</span><span class="string">"text"</span><span class="special">);</span> +<span class="identifier">start_tag</span><span class="special">.</span><span class="identifier">name</span><span class="special">(</span><span class="string">"start_tag"</span><span class="special">);</span> +<span class="identifier">end_tag</span><span class="special">.</span><span class="identifier">name</span><span class="special">(</span><span class="string">"end_tag"</span><span class="special">);</span> +</pre> +<h6> +<a name="spirit.qi.tutorials.mini_xml___error_handling.h1"></a> + <span><a name="spirit.qi.tutorials.mini_xml___error_handling.on_error"></a></span><a class="link" href="mini_xml___error_handling.html#spirit.qi.tutorials.mini_xml___error_handling.on_error">On Error</a> + </h6> +<p> + <code class="computeroutput"><span class="identifier">on_error</span></code> declares our error + handler: + </p> +<pre class="programlisting"><span class="identifier">on_error</span><span class="special"><</span><span class="identifier">Action</span><span class="special">>(</span><span class="identifier">rule</span><span class="special">,</span> <span class="identifier">handler</span><span class="special">)</span> +</pre> +<p> + This will specify what we will do when we get an error. We will print out + an error message using phoenix: + </p> +<pre class="programlisting"><span class="identifier">on_error</span><span class="special"><</span><span class="identifier">fail</span><span class="special">></span> +<span class="special">(</span> + <span class="identifier">xml</span> + <span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> + <span class="special"><<</span> <span class="identifier">val</span><span class="special">(</span><span class="string">"Error! Expecting "</span><span class="special">)</span> + <span class="special"><<</span> <span class="identifier">_4</span> <span class="comment">// what failed?</span> + <span class="special"><<</span> <span class="identifier">val</span><span class="special">(</span><span class="string">" here: \""</span><span class="special">)</span> + <span class="special"><<</span> <span class="identifier">construct</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>(</span><span class="identifier">_3</span><span class="special">,</span> <span class="identifier">_2</span><span class="special">)</span> <span class="comment">// iterators to error-pos, end</span> + <span class="special"><<</span> <span class="identifier">val</span><span class="special">(</span><span class="string">"\""</span><span class="special">)</span> + <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span> +<span class="special">);</span> +</pre> +<p> + we choose to <code class="computeroutput"><span class="identifier">fail</span></code> in our + example for the <code class="computeroutput"><span class="identifier">Action</span></code>: + Quit and fail. Return a no_match (false). It can be one of: + </p> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + <code class="computeroutput"><span class="identifier">Action</span></code> + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + fail + </p> + </td> +<td> + <p> + Quit and fail. Return a no_match. + </p> + </td> +</tr> +<tr> +<td> + <p> + retry + </p> + </td> +<td> + <p> + Attempt error recovery, possibly moving the iterator position. + </p> + </td> +</tr> +<tr> +<td> + <p> + accept + </p> + </td> +<td> + <p> + Force success, moving the iterator position appropriately. + </p> + </td> +</tr> +<tr> +<td> + <p> + rethrow + </p> + </td> +<td> + <p> + Rethrows the error. + </p> + </td> +</tr> +</tbody> +</table></div> +<p> + <code class="computeroutput"><span class="identifier">rule</span></code> is the rule to which + the handler is attached. In our case, we are attaching to the <code class="computeroutput"><span class="identifier">xml</span></code> rule. + </p> +<p> + <code class="computeroutput"><span class="identifier">handler</span></code> is the actual error + handling function. It expects 4 arguments: + </p> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Arg + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + first + </p> + </td> +<td> + <p> + The position of the iterator when the rule with the handler was + entered. + </p> + </td> +</tr> +<tr> +<td> + <p> + last + </p> + </td> +<td> + <p> + The end of input. + </p> + </td> +</tr> +<tr> +<td> + <p> + error-pos + </p> + </td> +<td> + <p> + The actual position of the iterator where the error occured. + </p> + </td> +</tr> +<tr> +<td> + <p> + what + </p> + </td> +<td> + <p> + What failed: a string describing the failure. + </p> + </td> +</tr> +</tbody> +</table></div> +<h6> +<a name="spirit.qi.tutorials.mini_xml___error_handling.h2"></a> + <span><a name="spirit.qi.tutorials.mini_xml___error_handling.expectation_points"></a></span><a class="link" href="mini_xml___error_handling.html#spirit.qi.tutorials.mini_xml___error_handling.expectation_points">Expectation + Points</a> + </h6> +<p> + You might not have noticed it, but some of our expressions changed from + using the <code class="computeroutput"><span class="special">>></span></code> to <code class="computeroutput"><span class="special">></span></code>. Look, for example: + </p> +<pre class="programlisting"><span class="identifier">end_tag</span> <span class="special">=</span> + <span class="string">"</"</span> + <span class="special">></span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span> + <span class="special">></span> <span class="char">'>'</span> +<span class="special">;</span> +</pre> +<p> + What is it? It's the <span class="emphasis"><em>expectation</em></span> operator. You will + have some "deterministic points" in the grammar. Those are the + places where backtracking <span class="bold"><strong>cannot</strong></span> occur. + For our example above, when you get a <code class="computeroutput"><span class="string">"</"</span></code>, + you definitely must see a valid end-tag label next. It should be the one + you got from the start-tag. After that, you definitely must have a <code class="computeroutput"><span class="char">'>'</span></code> next. Otherwise, there is no point in + proceeding and trying other branches, regardless where they are. The input + is definitely erroneous. When this happens, an expectation_failure exception + is thrown. Somewhere outward, the error handler will catch the exception. + </p> +<p> + Try building the parser: <a href="../../../../../example/qi/mini_xml3.cpp" target="_top">../../example/qi/mini_xml3.cpp</a>. + You can find some examples in: <a href="../../../../../example/qi/mini_xml_samples" target="_top">../../example/qi/mini_xml_samples</a> + for testing purposes. "4.toyxml" has an error in it: + </p> +<pre class="programlisting"><span class="special"><</span><span class="identifier">foo</span><span class="special">><</span><span class="identifier">bar</span><span class="special">></</span><span class="identifier">foo</span><span class="special">></</span><span class="identifier">bar</span><span class="special">></span> +</pre> +<p> + Running the example with this gives you: + </p> +<pre class="programlisting"><span class="identifier">Error</span><span class="special">!</span> <span class="identifier">Expecting</span> <span class="string">"bar"</span> <span class="identifier">here</span><span class="special">:</span> <span class="string">"foo></bar>"</span> +<span class="identifier">Error</span><span class="special">!</span> <span class="identifier">Expecting</span> <span class="identifier">end_tag</span> <span class="identifier">here</span><span class="special">:</span> <span class="string">"<bar></foo></bar>"</span> +<span class="special">-------------------------</span> +<span class="identifier">Parsing</span> <span class="identifier">failed</span> +<span class="special">-------------------------</span> +</pre> +</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-2011 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="mini_xml___asts_.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="../quick_reference.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/number_list___stuffing_numbers_into_a_std__vector.html b/libs/spirit/doc/html/spirit/qi/tutorials/number_list___stuffing_numbers_into_a_std__vector.html new file mode 100755 index 0000000000..9e86f7b0f0 --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/number_list___stuffing_numbers_into_a_std__vector.html @@ -0,0 +1,97 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Number List - stuffing numbers into a std::vector</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="sum___adding_numbers.html" title="Sum - adding numbers"> +<link rel="next" href="number_list_redux___list_syntax.html" title="Number List Redux - list syntax"> +</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="sum___adding_numbers.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="number_list_redux___list_syntax.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.qi.tutorials.number_list___stuffing_numbers_into_a_std__vector"></a><a class="link" href="number_list___stuffing_numbers_into_a_std__vector.html" title="Number List - stuffing numbers into a std::vector">Number + List - stuffing numbers into a std::vector</a> +</h4></div></div></div> +<p> + This sample demonstrates a parser for a comma separated list of numbers. + The numbers are inserted in a vector using phoenix. + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">bool</span> <span class="identifier">parse_numbers</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">>&</span> <span class="identifier">v</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">_1</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">push_back</span><span class="special">;</span> + + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">phrase_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> + + <span class="comment">// Begin grammar</span> + <span class="special">(</span> + <span class="identifier">double_</span><span class="special">[</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">v</span><span class="special">),</span> <span class="identifier">_1</span><span class="special">)]</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="identifier">push_back</span><span class="special">(</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">v</span><span class="special">),</span> <span class="identifier">_1</span><span class="special">)])</span> + <span class="special">)</span> + <span class="special">,</span> + <span class="comment">// End grammar</span> + + <span class="identifier">space</span><span class="special">);</span> + + <span class="keyword">if</span> <span class="special">(</span><span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">)</span> <span class="comment">// fail if we did not get a full match</span> + <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">r</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + The full cpp file for this example can be found here: <a href="../../../../../example/qi/num_list2.cpp" target="_top">../../example/qi/num_list2.cpp</a> + </p> +<p> + This, again, is the same parser as before. This time, instead of summing + up the numbers, we stuff them in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>. + <code class="computeroutput"><span class="identifier">push_back</span></code> is supplied by + <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a>. The expression: + </p> +<pre class="programlisting"><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">v</span><span class="special">),</span> <span class="identifier">_1</span><span class="special">)</span> +</pre> +<p> + appends the parsed number. Like before, <code class="computeroutput"><span class="identifier">_1</span></code> + is a <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a> placeholder + for the parsed result attribute. Also, like before, <code class="computeroutput"><span class="identifier">ref</span><span class="special">(</span><span class="identifier">v</span><span class="special">)</span></code> + tells <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a> that + <code class="computeroutput"><span class="identifier">v</span></code>, the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>, + is a mutable reference. + </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-2011 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="sum___adding_numbers.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="number_list_redux___list_syntax.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/number_list_attribute___one_more__with_style.html b/libs/spirit/doc/html/spirit/qi/tutorials/number_list_attribute___one_more__with_style.html new file mode 100755 index 0000000000..3e409272e5 --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/number_list_attribute___one_more__with_style.html @@ -0,0 +1,124 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Number List Attribute - one more, with style</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="number_list_redux___list_syntax.html" title="Number List Redux - list syntax"> +<link rel="next" href="roman_numerals.html" title="Roman Numerals"> +</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="number_list_redux___list_syntax.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="roman_numerals.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.qi.tutorials.number_list_attribute___one_more__with_style"></a><a class="link" href="number_list_attribute___one_more__with_style.html" title="Number List Attribute - one more, with style">Number + List Attribute - one more, with style</a> +</h4></div></div></div> +<p> + You've seen that the <code class="computeroutput"><span class="identifier">double_</span></code> + parser has a <code class="computeroutput"><span class="keyword">double</span></code> attribute. + All parsers have an attribute, even complex parsers. Those that are composed + from primitives using operators, like the list parser, also have an attribute. + It so happens that the attribute of a list parser: + </p> +<pre class="programlisting"><span class="identifier">p</span> <span class="special">%</span> <span class="identifier">d</span> +</pre> +<p> + is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code> of the attribute of <code class="computeroutput"><span class="identifier">p</span></code>. So, for our parser: + </p> +<pre class="programlisting"><span class="identifier">double_</span> <span class="special">%</span> <span class="char">','</span> +</pre> +<p> + we'll have an attribute of: + </p> +<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> +</pre> +<p> + So, what does this give us? Well, we can simply pass in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span></code> + to our number list parser and it will happily churn out our result in our + vector. For that to happen, we'll use a variation of the <code class="computeroutput"><span class="identifier">phrase_parse</span></code> with an additional argument: + the parser's attribute. With the following arguments passed to <code class="computeroutput"><span class="identifier">phrase_parse</span></code> + </p> +<div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + An iterator pointing to the start of the input + </li> +<li class="listitem"> + An iterator pointing to one past the end of the input + </li> +<li class="listitem"> + The parser object + </li> +<li class="listitem"> + Another parser called the skip parser + </li> +<li class="listitem"> + The parser's attribute + </li> +</ol></div> +<p> + our parser now is further simplified to: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">bool</span> <span class="identifier">parse_numbers</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">>&</span> <span class="identifier">v</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">_1</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space</span><span class="special">;</span> + + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">phrase_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> + + <span class="comment">// Begin grammar</span> + <span class="special">(</span> + <span class="identifier">double_</span> <span class="special">%</span> <span class="char">','</span> + <span class="special">)</span> + <span class="special">,</span> + <span class="comment">// End grammar</span> + + <span class="identifier">space</span><span class="special">,</span> <span class="identifier">v</span><span class="special">);</span> + + <span class="keyword">if</span> <span class="special">(</span><span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">)</span> <span class="comment">// fail if we did not get a full match</span> + <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">r</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + The full cpp file for this example can be found here: <a href="../../../../../example/qi/num_list4.cpp" target="_top">../../example/qi/num_list4.cpp</a> + </p> +<p> + <span class="bold"><strong>Hey, no more actions!!!</strong></span> Now we're entering + the realm of attribute grammars. Cool eh? + </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-2011 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="number_list_redux___list_syntax.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="roman_numerals.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/number_list_redux___list_syntax.html b/libs/spirit/doc/html/spirit/qi/tutorials/number_list_redux___list_syntax.html new file mode 100755 index 0000000000..ceb53afe30 --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/number_list_redux___list_syntax.html @@ -0,0 +1,95 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Number List Redux - list syntax</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="number_list___stuffing_numbers_into_a_std__vector.html" title="Number List - stuffing numbers into a std::vector"> +<link rel="next" href="number_list_attribute___one_more__with_style.html" title="Number List Attribute - one more, with style"> +</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="number_list___stuffing_numbers_into_a_std__vector.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="number_list_attribute___one_more__with_style.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.qi.tutorials.number_list_redux___list_syntax"></a><a class="link" href="number_list_redux___list_syntax.html" title="Number List Redux - list syntax">Number + List Redux - list syntax</a> +</h4></div></div></div> +<p> + So far, we've been using the syntax: + </p> +<pre class="programlisting"><span class="identifier">double_</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> +</pre> +<p> + to parse a comma-delimited list of numbers. Such lists are common in parsing + and Spirit provides a simpler shortcut for them. The expression above can + be simplified to: + </p> +<pre class="programlisting"><span class="identifier">double_</span> <span class="special">%</span> <span class="char">','</span> +</pre> +<p> + read as: a list of doubles separated by <code class="computeroutput"><span class="char">','</span></code>. + </p> +<p> + This sample, again a variation of our previous example, demonstrates just + that: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">bool</span> <span class="identifier">parse_numbers</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">>&</span> <span class="identifier">v</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">_1</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">push_back</span><span class="special">;</span> + + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">phrase_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> + + <span class="comment">// Begin grammar</span> + <span class="special">(</span> + <span class="identifier">double_</span><span class="special">[</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">v</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> + <span class="special">,</span> + <span class="comment">// End grammar</span> + + <span class="identifier">space</span><span class="special">);</span> + + <span class="keyword">if</span> <span class="special">(</span><span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">)</span> <span class="comment">// fail if we did not get a full match</span> + <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">r</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + The full cpp file for this example can be found here: <a href="../../../../../example/qi/num_list3.cpp" target="_top">../../example/qi/num_list3.cpp</a> + </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-2011 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="number_list___stuffing_numbers_into_a_std__vector.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="number_list_attribute___one_more__with_style.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/quick_start.html b/libs/spirit/doc/html/spirit/qi/tutorials/quick_start.html new file mode 100755 index 0000000000..158046b01f --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/quick_start.html @@ -0,0 +1,82 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Quick Start</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="../tutorials.html" title="Tutorials"> +<link rel="next" href="warming_up.html" title="Warming up"> +</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="../tutorials.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="warming_up.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.qi.tutorials.quick_start"></a><a class="link" href="quick_start.html" title="Quick Start">Quick Start</a> +</h4></div></div></div> +<h6> +<a name="spirit.qi.tutorials.quick_start.h0"></a> + <span><a name="spirit.qi.tutorials.quick_start.why_would_you_want_to_use_spirit_qi_"></a></span><a class="link" href="quick_start.html#spirit.qi.tutorials.quick_start.why_would_you_want_to_use_spirit_qi_">Why + would you want to use Spirit.Qi?</a> + </h6> +<p> + Spirit.Qi is designed to be a practical parsing tool. The ability to generate + a fully-working parser from a formal EBNF specification inlined in C++ + significantly reduces development time. Programmers typically approach + parsing using ad hoc hacks with primitive tools such as scanf. Even regular-expression + libraries (such as boost regex) or scanners (such as Boost tokenizer) do + not scale well when we need to write more elaborate parsers. Attempting + to write even a moderately-complex parser using these tools leads to code + that is hard to understand and maintain. + </p> +<p> + One prime objective is to make the tool easy to use. When one thinks of + a parser generator, the usual reaction is "it must be big and complex + with a steep learning curve." Not so. Spirit is designed to be fully + scalable. The library is structured in layers. This permits learning on + an as-needed basis, after only learning the minimal core and basic concepts. + </p> +<p> + For development simplicity and ease in deployment, the entire library consists + of only header files, with no libraries to link against or build. Just + put the Spirit distribution in your include path, compile and run. Code + size? -very tight -essentially comparable to hand written recursive descent + code. + </p> +<p> + Our tutorials will walk you through the simplest Spirit examples, incrementally + building on top of the earlier examples as we expose more and more features + and techniques. We will try to be as gentle as possible with the learning + curve. We will present the tutorials in a cookbook style approach. This + style of presentation is based on our BoostCon '07 and BoostCon '08 slides. + </p> +<p> + Have fun! + </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-2011 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="../tutorials.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="warming_up.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/roman_numerals.html b/libs/spirit/doc/html/spirit/qi/tutorials/roman_numerals.html new file mode 100755 index 0000000000..6cf2201464 --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/roman_numerals.html @@ -0,0 +1,392 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Roman Numerals</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="number_list_attribute___one_more__with_style.html" title="Number List Attribute - one more, with style"> +<link rel="next" href="employee___parsing_into_structs.html" title="Employee - Parsing into structs"> +</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="number_list_attribute___one_more__with_style.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="employee___parsing_into_structs.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.qi.tutorials.roman_numerals"></a><a class="link" href="roman_numerals.html" title="Roman Numerals">Roman Numerals</a> +</h4></div></div></div> +<p> + This example demonstrates: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + symbol table + </li> +<li class="listitem"> + rule + </li> +<li class="listitem"> + grammar + </li> +</ul></div> +<h6> +<a name="spirit.qi.tutorials.roman_numerals.h0"></a> + <span><a name="spirit.qi.tutorials.roman_numerals.symbol_table"></a></span><a class="link" href="roman_numerals.html#spirit.qi.tutorials.roman_numerals.symbol_table">Symbol + Table</a> + </h6> +<p> + The symbol table holds a dictionary of symbols where each symbol is a sequence + of characters (a <code class="computeroutput"><span class="keyword">char</span></code>, <code class="computeroutput"><span class="keyword">wchar_t</span></code>, <code class="computeroutput"><span class="keyword">int</span></code>, + enumeration etc.) . The template class, parameterized by the character + type, can work efficiently with 8, 16, 32 and even 64 bit characters. Mutable + data of type T are associated with each symbol. + </p> +<p> + Traditionally, symbol table management is maintained separately outside + the BNF grammar through semantic actions. Contrary to standard practice, + the Spirit symbol table class <code class="computeroutput"><span class="identifier">symbols</span></code> + is a parser. An object of which may be used anywhere in the EBNF grammar + specification. It is an example of a dynamic parser. A dynamic parser is + characterized by its ability to modify its behavior at run time. Initially, + an empty symbols object matches nothing. At any time, symbols may be added + or removed, thus, dynamically altering its behavior. + </p> +<p> + Each entry in a symbol table has an associated mutable data slot. In this + regard, one can view the symbol table as an associative container (or map) + of key-value pairs where the keys are strings. + </p> +<p> + The symbols class expects two template parameters. The first parameter + specifies the character type of the symbols. The second specifies the data + type associated with each symbol: its attribute. + </p> +<p> + Here's a parser for roman hundreds (100..900) using the symbol table. Keep + in mind that the data associated with each slot is the parser's attribute + (which is passed to attached semantic actions). + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hundreds_</span> <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">symbols</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="keyword">unsigned</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">hundreds_</span><span class="special">()</span> + <span class="special">{</span> + <span class="identifier">add</span> + <span class="special">(</span><span class="string">"C"</span> <span class="special">,</span> <span class="number">100</span><span class="special">)</span> + <span class="special">(</span><span class="string">"CC"</span> <span class="special">,</span> <span class="number">200</span><span class="special">)</span> + <span class="special">(</span><span class="string">"CCC"</span> <span class="special">,</span> <span class="number">300</span><span class="special">)</span> + <span class="special">(</span><span class="string">"CD"</span> <span class="special">,</span> <span class="number">400</span><span class="special">)</span> + <span class="special">(</span><span class="string">"D"</span> <span class="special">,</span> <span class="number">500</span><span class="special">)</span> + <span class="special">(</span><span class="string">"DC"</span> <span class="special">,</span> <span class="number">600</span><span class="special">)</span> + <span class="special">(</span><span class="string">"DCC"</span> <span class="special">,</span> <span class="number">700</span><span class="special">)</span> + <span class="special">(</span><span class="string">"DCCC"</span> <span class="special">,</span> <span class="number">800</span><span class="special">)</span> + <span class="special">(</span><span class="string">"CM"</span> <span class="special">,</span> <span class="number">900</span><span class="special">)</span> + <span class="special">;</span> + <span class="special">}</span> + +<span class="special">}</span> <span class="identifier">hundreds</span><span class="special">;</span> +</pre> +<p> + </p> +<p> + Here's a parser for roman tens (10..90): + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">tens_</span> <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">symbols</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="keyword">unsigned</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">tens_</span><span class="special">()</span> + <span class="special">{</span> + <span class="identifier">add</span> + <span class="special">(</span><span class="string">"X"</span> <span class="special">,</span> <span class="number">10</span><span class="special">)</span> + <span class="special">(</span><span class="string">"XX"</span> <span class="special">,</span> <span class="number">20</span><span class="special">)</span> + <span class="special">(</span><span class="string">"XXX"</span> <span class="special">,</span> <span class="number">30</span><span class="special">)</span> + <span class="special">(</span><span class="string">"XL"</span> <span class="special">,</span> <span class="number">40</span><span class="special">)</span> + <span class="special">(</span><span class="string">"L"</span> <span class="special">,</span> <span class="number">50</span><span class="special">)</span> + <span class="special">(</span><span class="string">"LX"</span> <span class="special">,</span> <span class="number">60</span><span class="special">)</span> + <span class="special">(</span><span class="string">"LXX"</span> <span class="special">,</span> <span class="number">70</span><span class="special">)</span> + <span class="special">(</span><span class="string">"LXXX"</span> <span class="special">,</span> <span class="number">80</span><span class="special">)</span> + <span class="special">(</span><span class="string">"XC"</span> <span class="special">,</span> <span class="number">90</span><span class="special">)</span> + <span class="special">;</span> + <span class="special">}</span> + +<span class="special">}</span> <span class="identifier">tens</span><span class="special">;</span> +</pre> +<p> + </p> +<p> + and, finally, for ones (1..9): + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">ones_</span> <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">symbols</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="keyword">unsigned</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">ones_</span><span class="special">()</span> + <span class="special">{</span> + <span class="identifier">add</span> + <span class="special">(</span><span class="string">"I"</span> <span class="special">,</span> <span class="number">1</span><span class="special">)</span> + <span class="special">(</span><span class="string">"II"</span> <span class="special">,</span> <span class="number">2</span><span class="special">)</span> + <span class="special">(</span><span class="string">"III"</span> <span class="special">,</span> <span class="number">3</span><span class="special">)</span> + <span class="special">(</span><span class="string">"IV"</span> <span class="special">,</span> <span class="number">4</span><span class="special">)</span> + <span class="special">(</span><span class="string">"V"</span> <span class="special">,</span> <span class="number">5</span><span class="special">)</span> + <span class="special">(</span><span class="string">"VI"</span> <span class="special">,</span> <span class="number">6</span><span class="special">)</span> + <span class="special">(</span><span class="string">"VII"</span> <span class="special">,</span> <span class="number">7</span><span class="special">)</span> + <span class="special">(</span><span class="string">"VIII"</span> <span class="special">,</span> <span class="number">8</span><span class="special">)</span> + <span class="special">(</span><span class="string">"IX"</span> <span class="special">,</span> <span class="number">9</span><span class="special">)</span> + <span class="special">;</span> + <span class="special">}</span> + +<span class="special">}</span> <span class="identifier">ones</span><span class="special">;</span> +</pre> +<p> + </p> +<p> + Now we can use <code class="computeroutput"><span class="identifier">hundreds</span></code>, + <code class="computeroutput"><span class="identifier">tens</span></code> and <code class="computeroutput"><span class="identifier">ones</span></code> anywhere in our parser expressions. + They are all parsers. + </p> +<h6> +<a name="spirit.qi.tutorials.roman_numerals.h1"></a> + <span><a name="spirit.qi.tutorials.roman_numerals.rules"></a></span><a class="link" href="roman_numerals.html#spirit.qi.tutorials.roman_numerals.rules">Rules</a> + </h6> +<p> + Up until now, we've been inlining our parser expressions, passing them + directly to the <code class="computeroutput"><span class="identifier">phrase_parse</span></code> + function. The expression evaluates into a temporary, unnamed parser which + is passed into the <code class="computeroutput"><span class="identifier">phrase_parse</span></code> + function, used, and then destroyed. This is fine for small parsers. When + the expressions get complicated, you'd want to break the expressions into + smaller easier-to-understand pieces, name them, and refer to them from + other parser expressions by name. + </p> +<p> + A parser expression can be assigned to what is called a "rule". + There are various ways to declare rules. The simplest form is: + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">></span> <span class="identifier">r</span><span class="special">;</span> +</pre> +<p> + At the very least, the rule needs to know the iterator type it will be + working on. This rule cannot be used with <code class="computeroutput"><span class="identifier">phrase_parse</span></code>. + It can only be used with the <code class="computeroutput"><span class="identifier">parse</span></code> + function -- a version that does not do white space skipping (does not have + the skipper argument). If you want to have it skip white spaces, you need + to pass in the type skip parser, as in the next form: + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Skipper</span><span class="special">></span> <span class="identifier">r</span><span class="special">;</span> +</pre> +<p> + Example: + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">iterator</span><span class="special">,</span> <span class="identifier">space_type</span><span class="special">></span> <span class="identifier">r</span><span class="special">;</span> +</pre> +<p> + This type of rule can be used for both <code class="computeroutput"><span class="identifier">phrase_parse</span></code> + and <code class="computeroutput"><span class="identifier">parse</span></code>. + </p> +<p> + For our next example, there's one more rule form you should know about: + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Signature</span><span class="special">></span> <span class="identifier">r</span><span class="special">;</span> +</pre> +<p> + or + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Signature</span><span class="special">,</span> <span class="identifier">Skipper</span><span class="special">></span> <span class="identifier">r</span><span class="special">;</span> +</pre> +<div class="tip"><table border="0" summary="Tip"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../images/tip.png"></td> +<th align="left">Tip</th> +</tr> +<tr><td align="left" valign="top"><p> + All rule template arguments after Iterator can be supplied in any order. + </p></td></tr> +</table></div> +<p> + The Signature specifies the attributes of the rule. You've seen that our + parsers can have an attribute. Recall that the <code class="computeroutput"><span class="identifier">double_</span></code> + parser has an attribute of <code class="computeroutput"><span class="keyword">double</span></code>. + To be precise, these are <span class="emphasis"><em>synthesized</em></span> attributes. The + parser "synthesizes" the attribute value. Think of them as function + return values. + </p> +<p> + There's another type of attribute called "inherited" attribute. + We won't need them for now, but it's good that you be aware of such attributes. + You can think of them as function arguments. And, rightly so, the rule + signature is a function signature of the form: + </p> +<pre class="programlisting"><span class="identifier">result</span><span class="special">(</span><span class="identifier">argN</span><span class="special">,</span> <span class="identifier">argN</span><span class="special">,...,</span> <span class="identifier">argN</span><span class="special">)</span> +</pre> +<p> + After having declared a rule, you can now assign any parser expression + to it. Example: + </p> +<pre class="programlisting"><span class="identifier">r</span> <span class="special">=</span> <span class="identifier">double_</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> +</pre> +<h6> +<a name="spirit.qi.tutorials.roman_numerals.h2"></a> + <span><a name="spirit.qi.tutorials.roman_numerals.grammars"></a></span><a class="link" href="roman_numerals.html#spirit.qi.tutorials.roman_numerals.grammars">Grammars</a> + </h6> +<p> + A grammar encapsulates one or more rules. It has the same template parameters + as the rule. You declare a grammar by: + </p> +<div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + deriving a struct (or class) from the <code class="computeroutput"><span class="identifier">grammar</span></code> + class template + </li> +<li class="listitem"> + declare one or more rules as member variables + </li> +<li class="listitem"> + initialize the base grammar class by giving it the start rule (its + the first rule that gets called when the grammar starts parsing) + </li> +<li class="listitem"> + initialize your rules in your constructor + </li> +</ol></div> +<p> + The roman numeral grammar is a very nice and simple example of a grammar: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">roman</span> <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">grammar</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">unsigned</span><span class="special">()></span> +<span class="special">{</span> + <span class="identifier">roman</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">roman</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">start</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">eps</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">_val</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">_1</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> + + <span class="identifier">start</span> <span class="special">=</span> <span class="identifier">eps</span> <span class="special">[</span><span class="identifier">_val</span> <span class="special">=</span> <span class="number">0</span><span class="special">]</span> <span class="special">>></span> + <span class="special">(</span> + <span class="special">+</span><span class="identifier">lit</span><span class="special">(</span><span class="char">'M'</span><span class="special">)</span> <span class="special">[</span><span class="identifier">_val</span> <span class="special">+=</span> <span class="number">1000</span><span class="special">]</span> + <span class="special">||</span> <span class="identifier">hundreds</span> <span class="special">[</span><span class="identifier">_val</span> <span class="special">+=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">||</span> <span class="identifier">tens</span> <span class="special">[</span><span class="identifier">_val</span> <span class="special">+=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">||</span> <span class="identifier">ones</span> <span class="special">[</span><span class="identifier">_val</span> <span class="special">+=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">)</span> + <span class="special">;</span> + <span class="special">}</span> + + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">unsigned</span><span class="special">()></span> <span class="identifier">start</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + Things to take notice of: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + The grammar and start rule signature is <code class="computeroutput"><span class="keyword">unsigned</span><span class="special">()</span></code>. It has a synthesized attribute (return + value) of type <code class="computeroutput"><span class="keyword">unsigned</span></code> + with no inherited attributes (arguments). + </li> +<li class="listitem"> + We did not specify a skip-parser. We don't want to skip in between + the numerals. + </li> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">roman</span><span class="special">::</span><span class="identifier">base_type</span></code> is a typedef for <code class="computeroutput"><span class="identifier">grammar</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> + <span class="keyword">unsigned</span><span class="special">()></span></code>. + If <code class="computeroutput"><span class="identifier">roman</span></code> was not a + template, you could simply write: base_type(start) + </li> +<li class="listitem"> + It's best to make your grammar templates such that they can be reused + for different iterator types. + </li> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">_val</span></code> is another <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a> placeholder + representing the rule's synthesized attribute. + </li> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">eps</span></code> is a special spirit + parser that consumes no input but is always successful. We use it to + initialize <code class="computeroutput"><span class="identifier">_val</span></code>, the + rule's synthesized attribute, to zero before anything else. The actual + parser starts at <code class="computeroutput"><span class="special">+</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'M'</span><span class="special">)</span></code>, + parsing roman thousands. Using <code class="computeroutput"><span class="identifier">eps</span></code> + this way is good for doing pre and post initializations. + </li> +<li class="listitem"> + The expression <code class="computeroutput"><span class="identifier">a</span> <span class="special">||</span> + <span class="identifier">b</span></code> reads: match a or b and + in sequence. That is, if both <code class="computeroutput"><span class="identifier">a</span></code> + and <code class="computeroutput"><span class="identifier">b</span></code> match, it must + be in sequence; this is equivalent to <code class="computeroutput"><span class="identifier">a</span> + <span class="special">>></span> <span class="special">-</span><span class="identifier">b</span> <span class="special">|</span> <span class="identifier">b</span></code>, but more efficient. + </li> +</ul></div> +<h6> +<a name="spirit.qi.tutorials.roman_numerals.h3"></a> + <span><a name="spirit.qi.tutorials.roman_numerals.let_s_parse_"></a></span><a class="link" href="roman_numerals.html#spirit.qi.tutorials.roman_numerals.let_s_parse_">Let's + Parse!</a> + </h6> +<p> +</p> +<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">parse</span><span class="special">(</span><span class="identifier">iter</span><span class="special">,</span> <span class="identifier">end</span><span class="special">,</span> <span class="identifier">roman_parser</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span> + +<span class="keyword">if</span> <span class="special">(</span><span class="identifier">r</span> <span class="special">&&</span> <span class="identifier">iter</span> <span class="special">==</span> <span class="identifier">end</span><span class="special">)</span> +<span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"-------------------------\n"</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Parsing succeeded\n"</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"result = "</span> <span class="special"><<</span> <span class="identifier">result</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"-------------------------\n"</span><span class="special">;</span> +<span class="special">}</span> +<span class="keyword">else</span> +<span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">rest</span><span class="special">(</span><span class="identifier">iter</span><span class="special">,</span> <span class="identifier">end</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"-------------------------\n"</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Parsing failed\n"</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"stopped at: \": "</span> <span class="special"><<</span> <span class="identifier">rest</span> <span class="special"><<</span> <span class="string">"\"\n"</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"-------------------------\n"</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + <code class="computeroutput"><span class="identifier">roman_parser</span></code> is an object + of type <code class="computeroutput"><span class="identifier">roman</span></code>, our roman + numeral parser. This time around we are using the no-skipping version of + the parse functions. We do not want to skip any spaces! We are also passing + in an attribute, <code class="computeroutput"><span class="keyword">unsigned</span> <span class="identifier">result</span></code>, which will receive the parsed + value. + </p> +<p> + The full cpp file for this example can be found here: <a href="../../../../../example/qi/roman.cpp" target="_top">../../example/qi/roman.cpp</a> + </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-2011 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="number_list_attribute___one_more__with_style.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="employee___parsing_into_structs.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/semantic_actions.html b/libs/spirit/doc/html/spirit/qi/tutorials/semantic_actions.html new file mode 100755 index 0000000000..c47024b3ec --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/semantic_actions.html @@ -0,0 +1,274 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Parser Semantic Actions</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="warming_up.html" title="Warming up"> +<link rel="next" href="complex___our_first_complex_parser.html" title="Complex - Our first complex parser"> +</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="complex___our_first_complex_parser.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.qi.tutorials.semantic_actions"></a><a class="link" href="semantic_actions.html" title="Parser Semantic Actions">Parser Semantic + Actions</a> +</h4></div></div></div> +<p> + The example in the previous section was very simplistic. It only recognized + data, but did nothing with it. It answered the question: "Did the + input match?". Now, we want to extract information from what was parsed. + For example, we would want to store the parsed number after a successful + match. To do this, you will need <span class="emphasis"><em>semantic actions</em></span>. + </p> +<p> + 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 parser successfully recognizes a portion of the input. Say + you have a parser <code class="computeroutput"><span class="identifier">P</span></code>, and + a C++ function <code class="computeroutput"><span class="identifier">F</span></code>. You can + make the parser call <code class="computeroutput"><span class="identifier">F</span></code> + whenever it matches an input by attaching <code class="computeroutput"><span class="identifier">F</span></code>: + </p> +<pre class="programlisting"><span class="identifier">P</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 parser, <code class="computeroutput"><span class="identifier">P</span></code>. + </p> +<p> + The function/function object signature depends on the type of the parser + to which it is attached. The parser <code class="computeroutput"><span class="identifier">double_</span></code> + passes the parsed number. 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="identifier">n</span><span class="special">);</span> +</pre> +<p> + There are actually 2 more arguments being passed (the parser context and + a reference to a boolean 'hit' parameter). We don't need these, for now, + but we'll see more on these other arguments later. Spirit.Qi allows us + to bind a single argument function, like above. The other arguments are + simply ignored. + </p> +<h6> +<a name="spirit.qi.tutorials.semantic_actions.h0"></a> + <span><a name="spirit.qi.tutorials.semantic_actions.examples_of_semantic_actions"></a></span><a class="link" href="semantic_actions.html#spirit.qi.tutorials.semantic_actions.examples_of_semantic_actions">Examples + of Semantic Actions</a> + </h6> +<p> + Presented are 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 <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> + Given: + </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">qi</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">qi</span><span class="special">;</span> + + <span class="comment">// A plain function</span> + <span class="keyword">void</span> <span class="identifier">print</span><span class="special">(</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">i</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="special">}</span> + + <span class="comment">// A member function</span> + <span class="keyword">struct</span> <span class="identifier">writer</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="keyword">const</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">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</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">print_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="keyword">const</span><span class="special">&</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">unused_type</span><span class="special">,</span> <span class="identifier">qi</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">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</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. <code class="computeroutput"><span class="identifier">unused_type</span></code> + is a Spirit supplied support class. + </p> +<p> + All examples parse inputs 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">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</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">print</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 sibling of <code class="computeroutput"><span class="identifier">double_</span></code>. + I'm sure you can guess what this parser does. + </p> +<p> + The next example shows how to attach a simple function object: + </p> +<p> +</p> +<pre class="programlisting"><span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</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">print_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">writer</span> <span class="identifier">w</span><span class="special">;</span> +<span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</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">writer</span><span class="special">::</span><span class="identifier">print</span><span class="special">,</span> <span class="special">&</span><span class="identifier">w</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">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</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">print</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> + Yep, we can also use <a href="../../../../../../../libs/lambda/index.html" target="_top">Boost.Lambda</a>: + </p> +<p> +</p> +<pre class="programlisting"><span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</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">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">_1</span> <span class="special"><<</span> <span class="char">'\n'</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 parsing with Spirit. Familiarize + yourself with this task and get intimate 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/qi/actions.cpp" target="_top">../../example/qi/actions.cpp</a> + </p> +<h6> +<a name="spirit.qi.tutorials.semantic_actions.h1"></a> + <span><a name="spirit.qi.tutorials.semantic_actions.phoenix"></a></span><a class="link" href="semantic_actions.html#spirit.qi.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 parsing, it is suggested that you use this library. All the following + examples in this tutorial will use <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a> + for semantic actions. + </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.Qi</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 global 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">qi</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-2011 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="complex___our_first_complex_parser.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/sum___adding_numbers.html b/libs/spirit/doc/html/spirit/qi/tutorials/sum___adding_numbers.html new file mode 100755 index 0000000000..12c10cabd7 --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/sum___adding_numbers.html @@ -0,0 +1,233 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Sum - adding numbers</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="complex___our_first_complex_parser.html" title="Complex - Our first complex parser"> +<link rel="next" href="number_list___stuffing_numbers_into_a_std__vector.html" title="Number List - stuffing numbers into a std::vector"> +</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="complex___our_first_complex_parser.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="number_list___stuffing_numbers_into_a_std__vector.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.qi.tutorials.sum___adding_numbers"></a><a class="link" href="sum___adding_numbers.html" title="Sum - adding numbers">Sum - adding + numbers</a> +</h4></div></div></div> +<p> + Here's a parser that sums a comma-separated list of numbers. + </p> +<p> + Ok we've glossed over some details in our previous examples. First, our + includes: + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</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">include</span><span class="special">/</span><span class="identifier">qi</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</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">include</span><span class="special">/</span><span class="identifier">phoenix_core</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</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">include</span><span class="special">/</span><span class="identifier">phoenix_operator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span> +</pre> +<p> + </p> +<p> + Then some using directives: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">qi</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">qi</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">ascii</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">ascii</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">phoenix</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">;</span> + +<span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">_1</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">ref</span><span class="special">;</span> +</pre> +<p> + </p> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Namespace + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + boost::phoenix + </p> + </td> +<td> + <p> + All of phoenix + </p> + </td> +</tr> +<tr> +<td> + <p> + boost::spirit + </p> + </td> +<td> + <p> + All of spirit + </p> + </td> +</tr> +<tr> +<td> + <p> + boost::spirit::qi + </p> + </td> +<td> + <p> + All of spirit.qi + </p> + </td> +</tr> +<tr> +<td> + <p> + boost::spirit::ascii + </p> + </td> +<td> + <p> + ASCII version of <code class="computeroutput"><span class="identifier">char_</span></code> + and all char related parsers. Other encodings are also provided + (e.g. also an ISO8859.1) + </p> + </td> +</tr> +<tr> +<td> + <p> + boost::spirit::arg_names + </p> + </td> +<td> + <p> + Special phoenix placeholders for spirit + </p> + </td> +</tr> +</tbody> +</table></div> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + If you feel uneasy with using whole namespaces, feel free to qualify + your code, use namespace aliases, etc. For the purpose of this tutorial, + we will be presenting unqualified names for both Spirit and <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a>. + No worries, we will always present the full working code, so you won't + get lost. In fact, all examples in this tutorial have a corresponding + cpp file that QuickBook (the documentation tool we are using) imports + in here as code snippets. + </p></td></tr> +</table></div> +<p> + Now the actual parser: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">bool</span> <span class="identifier">adder</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&</span> <span class="identifier">n</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> + + <span class="comment">// Begin grammar</span> + <span class="special">(</span> + <span class="identifier">double_</span><span class="special">[</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</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="identifier">ref</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span> <span class="special">+=</span> <span class="identifier">_1</span><span class="special">])</span> + <span class="special">)</span> + <span class="special">,</span> + <span class="comment">// End grammar</span> + + <span class="identifier">space</span><span class="special">);</span> + + <span class="keyword">if</span> <span class="special">(</span><span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">)</span> <span class="comment">// fail if we did not get a full match</span> + <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">r</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + The full cpp file for this example can be found here: <a href="../../../../../example/qi/sum.cpp" target="_top">../../example/qi/sum.cpp</a> + </p> +<p> + This is almost like our original numbers list example. We're incrementally + building on top of our examples. This time though, like in the complex + number example, we'll be adding the smarts. There's an accumulator (<code class="computeroutput"><span class="keyword">double</span><span class="special">&</span> <span class="identifier">n</span></code>) that adds the numbers parsed. On a + successful parse, this number is the sum of all the parsed numbers. + </p> +<p> + The first <code class="computeroutput"><span class="identifier">double_</span></code> parser + attaches this action: + </p> +<pre class="programlisting"><span class="identifier">ref</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">_1</span> +</pre> +<p> + This assigns the parsed result (actually, the attribute of <code class="computeroutput"><span class="identifier">double_</span></code>) to <code class="computeroutput"><span class="identifier">n</span></code>. + <code class="computeroutput"><span class="identifier">ref</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span></code> tells + <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a> that <code class="computeroutput"><span class="identifier">n</span></code> is a mutable reference. <code class="computeroutput"><span class="identifier">_1</span></code> is a <a href="../../../../../phoenix/doc/html/index.html" target="_top">Phoenix</a> + placeholder for the parsed result attribute. + </p> +<p> + The second <code class="computeroutput"><span class="identifier">double_</span></code> parser + attaches this action: + </p> +<pre class="programlisting"><span class="identifier">ref</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span> <span class="special">+=</span> <span class="identifier">_1</span> +</pre> +<p> + So, subsequent numbers add into <code class="computeroutput"><span class="identifier">n</span></code>. + </p> +<p> + That wasn't too bad, was it :-) ? + </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-2011 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="complex___our_first_complex_parser.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="number_list___stuffing_numbers_into_a_std__vector.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/doc/html/spirit/qi/tutorials/warming_up.html b/libs/spirit/doc/html/spirit/qi/tutorials/warming_up.html new file mode 100755 index 0000000000..466b7e5fb3 --- /dev/null +++ b/libs/spirit/doc/html/spirit/qi/tutorials/warming_up.html @@ -0,0 +1,294 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Warming up</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit 2.5.2"> +<link rel="up" href="../tutorials.html" title="Tutorials"> +<link rel="prev" href="quick_start.html" title="Quick Start"> +<link rel="next" href="semantic_actions.html" title="Parser Semantic Actions"> +</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="quick_start.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="semantic_actions.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.qi.tutorials.warming_up"></a><a class="link" href="warming_up.html" title="Warming up">Warming up</a> +</h4></div></div></div> +<p> + We'll start by showing examples of parser expressions to give you a feel + on how to build parsers from the simplest parser, building up as we go. + When comparing EBNF to <a href="http://boost-spirit.com" target="_top">Spirit</a>, + the expressions may seem awkward at first. <a href="http://boost-spirit.com" target="_top">Spirit</a> + heavily uses operator overloading to accomplish its magic. + </p> +<h6> +<a name="spirit.qi.tutorials.warming_up.h0"></a> + <span><a name="spirit.qi.tutorials.warming_up.trivial_example__1_parsing_a_number"></a></span><a class="link" href="warming_up.html#spirit.qi.tutorials.warming_up.trivial_example__1_parsing_a_number">Trivial + Example #1 Parsing a number</a> + </h6> +<p> + Create a parser that will parse a floating-point number. + </p> +<pre class="programlisting"><span class="identifier">double_</span> +</pre> +<p> + (You've got to admit, that's trivial!) The above code actually generates + a Spirit floating point parser (a built-in parser). Spirit has many pre-defined + parsers and consistent naming conventions help you keep from going insane! + </p> +<h6> +<a name="spirit.qi.tutorials.warming_up.h1"></a> + <span><a name="spirit.qi.tutorials.warming_up.trivial_example__2_parsing_two_numbers"></a></span><a class="link" href="warming_up.html#spirit.qi.tutorials.warming_up.trivial_example__2_parsing_two_numbers">Trivial + Example #2 Parsing two numbers</a> + </h6> +<p> + Create a parser that will accept a line consisting of two floating-point + numbers. + </p> +<pre class="programlisting"><span class="identifier">double_</span> <span class="special">>></span> <span class="identifier">double_</span> +</pre> +<p> + Here you see the familiar floating-point numeric parser <code class="computeroutput"><span class="identifier">double_</span></code> + used twice, once for each number. What's that <code class="computeroutput"><span class="special">>></span></code> + operator doing in there? Well, they had to be separated by something, and + this was chosen as the "followed by" sequence operator. The above + program creates a parser from two simpler parsers, glueing them together + with the sequence operator. The result is a parser that is a composition + of smaller parsers. Whitespace between numbers can implicitly be consumed + depending on how the parser is invoked (see below). + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + When we combine parsers, we end up with a "bigger" parser, + but it's still a parser. Parsers can get bigger and bigger, nesting more + and more, but whenever you glue two parsers together, you end up with + one bigger parser. This is an important concept. + </p></td></tr> +</table></div> +<h6> +<a name="spirit.qi.tutorials.warming_up.h2"></a> + <span><a name="spirit.qi.tutorials.warming_up.trivial_example__3_parsing_zero_or_more_numbers"></a></span><a class="link" href="warming_up.html#spirit.qi.tutorials.warming_up.trivial_example__3_parsing_zero_or_more_numbers">Trivial + Example #3 Parsing zero or more numbers</a> + </h6> +<p> + Create a parser that will accept zero or more floating-point numbers. + </p> +<pre class="programlisting"><span class="special">*</span><span class="identifier">double_</span> +</pre> +<p> + This is like a regular-expression Kleene Star, though the syntax might + look a bit odd for a C++ programmer not used to seeing the <code class="computeroutput"><span class="special">*</span></code> operator overloaded like this. Actually, + if you know regular expressions it may look odd too since the star is before + the expression it modifies. C'est la vie. Blame it on the fact that we + must work with the syntax rules of C++. + </p> +<p> + Any expression that evaluates to a parser may be used with the Kleene Star. + Keep in mind that C++ operator precedence rules may require you to put + expressions in parentheses for complex expressions. The Kleene Star is + also known as a Kleene Closure, but we call it the Star in most places. + </p> +<h6> +<a name="spirit.qi.tutorials.warming_up.h3"></a> + <span><a name="spirit.qi.tutorials.warming_up.trivial_example__4_parsing_a_comma_delimited_list_of_numbers"></a></span><a class="link" href="warming_up.html#spirit.qi.tutorials.warming_up.trivial_example__4_parsing_a_comma_delimited_list_of_numbers">Trivial + Example #4 Parsing a comma-delimited list of numbers</a> + </h6> +<p> + This example will create a parser that accepts a comma-delimited list of + numbers. + </p> +<pre class="programlisting"><span class="identifier">double_</span> <span class="special">>></span> <span class="special">*(</span><span class="identifier">char_</span><span class="special">(</span><span class="char">','</span><span class="special">)</span> <span class="special">>></span> <span class="identifier">double_</span><span class="special">)</span> +</pre> +<p> + Notice <code class="computeroutput"><span class="identifier">char_</span><span class="special">(</span><span class="char">','</span><span class="special">)</span></code>. It is + a literal character parser that can recognize the comma <code class="computeroutput"><span class="char">','</span></code>. + In this case, the Kleene Star is modifying a more complex parser, namely, + the one generated by the expression: + </p> +<pre class="programlisting"><span class="special">(</span><span class="identifier">char_</span><span class="special">(</span><span class="char">','</span><span class="special">)</span> <span class="special">>></span> <span class="identifier">double_</span><span class="special">)</span> +</pre> +<p> + Note that this is a case where the parentheses are necessary. The Kleene + star encloses the complete expression above. + </p> +<h6> +<a name="spirit.qi.tutorials.warming_up.h4"></a> + <span><a name="spirit.qi.tutorials.warming_up.let_s_parse_"></a></span><a class="link" href="warming_up.html#spirit.qi.tutorials.warming_up.let_s_parse_">Let's + Parse!</a> + </h6> +<p> + We're done with defining the parser. So the next step is now invoking this + parser to do its work. There are a couple of ways to do this. For now, + we will use the <code class="computeroutput"><span class="identifier">phrase_parse</span></code> + function. One overload of this function accepts four arguments: + </p> +<div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + An iterator pointing to the start of the input + </li> +<li class="listitem"> + An iterator pointing to one past the end of the input + </li> +<li class="listitem"> + The parser object + </li> +<li class="listitem"> + Another parser called the skip parser + </li> +</ol></div> +<p> + In our example, we wish to skip spaces and tabs. Another parser named + <code class="computeroutput"><span class="identifier">space</span></code> is included in Spirit's + repertoire of predefined parsers. It is a very simple parser that simply + recognizes whitespace. We will use <code class="computeroutput"><span class="identifier">space</span></code> + as our skip parser. The skip parser is the one responsible for skipping + characters in between parser elements such as the <code class="computeroutput"><span class="identifier">double_</span></code> + and <code class="computeroutput"><span class="identifier">char_</span></code>. + </p> +<p> + Ok, so now let's parse! + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">bool</span> <span class="identifier">parse_numbers</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">last</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space</span><span class="special">;</span> + + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">phrase_parse</span><span class="special">(</span> + <span class="identifier">first</span><span class="special">,</span> <a class="co" name="spirit.qi.tutorials.warming_up.c0" href="warming_up.html#spirit.qi.tutorials.warming_up.c1"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> + <span class="identifier">last</span><span class="special">,</span> <a class="co" name="spirit.qi.tutorials.warming_up.c2" href="warming_up.html#spirit.qi.tutorials.warming_up.c3"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> + <span class="identifier">double_</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> <a class="co" name="spirit.qi.tutorials.warming_up.c4" href="warming_up.html#spirit.qi.tutorials.warming_up.c5"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> + <span class="identifier">space</span> <a class="co" name="spirit.qi.tutorials.warming_up.c6" href="warming_up.html#spirit.qi.tutorials.warming_up.c7"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> + <span class="special">);</span> + <span class="keyword">if</span> <span class="special">(</span><span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">)</span> <span class="comment">// fail if we did not get a full match</span> + <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">r</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +<div class="calloutlist"><table border="0" summary="Callout list"> +<tr> +<td width="5%" valign="top" align="left"><p><a name="spirit.qi.tutorials.warming_up.c1"></a><a href="#spirit.qi.tutorials.warming_up.c0"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td> +<td valign="top" align="left"><p> + start iterator + </p></td> +</tr> +<tr> +<td width="5%" valign="top" align="left"><p><a name="spirit.qi.tutorials.warming_up.c3"></a><a href="#spirit.qi.tutorials.warming_up.c2"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td> +<td valign="top" align="left"><p> + end iterator + </p></td> +</tr> +<tr> +<td width="5%" valign="top" align="left"><p><a name="spirit.qi.tutorials.warming_up.c5"></a><a href="#spirit.qi.tutorials.warming_up.c4"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td> +<td valign="top" align="left"><p> + the parser + </p></td> +</tr> +<tr> +<td width="5%" valign="top" align="left"><p><a name="spirit.qi.tutorials.warming_up.c7"></a><a href="#spirit.qi.tutorials.warming_up.c6"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td> +<td valign="top" align="left"><p> + the skip-parser + </p></td> +</tr> +</table></div> +<p> + The parse function returns <code class="computeroutput"><span class="keyword">true</span></code> + or <code class="computeroutput"><span class="keyword">false</span></code> depending on the + result of the parse. The first iterator is passed by reference. On a successful + parse, this iterator is repositioned to the rightmost position consumed + by the parser. If this becomes equal to <code class="computeroutput"><span class="identifier">last</span></code>, + then we have a full match. If not, then we have a partial match. A partial + match happens when the parser is only able to parse a portion of the input. + </p> +<p> + Note that we inlined the parser directly in the call to parse. Upon calling + parse, the expression evaluates into a temporary, unnamed parser which + is passed into the parse() function, used, and then destroyed. + </p> +<p> + Here, we opted to make the parser generic by making it a template, parameterized + by the iterator type. By doing so, it can take in data coming from any + STL conforming sequence as long as the iterators conform to a forward iterator. + </p> +<p> + You can find the full cpp file here: <a href="../../../../../example/qi/num_list1.cpp" target="_top">../../example/qi/num_list1.cpp</a> + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"> +<p> + <code class="computeroutput"><span class="keyword">char</span></code> and <code class="computeroutput"><span class="keyword">wchar_t</span></code> + operands + </p> +<p> + The careful reader may notice that the parser expression has <code class="computeroutput"><span class="char">','</span></code> instead of <code class="computeroutput"><span class="identifier">char_</span><span class="special">(</span><span class="char">','</span><span class="special">)</span></code> + as the previous examples did. This is ok due to C++ syntax rules of conversion. + There are <code class="computeroutput"><span class="special">>></span></code> operators + that are overloaded to accept a <code class="computeroutput"><span class="keyword">char</span></code> + or <code class="computeroutput"><span class="keyword">wchar_t</span></code> argument on its + left or right (but not both). An operator may be overloaded if at least + one of its parameters is a user-defined type. In this case, the <code class="computeroutput"><span class="identifier">double_</span></code> is the 2nd argument to <code class="computeroutput"><span class="keyword">operator</span><span class="special">>></span></code>, + and so the proper overload of <code class="computeroutput"><span class="special">>></span></code> + is used, converting <code class="computeroutput"><span class="char">','</span></code> into + a character literal parser. + </p> +<p> + The problem with omitting the <code class="computeroutput"><span class="identifier">char_</span></code> + should be obvious: <code class="computeroutput"><span class="char">'a'</span> <span class="special">>></span> + <span class="char">'b'</span></code> is not a spirit parser, it is + a numeric expression, right-shifting the ASCII (or another encoding) + value of <code class="computeroutput"><span class="char">'a'</span></code> by the ASCII value + of <code class="computeroutput"><span class="char">'b'</span></code>. However, both <code class="computeroutput"><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">)</span> <span class="special">>></span> + <span class="char">'b'</span></code> and <code class="computeroutput"><span class="char">'a'</span> + <span class="special">>></span> <span class="identifier">char_</span><span class="special">(</span><span class="char">'b'</span><span class="special">)</span></code> + are Spirit sequence parsers for the letter <code class="computeroutput"><span class="char">'a'</span></code> + followed by <code class="computeroutput"><span class="char">'b'</span></code>. You'll get + used to it, sooner or later. + </p> +</td></tr> +</table></div> +<p> + Finally, take note that we test for a full match (i.e. the parser fully + parsed the input) by checking if the first iterator, after parsing, is + equal to the end iterator. You may strike out this part if partial matches + are to be allowed. + </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-2011 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="quick_start.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="semantic_actions.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> |