• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Mini XML - ASTs!</title>
5<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../../../index.html" title="Spirit 2.5.8">
8<link rel="up" href="../tutorials.html" title="Tutorials">
9<link rel="prev" href="employee___parsing_into_structs.html" title="Employee - Parsing into structs">
10<link rel="next" href="mini_xml___error_handling.html" title="Mini XML - Error Handling">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="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>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h4 class="title">
27<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>
28</h4></div></div></div>
29<p>
30          Stop and think about it... We've come very close to generating an AST (abstract
31          syntax tree) in our last example. We parsed a single structure and generated
32          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>.
33          If we changed the implementation to parse one or more employees, the result
34          would be a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">employee</span><span class="special">&gt;</span></code>.
35          We can go on and add more hierarchy: teams, departments, corporations.
36          Then we'll have an AST representation of it all.
37        </p>
38<p>
39          In this example (actually two examples), we'll now explore how to create
40          ASTs. We will parse a minimalistic XML-like language and compile the results
41          into our data structures in the form of a tree.
42        </p>
43<p>
44          Along the way, we'll see new features:
45        </p>
46<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
47<li class="listitem">
48              Inherited attributes
49            </li>
50<li class="listitem">
51              Variant attributes
52            </li>
53<li class="listitem">
54              Local Variables
55            </li>
56<li class="listitem">
57              Not Predicate
58            </li>
59<li class="listitem">
60              Lazy Lit
61            </li>
62</ul></div>
63<p>
64          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>
65          and here: <a href="../../../../../example/qi/mini_xml2.cpp" target="_top">../../example/qi/mini_xml2.cpp</a>
66        </p>
67<p>
68          There are a couple of sample toy-xml files in the mini_xml_samples subdirectory:
69          <a href="../../../../../example/qi/mini_xml_samples/1.toyxml" target="_top">../../example/qi/mini_xml_samples/1.toyxml</a>,
70          <a href="../../../../../example/qi/mini_xml_samples/2.toyxml" target="_top">../../example/qi/mini_xml_samples/2.toyxml</a>,
71          and <a href="../../../../../example/qi/mini_xml_samples/3.toyxml" target="_top">../../example/qi/mini_xml_samples/3.toyxml</a>
72          for testing purposes. The example <a href="../../../../../example/qi/mini_xml_samples/4.toyxml" target="_top">../../example/qi/mini_xml_samples/4.toyxml</a>
73          has an error in it.
74        </p>
75<h6>
76<a name="spirit.qi.tutorials.mini_xml___asts_.h0"></a>
77          <span class="phrase"><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
78          Cut</a>
79        </h6>
80<p>
81          Without further delay, here's the first version of the XML grammar:
82        </p>
83<p>
84</p>
85<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">&gt;</span>
86<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">&lt;</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">&gt;</span>
87<span class="special">{</span>
88    <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>
89    <span class="special">{</span>
90        <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span>
91        <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span>
92        <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
93        <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">string</span><span class="special">;</span>
94        <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>
95
96        <span class="keyword">using</span> <span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">at_c</span><span class="special">;</span>
97        <span class="keyword">using</span> <span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">push_back</span><span class="special">;</span>
98
99        <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">'&lt;'</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>
100        <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>
101
102        <span class="identifier">start_tag</span> <span class="special">=</span>
103                <span class="char">'&lt;'</span>
104            <span class="special">&gt;&gt;</span>  <span class="special">!</span><span class="identifier">lit</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span>
105            <span class="special">&gt;&gt;</span>  <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'&gt;'</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>
106            <span class="special">&gt;&gt;</span>  <span class="char">'&gt;'</span>
107        <span class="special">;</span>
108
109        <span class="identifier">end_tag</span> <span class="special">=</span>
110                <span class="string">"&lt;/"</span>
111            <span class="special">&gt;&gt;</span>  <span class="identifier">lit</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span>
112            <span class="special">&gt;&gt;</span>  <span class="char">'&gt;'</span>
113        <span class="special">;</span>
114
115        <span class="identifier">xml</span> <span class="special">=</span>
116                <span class="identifier">start_tag</span>                   <span class="special">[</span><span class="identifier">at_c</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span>
117            <span class="special">&gt;&gt;</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">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">),</span> <span class="identifier">_1</span><span class="special">)]</span>
118            <span class="special">&gt;&gt;</span>  <span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">at_c</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">))</span>
119        <span class="special">;</span>
120    <span class="special">}</span>
121
122    <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">xml</span><span class="special">;</span>
123    <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">node</span><span class="special">;</span>
124    <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">text</span><span class="special">;</span>
125    <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">start_tag</span><span class="special">;</span>
126    <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">end_tag</span><span class="special">;</span>
127<span class="special">};</span>
128</pre>
129<p>
130        </p>
131<p>
132          Going bottom up, let's examine the <code class="computeroutput"><span class="identifier">text</span></code>
133          rule:
134        </p>
135<pre class="programlisting"><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">text</span><span class="special">;</span>
136</pre>
137<p>
138          and its definition:
139        </p>
140<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">'&lt;'</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>
141</pre>
142<p>
143          The semantic action collects the chars and appends them (via +=) to the
144          <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> attribute of the rule (represented
145          by the placeholder <code class="computeroutput"><span class="identifier">_val</span></code>).
146        </p>
147<h6>
148<a name="spirit.qi.tutorials.mini_xml___asts_.h1"></a>
149          <span class="phrase"><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>
150        </h6>
151<pre class="programlisting"><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">node</span><span class="special">;</span>
152</pre>
153<p>
154          and its definition:
155        </p>
156<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>
157</pre>
158<p>
159          We'll see a <code class="computeroutput"><span class="identifier">mini_xml_node</span></code>
160          structure later. Looking at the rule definition, we see some alternation
161          going on here. An xml <code class="computeroutput"><span class="identifier">node</span></code>
162          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...
163        </p>
164<pre class="programlisting"><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">start_tag</span><span class="special">;</span>
165</pre>
166<p>
167          Again, with an attribute of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
168          Then, it's definition:
169        </p>
170<pre class="programlisting"><span class="identifier">start_tag</span> <span class="special">=</span>
171        <span class="char">'&lt;'</span>
172    <span class="special">&gt;&gt;</span>  <span class="special">!</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span>
173    <span class="special">&gt;&gt;</span>  <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'&gt;'</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>
174    <span class="special">&gt;&gt;</span>  <span class="char">'&gt;'</span>
175<span class="special">;</span>
176</pre>
177<h6>
178<a name="spirit.qi.tutorials.mini_xml___asts_.h2"></a>
179          <span class="phrase"><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>
180        </h6>
181<p>
182          <code class="computeroutput"><span class="identifier">start_tag</span></code> is similar to
183          the <code class="computeroutput"><span class="identifier">text</span></code> rule apart from
184          the added <code class="computeroutput"><span class="char">'&lt;'</span></code> and <code class="computeroutput"><span class="char">'&gt;'</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
185          is a "Not Predicate":
186        </p>
187<pre class="programlisting"><span class="special">!</span><span class="identifier">p</span>
188</pre>
189<p>
190          It will try the parser, <code class="computeroutput"><span class="identifier">p</span></code>.
191          If it is successful, fail; otherwise, pass. In other words, it negates
192          the result of <code class="computeroutput"><span class="identifier">p</span></code>. Like the
193          <code class="computeroutput"><span class="identifier">eps</span></code>, it does not consume
194          any input though. It will always rewind the iterator position to where
195          it was upon entry. So, the expression:
196        </p>
197<pre class="programlisting"><span class="special">!</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span>
198</pre>
199<p>
200          basically says: we should not have a <code class="computeroutput"><span class="char">'/'</span></code>
201          at this point.
202        </p>
203<h6>
204<a name="spirit.qi.tutorials.mini_xml___asts_.h3"></a>
205          <span class="phrase"><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
206          Attribute</a>
207        </h6>
208<p>
209          The <code class="computeroutput"><span class="identifier">end_tag</span></code>:
210        </p>
211<pre class="programlisting"><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">end_tag</span><span class="special">;</span>
212</pre>
213<p>
214          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>.
215          The <code class="computeroutput"><span class="identifier">end_tag</span></code> does not have
216          a synthesized attribute. Let's see its definition:
217        </p>
218<pre class="programlisting"><span class="identifier">end_tag</span> <span class="special">=</span>
219        <span class="string">"&lt;/"</span>
220    <span class="special">&gt;&gt;</span>  <span class="identifier">lit</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span>
221    <span class="special">&gt;&gt;</span>  <span class="char">'&gt;'</span>
222<span class="special">;</span>
223</pre>
224<p>
225          <code class="computeroutput"><span class="identifier">_r1</span></code> is yet another <a href="../../../../../../../libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a> placeholder
226          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>,
227          etc. if you have more).
228        </p>
229<h6>
230<a name="spirit.qi.tutorials.mini_xml___asts_.h4"></a>
231          <span class="phrase"><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
232          Lazy Lit</a>
233        </h6>
234<p>
235          Check out how we used <code class="computeroutput"><span class="identifier">lit</span></code>
236          here, this time, not with a literal string, but with the value of the first
237          inherited attribute, which is specified as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
238          in our rule declaration.
239        </p>
240<p>
241          Finally, our <code class="computeroutput"><span class="identifier">xml</span></code> rule:
242        </p>
243<pre class="programlisting"><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">xml</span><span class="special">;</span>
244</pre>
245<p>
246          <code class="computeroutput"><span class="identifier">mini_xml</span></code> is our attribute
247          here. We'll see later what it is. Let's see its definition:
248        </p>
249<pre class="programlisting"><span class="identifier">xml</span> <span class="special">=</span>
250        <span class="identifier">start_tag</span>                   <span class="special">[</span><span class="identifier">at_c</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span>
251    <span class="special">&gt;&gt;</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">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">),</span> <span class="identifier">_1</span><span class="special">)]</span>
252    <span class="special">&gt;&gt;</span>  <span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">at_c</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">))</span>
253<span class="special">;</span>
254</pre>
255<p>
256          Those who know <a href="../../../../../../../libs/fusion/doc/html/index.html" target="_top">Boost.Fusion</a>
257          now will notice <code class="computeroutput"><span class="identifier">at_c</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;</span></code> and
258          <code class="computeroutput"><span class="identifier">at_c</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;</span></code>. This
259          gives us a hint that <code class="computeroutput"><span class="identifier">mini_xml</span></code>
260          is a sort of a tuple - a fusion sequence. <code class="computeroutput"><span class="identifier">at_c</span><span class="special">&lt;</span><span class="identifier">N</span><span class="special">&gt;</span></code> here is a lazy version of the tuple
261          accessors, provided by <a href="../../../../../../../libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a>.
262        </p>
263<h6>
264<a name="spirit.qi.tutorials.mini_xml___asts_.h5"></a>
265          <span class="phrase"><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
266          all works</a>
267        </h6>
268<p>
269          So, what's happening?
270        </p>
271<div class="orderedlist"><ol class="orderedlist" type="1">
272<li class="listitem">
273              Upon parsing <code class="computeroutput"><span class="identifier">start_tag</span></code>,
274              the parsed start-tag string is placed in <code class="computeroutput"><span class="identifier">at_c</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">)</span></code>.
275            </li>
276<li class="listitem">
277              Then we parse zero or more <code class="computeroutput"><span class="identifier">node</span></code>s.
278              At each step, we <code class="computeroutput"><span class="identifier">push_back</span></code>
279              the result into <code class="computeroutput"><span class="identifier">at_c</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">)</span></code>.
280            </li>
281<li class="listitem">
282              Finally, we parse the <code class="computeroutput"><span class="identifier">end_tag</span></code>
283              giving it an inherited attribute: <code class="computeroutput"><span class="identifier">at_c</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">)</span></code>. This is the string we obtained from
284              the <code class="computeroutput"><span class="identifier">start_tag</span></code>. Investigate
285              <code class="computeroutput"><span class="identifier">end_tag</span></code> above. It will
286              fail to parse if it gets something different from what we got from
287              the <code class="computeroutput"><span class="identifier">start_tag</span></code>. This
288              ensures that our tags are balanced.
289            </li>
290</ol></div>
291<p>
292          To give the last item some more light, what happens is this:
293        </p>
294<pre class="programlisting"><span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">at_c</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">))</span>
295</pre>
296<p>
297          calls:
298        </p>
299<pre class="programlisting"><span class="identifier">end_tag</span> <span class="special">=</span>
300        <span class="string">"&lt;/"</span>
301    <span class="special">&gt;&gt;</span>  <span class="identifier">lit</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span>
302    <span class="special">&gt;&gt;</span>  <span class="char">'&gt;'</span>
303<span class="special">;</span>
304</pre>
305<p>
306          passing in <code class="computeroutput"><span class="identifier">at_c</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">)</span></code>, the string from start tag. This is referred
307          to in the <code class="computeroutput"><span class="identifier">end_tag</span></code> body
308          as <code class="computeroutput"><span class="identifier">_r1</span></code>.
309        </p>
310<h6>
311<a name="spirit.qi.tutorials.mini_xml___asts_.h6"></a>
312          <span class="phrase"><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>
313        </h6>
314<p>
315          Let's see our structures. It will definitely be hierarchical: xml is hierarchical.
316          It will also be recursive: xml is recursive.
317        </p>
318<p>
319</p>
320<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">mini_xml</span><span class="special">;</span>
321
322<span class="keyword">typedef</span>
323    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span>
324        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">recursive_wrapper</span><span class="special">&lt;</span><span class="identifier">mini_xml</span><span class="special">&gt;</span>
325      <span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span>
326    <span class="special">&gt;</span>
327<span class="identifier">mini_xml_node</span><span class="special">;</span>
328
329<span class="keyword">struct</span> <span class="identifier">mini_xml</span>
330<span class="special">{</span>
331    <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>
332    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">mini_xml_node</span><span class="special">&gt;</span> <span class="identifier">children</span><span class="special">;</span>        <span class="comment">// children</span>
333<span class="special">};</span>
334</pre>
335<p>
336        </p>
337<h6>
338<a name="spirit.qi.tutorials.mini_xml___asts_.h7"></a>
339          <span class="phrase"><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
340          Alternates and Variants</a>
341        </h6>
342<p>
343          So that's what a <code class="computeroutput"><span class="identifier">mini_xml_node</span></code>
344          looks like. We had a hint that it is either a <code class="computeroutput"><span class="identifier">string</span></code>
345          or a <code class="computeroutput"><span class="identifier">mini_xml</span></code>. For this,
346          we use <a href="http://www.boost.org/doc/html/variant.html" target="_top">Boost.Variant</a>.
347          <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
348          structure.
349        </p>
350<p>
351          Yep, you got that right: the attribute of an alternate:
352        </p>
353<pre class="programlisting"><span class="identifier">a</span> <span class="special">|</span> <span class="identifier">b</span>
354</pre>
355<p>
356          is a
357        </p>
358<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">&gt;</span>
359</pre>
360<p>
361          where <code class="computeroutput"><span class="identifier">A</span></code> is the attribute
362          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>.
363        </p>
364<h6>
365<a name="spirit.qi.tutorials.mini_xml___asts_.h8"></a>
366          <span class="phrase"><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
367          structs again</a>
368        </h6>
369<p>
370          <code class="computeroutput"><span class="identifier">mini_xml</span></code> is no brainier.
371          It is a plain ol' struct. But as we've seen in our employee example, we
372          can adapt that to be a <a href="../../../../../../../libs/fusion/doc/html/index.html" target="_top">Boost.Fusion</a>
373          sequence:
374        </p>
375<p>
376</p>
377<pre class="programlisting"><span class="identifier">BOOST_FUSION_ADAPT_STRUCT</span><span class="special">(</span>
378    <span class="identifier">client</span><span class="special">::</span><span class="identifier">mini_xml</span><span class="special">,</span>
379    <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>
380    <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">client</span><span class="special">::</span><span class="identifier">mini_xml_node</span><span class="special">&gt;,</span> <span class="identifier">children</span><span class="special">)</span>
381<span class="special">)</span>
382</pre>
383<p>
384        </p>
385<h6>
386<a name="spirit.qi.tutorials.mini_xml___asts_.h9"></a>
387          <span class="phrase"><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>
388        </h6>
389<p>
390          Here's another version. The AST structure remains the same, but this time,
391          you'll see that we make use of auto-rules making the grammar semantic-action-less.
392          Here it is:
393        </p>
394<p>
395</p>
396<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">&gt;</span>
397<span class="keyword">struct</span> <span class="identifier">mini_xml_grammar</span>
398  <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">grammar</span><span class="special">&lt;</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">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;,</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">&gt;</span>
399<span class="special">{</span>
400    <span class="identifier">mini_xml_grammar</span><span class="special">()</span>
401      <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>
402    <span class="special">{</span>
403        <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span>
404        <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span>
405        <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
406        <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">string</span><span class="special">;</span>
407        <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>
408
409        <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">'&lt;'</span><span class="special">)];</span>
410        <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>
411
412        <span class="identifier">start_tag</span> <span class="special">%=</span>
413                <span class="char">'&lt;'</span>
414            <span class="special">&gt;&gt;</span>  <span class="special">!</span><span class="identifier">lit</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span>
415            <span class="special">&gt;&gt;</span>  <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'&gt;'</span><span class="special">)]</span>
416            <span class="special">&gt;&gt;</span>  <span class="char">'&gt;'</span>
417        <span class="special">;</span>
418
419        <span class="identifier">end_tag</span> <span class="special">=</span>
420                <span class="string">"&lt;/"</span>
421            <span class="special">&gt;&gt;</span>  <span class="identifier">lit</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span>
422            <span class="special">&gt;&gt;</span>  <span class="char">'&gt;'</span>
423        <span class="special">;</span>
424
425        <span class="identifier">xml</span> <span class="special">%=</span>
426                <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>
427            <span class="special">&gt;&gt;</span>  <span class="special">*</span><span class="identifier">node</span>
428            <span class="special">&gt;&gt;</span>  <span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">_a</span><span class="special">)</span>
429        <span class="special">;</span>
430    <span class="special">}</span>
431
432    <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</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">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;,</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">&gt;</span> <span class="identifier">xml</span><span class="special">;</span>
433    <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">node</span><span class="special">;</span>
434    <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">text</span><span class="special">;</span>
435    <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">start_tag</span><span class="special">;</span>
436    <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">end_tag</span><span class="special">;</span>
437<span class="special">};</span>
438</pre>
439<p>
440        </p>
441<p>
442          This one shouldn't be any more difficult to understand after going through
443          the first xml parser example. The rules are almost the same, except that,
444          we got rid of semantic actions and used auto-rules (see the employee example
445          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:
446        </p>
447<h6>
448<a name="spirit.qi.tutorials.mini_xml___asts_.h10"></a>
449          <span class="phrase"><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>
450        </h6>
451<pre class="programlisting"><span class="identifier">rule</span><span class="special">&lt;</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">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;,</span> <span class="identifier">space_type</span><span class="special">&gt;</span> <span class="identifier">xml</span><span class="special">;</span>
452</pre>
453<p>
454          Wow, we have four template parameters now. What's that <code class="computeroutput"><span class="identifier">locals</span></code>
455          guy doing there? Well, it declares that the rule <code class="computeroutput"><span class="identifier">xml</span></code>
456          will have one local variable: a <code class="computeroutput"><span class="identifier">string</span></code>.
457          Let's see how this is used in action:
458        </p>
459<pre class="programlisting"><span class="identifier">xml</span> <span class="special">%=</span>
460        <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>
461    <span class="special">&gt;&gt;</span>  <span class="special">*</span><span class="identifier">node</span>
462    <span class="special">&gt;&gt;</span>  <span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">_a</span><span class="special">)</span>
463<span class="special">;</span>
464</pre>
465<div class="orderedlist"><ol class="orderedlist" type="1">
466<li class="listitem">
467              Upon parsing <code class="computeroutput"><span class="identifier">start_tag</span></code>,
468              the parsed start-tag string is placed in the local variable specified
469              by (yet another) <a href="../../../../../../../libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a>
470              placeholder: <code class="computeroutput"><span class="identifier">_a</span></code>. We
471              have only one local variable. If we had more, these are designated
472              by <code class="computeroutput"><span class="identifier">_b</span></code>..<code class="computeroutput"><span class="identifier">_z</span></code>.
473            </li>
474<li class="listitem">
475              Then we parse zero or more <code class="computeroutput"><span class="identifier">node</span></code>s.
476            </li>
477<li class="listitem">
478              Finally, we parse the <code class="computeroutput"><span class="identifier">end_tag</span></code>
479              giving it an inherited attribute: <code class="computeroutput"><span class="identifier">_a</span></code>,
480              our local variable.
481            </li>
482</ol></div>
483<p>
484          There are no actions involved in stuffing data into our <code class="computeroutput"><span class="identifier">xml</span></code>
485          attribute. It's all taken care of thanks to the auto-rule.
486        </p>
487</div>
488<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
489<td align="left"></td>
490<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p>
491        Distributed under the Boost Software License, Version 1.0. (See accompanying
492        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>)
493      </p>
494</div></td>
495</tr></table>
496<hr>
497<div class="spirit-nav">
498<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>
499</div>
500</body>
501</html>
502