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"><</span><span class="identifier">employee</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></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"><</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> 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">'<'</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">'<'</span> 104 <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> 105 <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> 106 <span class="special">>></span> <span class="char">'>'</span> 107 <span class="special">;</span> 108 109 <span class="identifier">end_tag</span> <span class="special">=</span> 110 <span class="string">"</"</span> 111 <span class="special">>></span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span> 112 <span class="special">>></span> <span class="char">'>'</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"><</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> 117 <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> 118 <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> 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"><</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> 123 <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> 124 <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> 125 <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> 126 <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> 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"><</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> 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">'<'</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"><</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> 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"><</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> 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">'<'</span> 172 <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> 173 <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> 174 <span class="special">>></span> <span class="char">'>'</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">'<'</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 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"><</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> 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">"</"</span> 220 <span class="special">>></span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span> 221 <span class="special">>></span> <span class="char">'>'</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"><</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> 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"><</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> 251 <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> 252 <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> 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"><</span><span class="number">0</span><span class="special">></span></code> and 258 <code class="computeroutput"><span class="identifier">at_c</span><span class="special"><</span><span class="number">1</span><span class="special">></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"><</span><span class="identifier">N</span><span class="special">></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"><</span><span class="number">0</span><span class="special">>(</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"><</span><span class="number">1</span><span class="special">>(</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"><</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 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"><</span><span class="number">0</span><span class="special">>(</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">"</"</span> 301 <span class="special">>></span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span> 302 <span class="special">>></span> <span class="char">'>'</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"><</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 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"><</span> 324 <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> 325 <span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> 326 <span class="special">></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"><</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> 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"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">></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"><</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> 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"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></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"><</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> 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">'<'</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">'<'</span> 414 <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> 415 <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> 416 <span class="special">>></span> <span class="char">'>'</span> 417 <span class="special">;</span> 418 419 <span class="identifier">end_tag</span> <span class="special">=</span> 420 <span class="string">"</"</span> 421 <span class="special">>></span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span> 422 <span class="special">>></span> <span class="char">'>'</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">>></span> <span class="special">*</span><span class="identifier">node</span> 428 <span class="special">>></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"><</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> 433 <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> 434 <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> 435 <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> 436 <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> 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"><</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> 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">>></span> <span class="special">*</span><span class="identifier">node</span> 462 <span class="special">>></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