1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Warming up</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="quick_start.html" title="Quick Start"> 10<link rel="next" href="semantic_actions.html" title="Parser Semantic Actions"> 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="quick_start.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorials.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="semantic_actions.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h4 class="title"> 27<a name="spirit.qi.tutorials.warming_up"></a><a class="link" href="warming_up.html" title="Warming up">Warming up</a> 28</h4></div></div></div> 29<p> 30 We'll start by showing examples of parser expressions to give you a feel 31 on how to build parsers from the simplest parser, building up as we go. 32 When comparing EBNF to <a href="http://boost-spirit.com" target="_top">Spirit</a>, 33 the expressions may seem awkward at first. <a href="http://boost-spirit.com" target="_top">Spirit</a> 34 heavily uses operator overloading to accomplish its magic. 35 </p> 36<h6> 37<a name="spirit.qi.tutorials.warming_up.h0"></a> 38 <span class="phrase"><a name="spirit.qi.tutorials.warming_up.trivial_example__1_parsing_a_number"></a></span><a class="link" href="warming_up.html#spirit.qi.tutorials.warming_up.trivial_example__1_parsing_a_number">Trivial 39 Example #1 Parsing a number</a> 40 </h6> 41<p> 42 Create a parser that will parse a floating-point number. 43 </p> 44<pre class="programlisting"><span class="identifier">double_</span> 45</pre> 46<p> 47 (You've got to admit, that's trivial!) The above code actually generates 48 a Spirit floating point parser (a built-in parser). Spirit has many pre-defined 49 parsers and consistent naming conventions help you keep from going insane! 50 </p> 51<h6> 52<a name="spirit.qi.tutorials.warming_up.h1"></a> 53 <span class="phrase"><a name="spirit.qi.tutorials.warming_up.trivial_example__2_parsing_two_numbers"></a></span><a class="link" href="warming_up.html#spirit.qi.tutorials.warming_up.trivial_example__2_parsing_two_numbers">Trivial 54 Example #2 Parsing two numbers</a> 55 </h6> 56<p> 57 Create a parser that will accept a line consisting of two floating-point 58 numbers. 59 </p> 60<pre class="programlisting"><span class="identifier">double_</span> <span class="special">>></span> <span class="identifier">double_</span> 61</pre> 62<p> 63 Here you see the familiar floating-point numeric parser <code class="computeroutput"><span class="identifier">double_</span></code> 64 used twice, once for each number. What's that <code class="computeroutput"><span class="special">>></span></code> 65 operator doing in there? Well, they had to be separated by something, and 66 this was chosen as the "followed by" sequence operator. The above 67 program creates a parser from two simpler parsers, glueing them together 68 with the sequence operator. The result is a parser that is a composition 69 of smaller parsers. Whitespace between numbers can implicitly be consumed 70 depending on how the parser is invoked (see below). 71 </p> 72<div class="note"><table border="0" summary="Note"> 73<tr> 74<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> 75<th align="left">Note</th> 76</tr> 77<tr><td align="left" valign="top"><p> 78 When we combine parsers, we end up with a "bigger" parser, 79 but it's still a parser. Parsers can get bigger and bigger, nesting more 80 and more, but whenever you glue two parsers together, you end up with 81 one bigger parser. This is an important concept. 82 </p></td></tr> 83</table></div> 84<h6> 85<a name="spirit.qi.tutorials.warming_up.h2"></a> 86 <span class="phrase"><a name="spirit.qi.tutorials.warming_up.trivial_example__3_parsing_zero_or_more_numbers"></a></span><a class="link" href="warming_up.html#spirit.qi.tutorials.warming_up.trivial_example__3_parsing_zero_or_more_numbers">Trivial 87 Example #3 Parsing zero or more numbers</a> 88 </h6> 89<p> 90 Create a parser that will accept zero or more floating-point numbers. 91 </p> 92<pre class="programlisting"><span class="special">*</span><span class="identifier">double_</span> 93</pre> 94<p> 95 This is like a regular-expression Kleene Star, though the syntax might 96 look a bit odd for a C++ programmer not used to seeing the <code class="computeroutput"><span class="special">*</span></code> operator overloaded like this. Actually, 97 if you know regular expressions it may look odd too since the star is before 98 the expression it modifies. C'est la vie. Blame it on the fact that we 99 must work with the syntax rules of C++. 100 </p> 101<p> 102 Any expression that evaluates to a parser may be used with the Kleene Star. 103 Keep in mind that C++ operator precedence rules may require you to put 104 expressions in parentheses for complex expressions. The Kleene Star is 105 also known as a Kleene Closure, but we call it the Star in most places. 106 </p> 107<h6> 108<a name="spirit.qi.tutorials.warming_up.h3"></a> 109 <span class="phrase"><a name="spirit.qi.tutorials.warming_up.trivial_example__4_parsing_a_comma_delimited_list_of_numbers"></a></span><a class="link" href="warming_up.html#spirit.qi.tutorials.warming_up.trivial_example__4_parsing_a_comma_delimited_list_of_numbers">Trivial 110 Example #4 Parsing a comma-delimited list of numbers</a> 111 </h6> 112<p> 113 This example will create a parser that accepts a comma-delimited list of 114 numbers. 115 </p> 116<pre class="programlisting"><span class="identifier">double_</span> <span class="special">>></span> <span class="special">*(</span><span class="identifier">char_</span><span class="special">(</span><span class="char">','</span><span class="special">)</span> <span class="special">>></span> <span class="identifier">double_</span><span class="special">)</span> 117</pre> 118<p> 119 Notice <code class="computeroutput"><span class="identifier">char_</span><span class="special">(</span><span class="char">','</span><span class="special">)</span></code>. It is 120 a literal character parser that can recognize the comma <code class="computeroutput"><span class="char">','</span></code>. 121 In this case, the Kleene Star is modifying a more complex parser, namely, 122 the one generated by the expression: 123 </p> 124<pre class="programlisting"><span class="special">(</span><span class="identifier">char_</span><span class="special">(</span><span class="char">','</span><span class="special">)</span> <span class="special">>></span> <span class="identifier">double_</span><span class="special">)</span> 125</pre> 126<p> 127 Note that this is a case where the parentheses are necessary. The Kleene 128 star encloses the complete expression above. 129 </p> 130<h6> 131<a name="spirit.qi.tutorials.warming_up.h4"></a> 132 <span class="phrase"><a name="spirit.qi.tutorials.warming_up.let_s_parse_"></a></span><a class="link" href="warming_up.html#spirit.qi.tutorials.warming_up.let_s_parse_">Let's 133 Parse!</a> 134 </h6> 135<p> 136 We're done with defining the parser. So the next step is now invoking this 137 parser to do its work. There are a couple of ways to do this. For now, 138 we will use the <code class="computeroutput"><span class="identifier">phrase_parse</span></code> 139 function. One overload of this function accepts four arguments: 140 </p> 141<div class="orderedlist"><ol class="orderedlist" type="1"> 142<li class="listitem"> 143 An iterator pointing to the start of the input 144 </li> 145<li class="listitem"> 146 An iterator pointing to one past the end of the input 147 </li> 148<li class="listitem"> 149 The parser object 150 </li> 151<li class="listitem"> 152 Another parser called the skip parser 153 </li> 154</ol></div> 155<p> 156 In our example, we wish to skip spaces and tabs. Another parser named 157 <code class="computeroutput"><span class="identifier">space</span></code> is included in Spirit's 158 repertoire of predefined parsers. It is a very simple parser that simply 159 recognizes whitespace. We will use <code class="computeroutput"><span class="identifier">space</span></code> 160 as our skip parser. The skip parser is the one responsible for skipping 161 characters in between parser elements such as the <code class="computeroutput"><span class="identifier">double_</span></code> 162 and <code class="computeroutput"><span class="identifier">char_</span></code>. 163 </p> 164<p> 165 Ok, so now let's parse! 166 </p> 167<p> 168</p> 169<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> 170<span class="keyword">bool</span> <span class="identifier">parse_numbers</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">last</span><span class="special">)</span> 171<span class="special">{</span> 172 <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span> 173 <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">;</span> 174 <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space</span><span class="special">;</span> 175 176 <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">phrase_parse</span><span class="special">(</span> 177 <span class="identifier">first</span><span class="special">,</span> <a class="co" name="spirit.qi.tutorials.warming_up.c0" href="warming_up.html#spirit.qi.tutorials.warming_up.c1"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> 178 <span class="identifier">last</span><span class="special">,</span> <a class="co" name="spirit.qi.tutorials.warming_up.c2" href="warming_up.html#spirit.qi.tutorials.warming_up.c3"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> 179 <span class="identifier">double_</span> <span class="special">>></span> <span class="special">*(</span><span class="char">','</span> <span class="special">>></span> <span class="identifier">double_</span><span class="special">),</span> <a class="co" name="spirit.qi.tutorials.warming_up.c4" href="warming_up.html#spirit.qi.tutorials.warming_up.c5"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> 180 <span class="identifier">space</span> <a class="co" name="spirit.qi.tutorials.warming_up.c6" href="warming_up.html#spirit.qi.tutorials.warming_up.c7"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> 181 <span class="special">);</span> 182 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">)</span> <span class="comment">// fail if we did not get a full match</span> 183 <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span> 184 <span class="keyword">return</span> <span class="identifier">r</span><span class="special">;</span> 185<span class="special">}</span> 186</pre> 187<p> 188 </p> 189<div class="calloutlist"><table border="0" summary="Callout list"> 190<tr> 191<td width="5%" valign="top" align="left"><p><a name="spirit.qi.tutorials.warming_up.c1"></a><a href="#spirit.qi.tutorials.warming_up.c0"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td> 192<td valign="top" align="left"><p> 193 start iterator 194 </p></td> 195</tr> 196<tr> 197<td width="5%" valign="top" align="left"><p><a name="spirit.qi.tutorials.warming_up.c3"></a><a href="#spirit.qi.tutorials.warming_up.c2"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td> 198<td valign="top" align="left"><p> 199 end iterator 200 </p></td> 201</tr> 202<tr> 203<td width="5%" valign="top" align="left"><p><a name="spirit.qi.tutorials.warming_up.c5"></a><a href="#spirit.qi.tutorials.warming_up.c4"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td> 204<td valign="top" align="left"><p> 205 the parser 206 </p></td> 207</tr> 208<tr> 209<td width="5%" valign="top" align="left"><p><a name="spirit.qi.tutorials.warming_up.c7"></a><a href="#spirit.qi.tutorials.warming_up.c6"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td> 210<td valign="top" align="left"><p> 211 the skip-parser 212 </p></td> 213</tr> 214</table></div> 215<p> 216 The parse function returns <code class="computeroutput"><span class="keyword">true</span></code> 217 or <code class="computeroutput"><span class="keyword">false</span></code> depending on the 218 result of the parse. The first iterator is passed by reference. On a successful 219 parse, this iterator is repositioned to the rightmost position consumed 220 by the parser. If this becomes equal to <code class="computeroutput"><span class="identifier">last</span></code>, 221 then we have a full match. If not, then we have a partial match. A partial 222 match happens when the parser is only able to parse a portion of the input. 223 </p> 224<p> 225 Note that we inlined the parser directly in the call to parse. Upon calling 226 parse, the expression evaluates into a temporary, unnamed parser which 227 is passed into the parse() function, used, and then destroyed. 228 </p> 229<p> 230 Here, we opted to make the parser generic by making it a template, parameterized 231 by the iterator type. By doing so, it can take in data coming from any 232 STL conforming sequence as long as the iterators conform to a forward iterator. 233 </p> 234<p> 235 You can find the full cpp file here: <a href="../../../../../example/qi/num_list1.cpp" target="_top">../../example/qi/num_list1.cpp</a> 236 </p> 237<div class="note"><table border="0" summary="Note"> 238<tr> 239<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> 240<th align="left">Note</th> 241</tr> 242<tr><td align="left" valign="top"> 243<p> 244 <code class="computeroutput"><span class="keyword">char</span></code> and <code class="computeroutput"><span class="keyword">wchar_t</span></code> 245 operands 246 </p> 247<p> 248 The careful reader may notice that the parser expression has <code class="computeroutput"><span class="char">','</span></code> instead of <code class="computeroutput"><span class="identifier">char_</span><span class="special">(</span><span class="char">','</span><span class="special">)</span></code> 249 as the previous examples did. This is ok due to C++ syntax rules of conversion. 250 There are <code class="computeroutput"><span class="special">>></span></code> operators 251 that are overloaded to accept a <code class="computeroutput"><span class="keyword">char</span></code> 252 or <code class="computeroutput"><span class="keyword">wchar_t</span></code> argument on its 253 left or right (but not both). An operator may be overloaded if at least 254 one of its parameters is a user-defined type. In this case, the <code class="computeroutput"><span class="identifier">double_</span></code> is the 2nd argument to <code class="computeroutput"><span class="keyword">operator</span><span class="special">>></span></code>, 255 and so the proper overload of <code class="computeroutput"><span class="special">>></span></code> 256 is used, converting <code class="computeroutput"><span class="char">','</span></code> into 257 a character literal parser. 258 </p> 259<p> 260 The problem with omitting the <code class="computeroutput"><span class="identifier">char_</span></code> 261 should be obvious: <code class="computeroutput"><span class="char">'a'</span> <span class="special">>></span> 262 <span class="char">'b'</span></code> is not a spirit parser, it is 263 a numeric expression, right-shifting the ASCII (or another encoding) 264 value of <code class="computeroutput"><span class="char">'a'</span></code> by the ASCII value 265 of <code class="computeroutput"><span class="char">'b'</span></code>. However, both <code class="computeroutput"><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">)</span> <span class="special">>></span> 266 <span class="char">'b'</span></code> and <code class="computeroutput"><span class="char">'a'</span> 267 <span class="special">>></span> <span class="identifier">char_</span><span class="special">(</span><span class="char">'b'</span><span class="special">)</span></code> 268 are Spirit sequence parsers for the letter <code class="computeroutput"><span class="char">'a'</span></code> 269 followed by <code class="computeroutput"><span class="char">'b'</span></code>. You'll get 270 used to it, sooner or later. 271 </p> 272</td></tr> 273</table></div> 274<p> 275 Finally, take note that we test for a full match (i.e. the parser fully 276 parsed the input) by checking if the first iterator, after parsing, is 277 equal to the end iterator. You may strike out this part if partial matches 278 are to be allowed. 279 </p> 280</div> 281<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 282<td align="left"></td> 283<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> 284 Distributed under the Boost Software License, Version 1.0. (See accompanying 285 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>) 286 </p> 287</div></td> 288</tr></table> 289<hr> 290<div class="spirit-nav"> 291<a accesskey="p" href="quick_start.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorials.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="semantic_actions.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> 292</div> 293</body> 294</html> 295