• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Quickstart 3 - Counting Words Using a Parser</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="Spirit.Lex Tutorials">
9<link rel="prev" href="lexer_quickstart2.html" title="Quickstart 2 - A better word counter using Spirit.Lex">
10<link rel="next" href="../abstracts.html" title="Abstracts">
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="lexer_quickstart2.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="../abstracts.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.lex.tutorials.lexer_quickstart3"></a><a class="link" href="lexer_quickstart3.html" title="Quickstart 3 - Counting Words Using a Parser">Quickstart
28        3 - Counting Words Using a Parser</a>
29</h4></div></div></div>
30<p>
31          The whole purpose of integrating <span class="emphasis"><em>Spirit.Lex</em></span> as part
32          of the <a href="http://boost-spirit.com" target="_top">Spirit</a> library was
33          to add a library allowing the merger of lexical analysis with the parsing
34          process as defined by a <a href="http://boost-spirit.com" target="_top">Spirit</a>
35          grammar. <a href="http://boost-spirit.com" target="_top">Spirit</a> parsers read
36          their input from an input sequence accessed by iterators. So naturally,
37          we chose iterators to be used as the interface between the lexer and the
38          parser. A second goal of the lexer/parser integration was to enable the
39          usage of different lexical analyzer libraries. The utilization of iterators
40          seemed to be the right choice from this standpoint as well, mainly because
41          these can be used as an abstraction layer hiding implementation specifics
42          of the used lexer library. The <a class="link" href="lexer_quickstart3.html#spirit.lex.flowcontrol" title="Figure 7. The common flow control implemented while parsing combined with lexical analysis">picture</a>
43          below shows the common flow control implemented while parsing combined
44          with lexical analysis.
45        </p>
46<p>
47          </p>
48<div class="figure">
49<a name="spirit.lex.flowcontrol"></a><p class="title"><b>Figure 7. The common flow control implemented while parsing
50          combined with lexical analysis</b></p>
51<div class="figure-contents"><span class="inlinemediaobject"><img src="../../.././images/flowofcontrol.png" alt="The common flow control implemented while parsing combined with lexical analysis"></span></div>
52</div>
53<p><br class="figure-break">
54        </p>
55<p>
56          Another problem related to the integration of the lexical analyzer with
57          the parser was to find a way how the defined tokens syntactically could
58          be blended with the grammar definition syntax of <a href="http://boost-spirit.com" target="_top">Spirit</a>.
59          For tokens defined as instances of the <code class="computeroutput"><span class="identifier">token_def</span><span class="special">&lt;&gt;</span></code> class the most natural way of integration
60          was to allow to directly use these as parser components. Semantically these
61          parser components succeed matching their input whenever the corresponding
62          token type has been matched by the lexer. This quick start example will
63          demonstrate this (and more) by counting words again, simply by adding up
64          the numbers inside of semantic actions of a parser (for the full example
65          code see here: <a href="../../../../../example/lex/word_count.cpp" target="_top">word_count.cpp</a>).
66        </p>
67<h6>
68<a name="spirit.lex.tutorials.lexer_quickstart3.h0"></a>
69          <span class="phrase"><a name="spirit.lex.tutorials.lexer_quickstart3.prerequisites"></a></span><a class="link" href="lexer_quickstart3.html#spirit.lex.tutorials.lexer_quickstart3.prerequisites">Prerequisites</a>
70        </h6>
71<p>
72          This example uses two of the <a href="http://boost-spirit.com" target="_top">Spirit</a>
73          library components: <span class="emphasis"><em>Spirit.Lex</em></span> and <span class="emphasis"><em>Spirit.Qi</em></span>,
74          consequently we have to <code class="computeroutput"><span class="preprocessor">#include</span></code>
75          the corresponding header files. Again, we need to include a couple of header
76          files from the <a href="../../../../../../../libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a>
77          library. This example shows how to attach functors to parser components,
78          which could be done using any type of C++ technique resulting in a callable
79          object. Using <a href="../../../../../../../libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a>
80          for this task simplifies things and avoids adding dependencies to other
81          libraries (<a href="../../../../../../../libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a>
82          is already in use for <a href="http://boost-spirit.com" target="_top">Spirit</a>
83          anyway).
84        </p>
85<p>
86</p>
87<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
88<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">lex_lexertl</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
89<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_operator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
90<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_statement</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
91<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_container</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
92</pre>
93<p>
94        </p>
95<p>
96          To make all the code below more readable we introduce the following namespaces.
97        </p>
98<p>
99</p>
100<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span>
101<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">;</span>
102</pre>
103<p>
104        </p>
105<h6>
106<a name="spirit.lex.tutorials.lexer_quickstart3.h1"></a>
107          <span class="phrase"><a name="spirit.lex.tutorials.lexer_quickstart3.defining_tokens"></a></span><a class="link" href="lexer_quickstart3.html#spirit.lex.tutorials.lexer_quickstart3.defining_tokens">Defining
108          Tokens</a>
109        </h6>
110<p>
111          If compared to the two previous quick start examples (<a class="link" href="lexer_quickstart1.html" title="Quickstart 1 - A word counter using Spirit.Lex">Lex
112          Quickstart 1 - A word counter using <span class="emphasis"><em>Spirit.Lex</em></span></a>
113          and <a class="link" href="lexer_quickstart2.html" title="Quickstart 2 - A better word counter using Spirit.Lex">Lex Quickstart
114          2 - A better word counter using <span class="emphasis"><em>Spirit.Lex</em></span></a>)
115          the token definition class for this example does not reveal any surprises.
116          However, it uses lexer token definition macros to simplify the composition
117          of the regular expressions, which will be described in more detail in the
118          section <span class="bold"><strong>FIXME</strong></span>. Generally, any token definition
119          is usable without modification from either a stand alone lexical analyzer
120          or in conjunction with a parser.
121        </p>
122<p>
123</p>
124<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Lexer</span><span class="special">&gt;</span>
125<span class="keyword">struct</span> <span class="identifier">word_count_tokens</span> <span class="special">:</span> <span class="identifier">lex</span><span class="special">::</span><span class="identifier">lexer</span><span class="special">&lt;</span><span class="identifier">Lexer</span><span class="special">&gt;</span>
126<span class="special">{</span>
127    <span class="identifier">word_count_tokens</span><span class="special">()</span>
128    <span class="special">{</span>
129        <span class="comment">// define patterns (lexer macros) to be used during token definition </span>
130        <span class="comment">// below</span>
131        <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">add_pattern</span>
132            <span class="special">(</span><span class="string">"WORD"</span><span class="special">,</span> <span class="string">"[^ \t\n]+"</span><span class="special">)</span>
133        <span class="special">;</span>
134
135        <span class="comment">// define tokens and associate them with the lexer</span>
136        <span class="identifier">word</span> <span class="special">=</span> <span class="string">"{WORD}"</span><span class="special">;</span>    <span class="comment">// reference the pattern 'WORD' as defined above</span>
137
138        <span class="comment">// this lexer will recognize 3 token types: words, newlines, and </span>
139        <span class="comment">// everything else</span>
140        <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">add</span>
141            <span class="special">(</span><span class="identifier">word</span><span class="special">)</span>          <span class="comment">// no token id is needed here</span>
142            <span class="special">(</span><span class="char">'\n'</span><span class="special">)</span>          <span class="comment">// characters are usable as tokens as well</span>
143            <span class="special">(</span><span class="string">"."</span><span class="special">,</span> <span class="identifier">IDANY</span><span class="special">)</span>    <span class="comment">// string literals will not be escaped by the library</span>
144        <span class="special">;</span>
145    <span class="special">}</span>
146
147    <span class="comment">// the token 'word' exposes the matched string as its parser attribute</span>
148    <span class="identifier">lex</span><span class="special">::</span><span class="identifier">token_def</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">word</span><span class="special">;</span>
149<span class="special">};</span>
150</pre>
151<p>
152        </p>
153<h6>
154<a name="spirit.lex.tutorials.lexer_quickstart3.h2"></a>
155          <span class="phrase"><a name="spirit.lex.tutorials.lexer_quickstart3.using_token_definition_instances_as_parsers"></a></span><a class="link" href="lexer_quickstart3.html#spirit.lex.tutorials.lexer_quickstart3.using_token_definition_instances_as_parsers">Using
156          Token Definition Instances as Parsers</a>
157        </h6>
158<p>
159          While the integration of lexer and parser in the control flow is achieved
160          by using special iterators wrapping the lexical analyzer, we still need
161          a means of expressing in the grammar what tokens to match and where. The
162          token definition class above uses three different ways of defining a token:
163        </p>
164<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
165<li class="listitem">
166              Using an instance of a <code class="computeroutput"><span class="identifier">token_def</span><span class="special">&lt;&gt;</span></code>, which is handy whenever you
167              need to specify a token attribute (for more information about lexer
168              related attributes please look here: Lexer Attributes).
169            </li>
170<li class="listitem">
171              Using a single character as the token, in this case the character represents
172              itself as a token, where the token id is the ASCII character value.
173            </li>
174<li class="listitem">
175              Using a regular expression represented as a string, where the token
176              id needs to be specified explicitly to make the token accessible from
177              the grammar level.
178            </li>
179</ul></div>
180<p>
181          All three token definition methods require a different method of grammar
182          integration. But as you can see from the following code snippet, each of
183          these methods are straightforward and blend the corresponding token instances
184          naturally with the surrounding <span class="emphasis"><em>Spirit.Qi</em></span> grammar syntax.
185        </p>
186<div class="informaltable"><table class="table">
187<colgroup>
188<col>
189<col>
190</colgroup>
191<thead><tr>
192<th>
193                  <p>
194                    Token definition
195                  </p>
196                </th>
197<th>
198                  <p>
199                    Parser integration
200                  </p>
201                </th>
202</tr></thead>
203<tbody>
204<tr>
205<td>
206                  <p>
207                    <code class="computeroutput"><span class="identifier">token_def</span><span class="special">&lt;&gt;</span></code>
208                  </p>
209                </td>
210<td>
211                  <p>
212                    The <code class="computeroutput"><span class="identifier">token_def</span><span class="special">&lt;&gt;</span></code> instance is directly
213                    usable as a parser component. Parsing of this component will
214                    succeed if the regular expression used to define this has been
215                    matched successfully.
216                  </p>
217                </td>
218</tr>
219<tr>
220<td>
221                  <p>
222                    single character
223                  </p>
224                </td>
225<td>
226                  <p>
227                    The single character is directly usable in the grammar. However,
228                    under certain circumstances it needs to be wrapped by a <code class="computeroutput"><span class="identifier">char_</span><span class="special">()</span></code>
229                    parser component. Parsing of this component will succeed if the
230                    single character has been matched.
231                  </p>
232                </td>
233</tr>
234<tr>
235<td>
236                  <p>
237                    explicit token id
238                  </p>
239                </td>
240<td>
241                  <p>
242                    To use an explicit token id in a <span class="emphasis"><em>Spirit.Qi</em></span>
243                    grammar you are required to wrap it with the special <code class="computeroutput"><span class="identifier">token</span><span class="special">()</span></code>
244                    parser component. Parsing of this component will succeed if the
245                    current token has the same token id as specified in the expression
246                    <code class="computeroutput"><span class="identifier">token</span><span class="special">(&lt;</span><span class="identifier">id</span><span class="special">&gt;)</span></code>.
247                  </p>
248                </td>
249</tr>
250</tbody>
251</table></div>
252<p>
253          The grammar definition below uses each of the three types demonstrating
254          their usage.
255        </p>
256<p>
257</p>
258<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>
259<span class="keyword">struct</span> <span class="identifier">word_count_grammar</span> <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">grammar</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">&gt;</span>
260<span class="special">{</span>
261    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">TokenDef</span><span class="special">&gt;</span>
262    <span class="identifier">word_count_grammar</span><span class="special">(</span><span class="identifier">TokenDef</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">tok</span><span class="special">)</span>
263      <span class="special">:</span> <span class="identifier">word_count_grammar</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">start</span><span class="special">)</span>
264      <span class="special">,</span> <span class="identifier">c</span><span class="special">(</span><span class="number">0</span><span class="special">),</span> <span class="identifier">w</span><span class="special">(</span><span class="number">0</span><span class="special">),</span> <span class="identifier">l</span><span class="special">(</span><span class="number">0</span><span class="special">)</span>
265    <span class="special">{</span>
266        <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">ref</span><span class="special">;</span>
267        <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">size</span><span class="special">;</span>
268
269        <span class="identifier">start</span> <span class="special">=</span>  <span class="special">*(</span>   <span class="identifier">tok</span><span class="special">.</span><span class="identifier">word</span>          <span class="special">[++</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">w</span><span class="special">),</span> <span class="identifier">ref</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span> <span class="special">+=</span> <span class="identifier">size</span><span class="special">(</span><span class="identifier">_1</span><span class="special">)]</span>
270                  <span class="special">|</span>   <span class="identifier">lit</span><span class="special">(</span><span class="char">'\n'</span><span class="special">)</span>         <span class="special">[++</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">c</span><span class="special">),</span> <span class="special">++</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">l</span><span class="special">)]</span>
271                  <span class="special">|</span>   <span class="identifier">qi</span><span class="special">::</span><span class="identifier">token</span><span class="special">(</span><span class="identifier">IDANY</span><span class="special">)</span>  <span class="special">[++</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">c</span><span class="special">)]</span>
272                  <span class="special">)</span>
273              <span class="special">;</span>
274    <span class="special">}</span>
275
276    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">c</span><span class="special">,</span> <span class="identifier">w</span><span class="special">,</span> <span class="identifier">l</span><span class="special">;</span>
277    <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">&gt;</span> <span class="identifier">start</span><span class="special">;</span>
278<span class="special">};</span>
279</pre>
280<p>
281        </p>
282<p>
283          As already described (see: <a class="link" href="../../abstracts/attributes.html" title="Attributes">Attributes</a>),
284          the <span class="emphasis"><em>Spirit.Qi</em></span> parser library builds upon a set of
285          fully attributed parser components. Consequently, all token definitions
286          support this attribute model as well. The most natural way of implementing
287          this was to use the token values as the attributes exposed by the parser
288          component corresponding to the token definition (you can read more about
289          this topic here: <a class="link" href="../abstracts/lexer_primitives/lexer_token_values.html" title="About Tokens and Token Values">About
290          Tokens and Token Values</a>). The example above takes advantage of the
291          full integration of the token values as the <code class="computeroutput"><span class="identifier">token_def</span><span class="special">&lt;&gt;</span></code>'s parser attributes: the <code class="computeroutput"><span class="identifier">word</span></code> token definition is declared as
292          a <code class="computeroutput"><span class="identifier">token_def</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code>,
293          making every instance of a <code class="computeroutput"><span class="identifier">word</span></code>
294          token carry the string representation of the matched input sequence as
295          its value. The semantic action attached to <code class="computeroutput"><span class="identifier">tok</span><span class="special">.</span><span class="identifier">word</span></code>
296          receives this string (represented by the <code class="computeroutput"><span class="identifier">_1</span></code>
297          placeholder) and uses it to calculate the number of matched characters:
298          <code class="computeroutput"><span class="identifier">ref</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span> <span class="special">+=</span>
299          <span class="identifier">size</span><span class="special">(</span><span class="identifier">_1</span><span class="special">)</span></code>.
300        </p>
301<h6>
302<a name="spirit.lex.tutorials.lexer_quickstart3.h3"></a>
303          <span class="phrase"><a name="spirit.lex.tutorials.lexer_quickstart3.pulling_everything_together"></a></span><a class="link" href="lexer_quickstart3.html#spirit.lex.tutorials.lexer_quickstart3.pulling_everything_together">Pulling
304          Everything Together</a>
305        </h6>
306<p>
307          The main function needs to implement a bit more logic now as we have to
308          initialize and start not only the lexical analysis but the parsing process
309          as well. The three type definitions (<code class="computeroutput"><span class="keyword">typedef</span></code>
310          statements) simplify the creation of the lexical analyzer and the grammar.
311          After reading the contents of the given file into memory it calls the function
312          <code class="computeroutput"><span class="identifier">tokenize_and_parse</span><span class="special">()</span></code>
313          to initialize the lexical analysis and parsing processes.
314        </p>
315<p>
316</p>
317<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">argv</span><span class="special">[])</span>
318<span class="special">{</span>
319<a class="co" name="spirit.lex.tutorials.lexer_quickstart3.c0" href="lexer_quickstart3.html#spirit.lex.tutorials.lexer_quickstart3.c1"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>  <span class="keyword">typedef</span> <span class="identifier">lex</span><span class="special">::</span><span class="identifier">lexertl</span><span class="special">::</span><span class="identifier">token</span><span class="special">&lt;</span>
320        <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span>
321    <span class="special">&gt;</span> <span class="identifier">token_type</span><span class="special">;</span>
322
323<a class="co" name="spirit.lex.tutorials.lexer_quickstart3.c2" href="lexer_quickstart3.html#spirit.lex.tutorials.lexer_quickstart3.c3"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>  <span class="keyword">typedef</span> <span class="identifier">lex</span><span class="special">::</span><span class="identifier">lexertl</span><span class="special">::</span><span class="identifier">lexer</span><span class="special">&lt;</span><span class="identifier">token_type</span><span class="special">&gt;</span> <span class="identifier">lexer_type</span><span class="special">;</span>
324
325<a class="co" name="spirit.lex.tutorials.lexer_quickstart3.c4" href="lexer_quickstart3.html#spirit.lex.tutorials.lexer_quickstart3.c5"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>  <span class="keyword">typedef</span> <span class="identifier">word_count_tokens</span><span class="special">&lt;</span><span class="identifier">lexer_type</span><span class="special">&gt;::</span><span class="identifier">iterator_type</span> <span class="identifier">iterator_type</span><span class="special">;</span>
326
327    <span class="comment">// now we use the types defined above to create the lexer and grammar</span>
328    <span class="comment">// object instances needed to invoke the parsing process</span>
329    <span class="identifier">word_count_tokens</span><span class="special">&lt;</span><span class="identifier">lexer_type</span><span class="special">&gt;</span> <span class="identifier">word_count</span><span class="special">;</span>          <span class="comment">// Our lexer</span>
330    <span class="identifier">word_count_grammar</span><span class="special">&lt;</span><span class="identifier">iterator_type</span><span class="special">&gt;</span> <span class="identifier">g</span> <span class="special">(</span><span class="identifier">word_count</span><span class="special">);</span>  <span class="comment">// Our parser </span>
331
332    <span class="comment">// read in the file int memory</span>
333    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">str</span> <span class="special">(</span><span class="identifier">read_from_file</span><span class="special">(</span><span class="number">1</span> <span class="special">==</span> <span class="identifier">argc</span> <span class="special">?</span> <span class="string">"word_count.input"</span> <span class="special">:</span> <span class="identifier">argv</span><span class="special">[</span><span class="number">1</span><span class="special">]));</span>
334    <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">c_str</span><span class="special">();</span>
335    <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">last</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">first</span><span class="special">[</span><span class="identifier">str</span><span class="special">.</span><span class="identifier">size</span><span class="special">()];</span>
336
337<a class="co" name="spirit.lex.tutorials.lexer_quickstart3.c6" href="lexer_quickstart3.html#spirit.lex.tutorials.lexer_quickstart3.c7"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a>  <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">lex</span><span class="special">::</span><span class="identifier">tokenize_and_parse</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="identifier">word_count</span><span class="special">,</span> <span class="identifier">g</span><span class="special">);</span>
338
339    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">r</span><span class="special">)</span> <span class="special">{</span>
340        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"lines: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">g</span><span class="special">.</span><span class="identifier">l</span> <span class="special">&lt;&lt;</span> <span class="string">", words: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">g</span><span class="special">.</span><span class="identifier">w</span>
341                  <span class="special">&lt;&lt;</span> <span class="string">", characters: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">g</span><span class="special">.</span><span class="identifier">c</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
342    <span class="special">}</span>
343    <span class="keyword">else</span> <span class="special">{</span>
344        <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">rest</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">);</span>
345        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"Parsing failed\n"</span> <span class="special">&lt;&lt;</span> <span class="string">"stopped at: \""</span>
346                  <span class="special">&lt;&lt;</span> <span class="identifier">rest</span> <span class="special">&lt;&lt;</span> <span class="string">"\"\n"</span><span class="special">;</span>
347    <span class="special">}</span>
348    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
349<span class="special">}</span>
350</pre>
351<p>
352        </p>
353<div class="calloutlist"><table border="0" summary="Callout list">
354<tr>
355<td width="5%" valign="top" align="left"><p><a name="spirit.lex.tutorials.lexer_quickstart3.c1"></a><a href="#spirit.lex.tutorials.lexer_quickstart3.c0"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
356<td valign="top" align="left"><p>
357              Define the token type to be used: <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
358              is available as the type of the token attribute
359            </p></td>
360</tr>
361<tr>
362<td width="5%" valign="top" align="left"><p><a name="spirit.lex.tutorials.lexer_quickstart3.c3"></a><a href="#spirit.lex.tutorials.lexer_quickstart3.c2"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
363<td valign="top" align="left"><p>
364              Define the lexer type to use implementing the state machine
365            </p></td>
366</tr>
367<tr>
368<td width="5%" valign="top" align="left"><p><a name="spirit.lex.tutorials.lexer_quickstart3.c5"></a><a href="#spirit.lex.tutorials.lexer_quickstart3.c4"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
369<td valign="top" align="left"><p>
370              Define the iterator type exposed by the lexer type
371            </p></td>
372</tr>
373<tr>
374<td width="5%" valign="top" align="left"><p><a name="spirit.lex.tutorials.lexer_quickstart3.c7"></a><a href="#spirit.lex.tutorials.lexer_quickstart3.c6"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td>
375<td valign="top" align="left"><p>
376              Parsing is done based on the token stream, not the character stream
377              read from the input. The function <code class="computeroutput"><span class="identifier">tokenize_and_parse</span><span class="special">()</span></code> wraps the passed iterator range
378              <code class="computeroutput"><span class="special">[</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">)</span></code> by the lexical analyzer and uses its
379              exposed iterators to parse the token stream.
380            </p></td>
381</tr>
382</table></div>
383</div>
384<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
385<td align="left"></td>
386<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p>
387        Distributed under the Boost Software License, Version 1.0. (See accompanying
388        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>)
389      </p>
390</div></td>
391</tr></table>
392<hr>
393<div class="spirit-nav">
394<a accesskey="p" href="lexer_quickstart2.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="../abstracts.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
395</div>
396</body>
397</html>
398