1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Employee - Parsing into structs</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 X3 3.0.4"> 8<link rel="up" href="../tutorials.html" title="Tutorials"> 9<link rel="prev" href="roman.html" title="Roman Numerals"> 10<link rel="next" href="minimal.html" title="X3 Program Structure"> 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="roman.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="minimal.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h3 class="title"> 27<a name="spirit_x3.tutorials.employee"></a><a class="link" href="employee.html" title="Employee - Parsing into structs">Employee - Parsing into 28 structs</a> 29</h3></div></div></div> 30<p> 31 It's a common question in the <a href="https://lists.sourceforge.net/lists/listinfo/spirit-general" target="_top">Spirit 32 Mailing List</a>: How do I parse and place the results into a C++ struct? 33 Of course, at this point, you already know various ways to do it, using semantic 34 actions. There are many ways to skin a cat. Spirit X3, being fully attributed, 35 makes it even easier. The next example demonstrates some features of Spirit 36 X3 that make this easy. In the process, you'll learn about: 37 </p> 38<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 39<li class="listitem"> 40 More about attributes 41 </li> 42<li class="listitem"> 43 Auto rules 44 </li> 45<li class="listitem"> 46 Some more built-in parsers 47 </li> 48<li class="listitem"> 49 Directives 50 </li> 51</ul></div> 52<p> 53 First, let's create a struct representing an employee: 54 </p> 55<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">client</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">ast</span> 56<span class="special">{</span> 57 <span class="keyword">struct</span> <span class="identifier">employee</span> 58 <span class="special">{</span> 59 <span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span> 60 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">forename</span><span class="special">;</span> 61 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">surname</span><span class="special">;</span> 62 <span class="keyword">double</span> <span class="identifier">salary</span><span class="special">;</span> 63 <span class="special">};</span> 64<span class="special">}}</span> 65</pre> 66<p> 67 Then, we need to tell <a href="../../../../../../../libs/fusion/doc/html/index.html" target="_top">Boost.Fusion</a> 68 about our employee struct to make it a first-class fusion citizen that the 69 grammar can utilize. If you don't know fusion yet, it is a <a href="http://www.boost.org/" target="_top">Boost</a> 70 library for working with heterogeneous collections of data, commonly referred 71 to as tuples. Spirit uses fusion extensively as part of its infrastructure. 72 </p> 73<p> 74 In fusion's view, a struct is just a form of a tuple. You can adapt any struct 75 to be a fully conforming fusion tuple: 76 </p> 77<pre class="programlisting"><span class="identifier">BOOST_FUSION_ADAPT_STRUCT</span><span class="special">(</span> 78 <span class="identifier">client</span><span class="special">::</span><span class="identifier">ast</span><span class="special">::</span><span class="identifier">employee</span><span class="special">,</span> 79 <span class="identifier">age</span><span class="special">,</span> <span class="identifier">forename</span><span class="special">,</span> <span class="identifier">surname</span><span class="special">,</span> <span class="identifier">salary</span> 80<span class="special">)</span> 81</pre> 82<p> 83 Now we'll write a parser for our employee. Inputs will be of the form: 84 </p> 85<pre class="programlisting"><span class="identifier">employee</span><span class="special">{</span> <span class="identifier">age</span><span class="special">,</span> <span class="string">"forename"</span><span class="special">,</span> <span class="string">"surname"</span><span class="special">,</span> <span class="identifier">salary</span> <span class="special">}</span> 86</pre> 87<p> 88 <a name="__tutorial_employee_parser__"></a>Here goes: 89 </p> 90<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">parser</span> 91<span class="special">{</span> 92 <span class="keyword">namespace</span> <span class="identifier">x3</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">x3</span><span class="special">;</span> 93 <span class="keyword">namespace</span> <span class="identifier">ascii</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">x3</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">;</span> 94 95 <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span> 96 <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span> 97 <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span> 98 <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span> 99 <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> 100 101 <span class="identifier">x3</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">employee</span><span class="special">,</span> <span class="identifier">ast</span><span class="special">::</span><span class="identifier">employee</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">employee</span> <span class="special">=</span> <span class="string">"employee"</span><span class="special">;</span> 102 103 <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">quoted_string</span> <span class="special">=</span> <span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">>></span> <span class="char">'"'</span><span class="special">];</span> 104 105 <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">employee_def</span> <span class="special">=</span> 106 <span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span> 107 <span class="special">>></span> <span class="char">'{'</span> 108 <span class="special">>></span> <span class="identifier">int_</span> <span class="special">>></span> <span class="char">','</span> 109 <span class="special">>></span> <span class="identifier">quoted_string</span> <span class="special">>></span> <span class="char">','</span> 110 <span class="special">>></span> <span class="identifier">quoted_string</span> <span class="special">>></span> <span class="char">','</span> 111 <span class="special">>></span> <span class="identifier">double_</span> 112 <span class="special">>></span> <span class="char">'}'</span> 113 <span class="special">;</span> 114 115 <span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">employee</span><span class="special">);</span> 116<span class="special">}</span> 117</pre> 118<p> 119 The full cpp file for this example can be found here: <a href="../../../../../example/x3/employee.cpp" target="_top">employee.cpp</a> 120 </p> 121<p> 122 Let's walk through this one step at a time (not necessarily from top to bottom). 123 </p> 124<h5> 125<a name="spirit_x3.tutorials.employee.h0"></a> 126 <span class="phrase"><a name="spirit_x3.tutorials.employee.rule_declaration"></a></span><a class="link" href="employee.html#spirit_x3.tutorials.employee.rule_declaration">Rule 127 Declaration</a> 128 </h5> 129<p> 130 We are assuming that you already know about rules. We introduced rules in 131 the previous <a class="link" href="roman.html" title="Roman Numerals">Roman Numerals example</a>. 132 Please go back and review the previous tutorial if you have to. 133 </p> 134<pre class="programlisting"><span class="identifier">x3</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">employee</span><span class="special">,</span> <span class="identifier">ast</span><span class="special">::</span><span class="identifier">employee</span><span class="special">></span> <span class="identifier">employee</span> <span class="special">=</span> <span class="string">"employee"</span><span class="special">;</span> 135</pre> 136<h5> 137<a name="spirit_x3.tutorials.employee.h1"></a> 138 <span class="phrase"><a name="spirit_x3.tutorials.employee.lexeme"></a></span><a class="link" href="employee.html#spirit_x3.tutorials.employee.lexeme">Lexeme</a> 139 </h5> 140<pre class="programlisting"><span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">>></span> <span class="char">'"'</span><span class="special">];</span> 141</pre> 142<p> 143 <code class="computeroutput"><span class="identifier">lexeme</span></code> inhibits space skipping 144 from the open brace to the closing brace. The expression parses quoted strings. 145 </p> 146<pre class="programlisting"><span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> 147</pre> 148<p> 149 parses one or more chars, except the double quote. It stops when it sees 150 a double quote. 151 </p> 152<h5> 153<a name="spirit_x3.tutorials.employee.h2"></a> 154 <span class="phrase"><a name="spirit_x3.tutorials.employee.difference"></a></span><a class="link" href="employee.html#spirit_x3.tutorials.employee.difference">Difference</a> 155 </h5> 156<p> 157 The expression: 158 </p> 159<pre class="programlisting"><span class="identifier">a</span> <span class="special">-</span> <span class="identifier">b</span> 160</pre> 161<p> 162 parses <code class="computeroutput"><span class="identifier">a</span></code> but not <code class="computeroutput"><span class="identifier">b</span></code>. Its attribute is just <code class="computeroutput"><span class="identifier">A</span></code>; the attribute of <code class="computeroutput"><span class="identifier">a</span></code>. 163 <code class="computeroutput"><span class="identifier">b</span></code>'s attribute is ignored. 164 Hence, the attribute of: 165 </p> 166<pre class="programlisting"><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span> 167</pre> 168<p> 169 is just <code class="computeroutput"><span class="keyword">char</span></code>. 170 </p> 171<h5> 172<a name="spirit_x3.tutorials.employee.h3"></a> 173 <span class="phrase"><a name="spirit_x3.tutorials.employee.plus"></a></span><a class="link" href="employee.html#spirit_x3.tutorials.employee.plus">Plus</a> 174 </h5> 175<pre class="programlisting"><span class="special">+</span><span class="identifier">a</span> 176</pre> 177<p> 178 is similar to Kleene star. Rather than match everything, <code class="computeroutput"><span class="special">+</span><span class="identifier">a</span></code> matches one or more. Like it's related 179 function, the Kleene star, its attribute is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span></code> 180 where <code class="computeroutput"><span class="identifier">A</span></code> is the attribute 181 of <code class="computeroutput"><span class="identifier">a</span></code>. So, putting all these 182 together, the attribute of 183 </p> 184<pre class="programlisting"><span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> 185</pre> 186<p> 187 is then: 188 </p> 189<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> 190</pre> 191<h5> 192<a name="spirit_x3.tutorials.employee.h4"></a> 193 <span class="phrase"><a name="spirit_x3.tutorials.employee.sequence_attribute"></a></span><a class="link" href="employee.html#spirit_x3.tutorials.employee.sequence_attribute">Sequence 194 Attribute</a> 195 </h5> 196<p> 197 Now what's the attribute of 198 </p> 199<pre class="programlisting"><span class="char">'"'</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">>></span> <span class="char">'"'</span> 200</pre> 201<p> 202 ? 203 </p> 204<p> 205 Well, typically, the attribute of: 206 </p> 207<pre class="programlisting"><span class="identifier">a</span> <span class="special">>></span> <span class="identifier">b</span> <span class="special">>></span> <span class="identifier">c</span> 208</pre> 209<p> 210 is: 211 </p> 212<pre class="programlisting"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">,</span> <span class="identifier">C</span><span class="special">></span> 213</pre> 214<p> 215 where <code class="computeroutput"><span class="identifier">A</span></code> is the attribute 216 of <code class="computeroutput"><span class="identifier">a</span></code>, <code class="computeroutput"><span class="identifier">B</span></code> 217 is the attribute of <code class="computeroutput"><span class="identifier">b</span></code> and 218 <code class="computeroutput"><span class="identifier">C</span></code> is the attribute of <code class="computeroutput"><span class="identifier">c</span></code>. What is <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span></code>? 219 - a tuple. 220 </p> 221<div class="note"><table border="0" summary="Note"> 222<tr> 223<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td> 224<th align="left">Note</th> 225</tr> 226<tr><td align="left" valign="top"><p> 227 If you don't know what I am talking about, see: <a href="http://tinyurl.com/6xun4j" target="_top">Fusion 228 Vector</a>. It might be a good idea to have a look into <a href="../../../../../../../libs/fusion/doc/html/index.html" target="_top">Boost.Fusion</a> 229 at this point. You'll definitely see more of it in the coming pages. 230 </p></td></tr> 231</table></div> 232<h5> 233<a name="spirit_x3.tutorials.employee.h5"></a> 234 <span class="phrase"><a name="spirit_x3.tutorials.employee.attribute_collapsing"></a></span><a class="link" href="employee.html#spirit_x3.tutorials.employee.attribute_collapsing">Attribute 235 Collapsing</a> 236 </h5> 237<p> 238 Some parsers, especially those very little literal parsers you see, like 239 <code class="computeroutput"><span class="char">'"'</span></code>, do not have attributes. 240 </p> 241<p> 242 Nodes without attributes are disregarded. In a sequence, like above, all 243 nodes with no attributes are filtered out of the <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span></code>. 244 So, since <code class="computeroutput"><span class="char">'"'</span></code> has no attribute, 245 and <code class="computeroutput"><span class="special">+(</span><span class="identifier">char_</span> 246 <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span></code> has a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span></code> 247 attribute, the whole expression's attribute should have been: 248 </p> 249<pre class="programlisting"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> <span class="special">></span> 250</pre> 251<p> 252 But wait, there's one more collapsing rule: If the attribute is followed 253 by a single element <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span></code>, 254 The element is stripped naked from its container. To make a long story short, 255 the attribute of the expression: 256 </p> 257<pre class="programlisting"><span class="char">'"'</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">>></span> <span class="char">'"'</span> 258</pre> 259<p> 260 is: 261 </p> 262<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> 263</pre> 264<h5> 265<a name="spirit_x3.tutorials.employee.h6"></a> 266 <span class="phrase"><a name="spirit_x3.tutorials.employee.rule_definition"></a></span><a class="link" href="employee.html#spirit_x3.tutorials.employee.rule_definition">Rule 267 Definition</a> 268 </h5> 269<p> 270 Again, we are assuming that you already know about rules and rule definitions. 271 We introduced rules in the previous <a class="link" href="roman.html" title="Roman Numerals">Roman 272 Numerals example</a>. Please go back and review the previous tutorial 273 if you have to. 274 </p> 275<pre class="programlisting"><span class="identifier">employee</span> <span class="special">=</span> 276 <span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span> 277 <span class="special">>></span> <span class="char">'{'</span> 278 <span class="special">>></span> <span class="identifier">int_</span> <span class="special">>></span> <span class="char">','</span> 279 <span class="special">>></span> <span class="identifier">quoted_string</span> <span class="special">>></span> <span class="char">','</span> 280 <span class="special">>></span> <span class="identifier">quoted_string</span> <span class="special">>></span> <span class="char">','</span> 281 <span class="special">>></span> <span class="identifier">double_</span> 282 <span class="special">>></span> <span class="char">'}'</span> 283 <span class="special">;</span> 284 285<span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">employee</span><span class="special">);</span> 286</pre> 287<p> 288 Applying our collapsing rules above, the RHS has an attribute of: 289 </p> 290<pre class="programlisting"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">></span> 291</pre> 292<p> 293 These nodes do not have an attribute: 294 </p> 295<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 296<li class="listitem"> 297 <code class="computeroutput"><span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span></code> 298 </li> 299<li class="listitem"> 300 <code class="computeroutput"><span class="char">'{'</span></code> 301 </li> 302<li class="listitem"> 303 <code class="computeroutput"><span class="char">','</span></code> 304 </li> 305<li class="listitem"> 306 <code class="computeroutput"><span class="char">'}'</span></code> 307 </li> 308</ul></div> 309<div class="note"><table border="0" summary="Note"> 310<tr> 311<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td> 312<th align="left">Note</th> 313</tr> 314<tr><td align="left" valign="top"><p> 315 In case you are wondering, <code class="computeroutput"><span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span></code> is the same as "employee". We 316 had to wrap it inside <code class="computeroutput"><span class="identifier">lit</span></code> 317 because immediately after it is <code class="computeroutput"><span class="special">>></span> 318 <span class="char">'{'</span></code>. You can't right-shift a <code class="computeroutput"><span class="keyword">char</span><span class="special">[]</span></code> and 319 a <code class="computeroutput"><span class="keyword">char</span></code> - you know, C++ syntax 320 rules. 321 </p></td></tr> 322</table></div> 323<p> 324 Recall that the attribute of <code class="computeroutput"><span class="identifier">parser</span><span class="special">::</span><span class="identifier">employee</span></code> 325 is the <code class="computeroutput"><span class="identifier">ast</span><span class="special">::</span><span class="identifier">employee</span></code> struct. 326 </p> 327<p> 328 Now everything is clear, right? The <code class="computeroutput"><span class="keyword">struct</span> 329 <span class="identifier">employee</span></code> <span class="bold"><strong>IS</strong></span> 330 compatible with <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">></span></code>. 331 So, the RHS of <code class="computeroutput"><span class="identifier">start</span></code> uses 332 start's attribute (a <code class="computeroutput"><span class="keyword">struct</span> <span class="identifier">employee</span></code>) in-situ when it does its work. 333 </p> 334</div> 335<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 336<td align="left"></td> 337<td align="right"><div class="copyright-footer">Copyright © 2001-2018 Joel de Guzman, 338 Hartmut Kaiser<p> 339 Distributed under the Boost Software License, Version 1.0. (See accompanying 340 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>) 341 </p> 342</div></td> 343</tr></table> 344<hr> 345<div class="spirit-nav"> 346<a accesskey="p" href="roman.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="minimal.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> 347</div> 348</body> 349</html> 350