• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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">&gt;&gt;</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">&gt;&gt;</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">&gt;&gt;</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">&gt;&gt;</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">&gt;&gt;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">&gt;</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">&gt;&gt;</span> <span class="special">*(</span><span class="char">','</span> <span class="special">&gt;&gt;</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">&gt;&gt;</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">&gt;&gt;</span></code>,
255            and so the proper overload of <code class="computeroutput"><span class="special">&gt;&gt;</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">&gt;&gt;</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">&gt;&gt;</span>
266            <span class="char">'b'</span></code> and <code class="computeroutput"><span class="char">'a'</span>
267            <span class="special">&gt;&gt;</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