• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Error Handling</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="rexpr.html" title="RExpressions - Recursive ASTs!">
10<link rel="next" href="../quick_reference.html" title="Quick Reference">
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="rexpr.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="../quick_reference.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.error_handling"></a><a class="link" href="error_handling.html" title="Error Handling">Error Handling</a>
28</h3></div></div></div>
29<p>
30        This tutorial wouldn't be complete without touching on error handling. As
31        a prerequisite in understanding this tutorial, please review the previous
32        <a class="link" href="employee.html" title="Employee - Parsing into structs">employee</a> and <a class="link" href="annotation.html" title="Annotations - Decorating the ASTs">annotations</a>
33        examples. This example builds on top of these previous examples.
34      </p>
35<p>
36        The full cpp file for this example can be found here: <a href="../../../../../example/x3/error_handling.cpp" target="_top">error_handling.cpp</a>
37      </p>
38<p>
39        Please review the previous <a class="link" href="annotation.html" title="Annotations - Decorating the ASTs">annotations
40        example</a>. The information there will be very helpful in understanding
41        error handling.
42      </p>
43<h5>
44<a name="spirit_x3.tutorials.error_handling.h0"></a>
45        <span class="phrase"><a name="spirit_x3.tutorials.error_handling.the_ast"></a></span><a class="link" href="error_handling.html#spirit_x3.tutorials.error_handling.the_ast">The
46        AST</a>
47      </h5>
48<p>
49        Our AST is exactly the same as what we had before in the <a class="link" href="annotation.html" title="Annotations - Decorating the ASTs">annotations</a>:
50      </p>
51<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>
52<span class="special">{</span>
53    <span class="keyword">struct</span> <span class="identifier">person</span> <span class="special">:</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">position_tagged</span>
54    <span class="special">{</span>
55        <span class="identifier">person</span><span class="special">(</span>
56            <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">first_name</span> <span class="special">=</span> <span class="string">""</span>
57          <span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">last_name</span> <span class="special">=</span> <span class="string">""</span>
58        <span class="special">)</span>
59        <span class="special">:</span> <span class="identifier">first_name</span><span class="special">(</span><span class="identifier">first_name</span><span class="special">)</span>
60        <span class="special">,</span> <span class="identifier">last_name</span><span class="special">(</span><span class="identifier">last_name</span><span class="special">)</span>
61        <span class="special">{}</span>
62
63        <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">first_name</span><span class="special">,</span> <span class="identifier">last_name</span><span class="special">;</span>
64    <span class="special">};</span>
65
66    <span class="keyword">struct</span> <span class="identifier">employee</span> <span class="special">:</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">position_tagged</span>
67    <span class="special">{</span>
68        <span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span>
69        <span class="identifier">person</span> <span class="identifier">who</span><span class="special">;</span>
70        <span class="keyword">double</span> <span class="identifier">salary</span><span class="special">;</span>
71    <span class="special">};</span>
72<span class="special">}}</span>
73</pre>
74<p>
75        We have two structs, the <code class="computeroutput"><span class="identifier">person</span></code>
76        and the <code class="computeroutput"><span class="identifier">employee</span></code>. Each inherits
77        from <code class="computeroutput"><span class="identifier">x3</span><span class="special">::</span><span class="identifier">position_tagged</span></code> which provides positional
78        information that we can use to tell the AST's position in the input stream
79        anytime. We will need these information for error handling and reporting.
80      </p>
81<p>
82        Like before, we need to tell <a href="../../../../../../../libs/fusion/doc/html/index.html" target="_top">Boost.Fusion</a>
83        about our structs to make them first-class fusion citizens that the grammar
84        can utilize:
85      </p>
86<pre class="programlisting"><span class="identifier">BOOST_FUSION_ADAPT_STRUCT</span><span class="special">(</span><span class="identifier">client</span><span class="special">::</span><span class="identifier">ast</span><span class="special">::</span><span class="identifier">person</span><span class="special">,</span>
87    <span class="identifier">first_name</span><span class="special">,</span> <span class="identifier">last_name</span>
88<span class="special">)</span>
89
90<span class="identifier">BOOST_FUSION_ADAPT_STRUCT</span><span class="special">(</span><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>
91    <span class="identifier">age</span><span class="special">,</span> <span class="identifier">who</span><span class="special">,</span> <span class="identifier">salary</span>
92<span class="special">)</span>
93</pre>
94<h5>
95<a name="spirit_x3.tutorials.error_handling.h1"></a>
96        <span class="phrase"><a name="spirit_x3.tutorials.error_handling.expectations"></a></span><a class="link" href="error_handling.html#spirit_x3.tutorials.error_handling.expectations">Expectations</a>
97      </h5>
98<p>
99        There are occasions in which it is expected that the input must match a particular
100        parser or the input is invalid. Such cases generally arise after matching
101        a portion of a grammar, such that the context is fully known. In such a situation,
102        failure to match should result in an exception. For example, when parsing
103        an e-mail address, a name, an "@" and a domain name must be matched
104        or the address is invalid.
105      </p>
106<p>
107        Two X3 mechanisms facilitate parser expectations:
108      </p>
109<div class="orderedlist"><ol class="orderedlist" type="1">
110<li class="listitem">
111            The expectation operator (Expectation operator)
112          </li>
113<li class="listitem">
114            The expect directive (<code class="computeroutput"><span class="identifier">expect</span></code><code class="computeroutput"><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>)
115          </li>
116</ol></div>
117<p>
118        The expectation operator (Expectation operator) requires that the following
119        parser (<code class="computeroutput"><span class="identifier">b</span></code>) match the input
120        or an <code class="computeroutput"><span class="identifier">expectation_failure</span></code>
121        is emitted. Using a client supplied <code class="computeroutput"><span class="identifier">on_error</span></code>
122        handler, the exception can be serviced by calling the handler with the source
123        iterators and context at which the parsing failed can be reported.
124      </p>
125<p>
126        By contrast, the sequence operator (Sequence) does not require that the following
127        parser match the input, which allows for backtracking or simply returning
128        false from the parse function with no exceptions.
129      </p>
130<p>
131        The expect directive (<code class="computeroutput"><span class="identifier">expect</span></code><code class="computeroutput"><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>)
132        requires that the argument parser matches the input or an exception is emitted.
133        Using on_error(), that exception can be handled by calling a handler with
134        the context at which the parsing failed can be reported.
135      </p>
136<h5>
137<a name="spirit_x3.tutorials.error_handling.h2"></a>
138        <span class="phrase"><a name="spirit_x3.tutorials.error_handling.on_error"></a></span><a class="link" href="error_handling.html#spirit_x3.tutorials.error_handling.on_error">on_error</a>
139      </h5>
140<p>
141        <code class="computeroutput"><span class="identifier">on_error</span></code> is the counterpart
142        of <code class="computeroutput"><span class="identifier">on_success</span></code>, as discussed
143        in the <a class="link" href="annotation.html" title="Annotations - Decorating the ASTs">annotations example</a>.
144        While <code class="computeroutput"><span class="identifier">on_success</span></code> handlers
145        are callback hooks to client code that are executed by the parser after a
146        <span class="emphasis"><em>successful</em></span> parse, <code class="computeroutput"><span class="identifier">on_error</span></code>
147        handlers are callback hooks to client code that are executed by the parser
148        when an <code class="computeroutput"><span class="identifier">expectation_failure</span></code>
149        is thrown via the expect operator or directive. <code class="computeroutput"><span class="identifier">on_error</span></code>
150        handlers have access to the iterators, the context and the exception that
151        was thrown.
152      </p>
153<h5>
154<a name="spirit_x3.tutorials.error_handling.h3"></a>
155        <span class="phrase"><a name="spirit_x3.tutorials.error_handling.error_handling"></a></span><a class="link" href="error_handling.html#spirit_x3.tutorials.error_handling.error_handling">Error
156        Handling</a>
157      </h5>
158<p>
159        Before we proceed, let me introduce a helper class, the x3::error_handler.
160        It is utility class that provides <a href="https://clang.llvm.org/" target="_top">Clang</a>
161        style error reporting which gives you nice reports such as the following:
162      </p>
163<pre class="programlisting">In line 16:
164Error! Expecting: person here:
165    'I am not a person!'    &lt;--- this should be a person
166____^_
167</pre>
168<p>
169        We'll see later that this error message is exactly what this example emits.
170      </p>
171<p>
172        Here's our <code class="computeroutput"><span class="identifier">on_error</span></code> handler:
173      </p>
174<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">error_handler</span>
175<span class="special">{</span>
176    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Exception</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">&gt;</span>
177    <span class="identifier">x3</span><span class="special">::</span><span class="identifier">error_handler_result</span> <span class="identifier">on_error</span><span class="special">(</span>
178        <span class="identifier">Iterator</span><span class="special">&amp;</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">last</span>
179      <span class="special">,</span> <span class="identifier">Exception</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">Context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">)</span>
180    <span class="special">{</span>
181        <span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">error_handler</span> <span class="special">=</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="identifier">x3</span><span class="special">::</span><span class="identifier">error_handler_tag</span><span class="special">&gt;(</span><span class="identifier">context</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span>
182        <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">message</span> <span class="special">=</span> <span class="string">"Error! Expecting: "</span> <span class="special">+</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">which</span><span class="special">()</span> <span class="special">+</span> <span class="string">" here:"</span><span class="special">;</span>
183        <span class="identifier">error_handler</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">where</span><span class="special">(),</span> <span class="identifier">message</span><span class="special">);</span>
184        <span class="keyword">return</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">error_handler_result</span><span class="special">::</span><span class="identifier">fail</span><span class="special">;</span>
185    <span class="special">}</span>
186<span class="special">};</span>
187</pre>
188<p>
189        <code class="computeroutput"><span class="identifier">x3</span><span class="special">::</span><span class="identifier">error_handler_tag</span></code> is a special tag we will
190        use to get a reference to the actual x3::error_handler that we will inject
191        at very start, when we call parse. We get the x3::error_handler here:
192      </p>
193<pre class="programlisting"><span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">error_handler</span> <span class="special">=</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="identifier">error_handler_tag</span><span class="special">&gt;(</span><span class="identifier">context</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span>
194</pre>
195<p>
196        The x3::error_handler handles all the nitty gritty details such as determining
197        the line number and actual column position, and formatting the error message
198        printed. All we have to do is provide the actual error string which we extract
199        from the <code class="computeroutput"><span class="identifier">expectation_failure</span></code>
200        exception:
201      </p>
202<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">message</span> <span class="special">=</span> <span class="string">"Error! Expecting: "</span> <span class="special">+</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">which</span><span class="special">()</span> <span class="special">+</span> <span class="string">" here:"</span><span class="special">;</span>
203</pre>
204<p>
205        Then, we return <code class="computeroutput"><span class="identifier">x3</span><span class="special">::</span><span class="identifier">error_handler_result</span><span class="special">::</span><span class="identifier">fail</span></code> to tell X3 that we want to fail the
206        parse when such an event is caught. You can return one of:
207      </p>
208<div class="informaltable"><table class="table">
209<colgroup>
210<col>
211<col>
212</colgroup>
213<thead><tr>
214<th>
215                <p>
216                  <code class="computeroutput"><span class="identifier">Action</span></code>
217                </p>
218              </th>
219<th>
220                <p>
221                  Description
222                </p>
223              </th>
224</tr></thead>
225<tbody>
226<tr>
227<td>
228                <p>
229                  fail
230                </p>
231              </td>
232<td>
233                <p>
234                  Quit and fail. Return a no_match.
235                </p>
236              </td>
237</tr>
238<tr>
239<td>
240                <p>
241                  retry
242                </p>
243              </td>
244<td>
245                <p>
246                  Attempt error recovery, possibly moving the iterator position.
247                </p>
248              </td>
249</tr>
250<tr>
251<td>
252                <p>
253                  accept
254                </p>
255              </td>
256<td>
257                <p>
258                  Force success, moving the iterator position appropriately.
259                </p>
260              </td>
261</tr>
262<tr>
263<td>
264                <p>
265                  rethrow
266                </p>
267              </td>
268<td>
269                <p>
270                  Rethrows the error.
271                </p>
272              </td>
273</tr>
274</tbody>
275</table></div>
276<h5>
277<a name="spirit_x3.tutorials.error_handling.h4"></a>
278        <span class="phrase"><a name="spirit_x3.tutorials.error_handling.the_parser"></a></span><a class="link" href="error_handling.html#spirit_x3.tutorials.error_handling.the_parser">The
279        Parser</a>
280      </h5>
281<p>
282        Now we'll rewrite employee parser with error handling in mind. Like the
283        <a class="link" href="annotation.html" title="Annotations - Decorating the ASTs">annotations</a> example,
284        inputs will be of the form:
285      </p>
286<pre class="programlisting"><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>
287</pre>
288<p>
289        Here we go:
290      </p>
291<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">parser</span>
292<span class="special">{</span>
293    <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span>
294    <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span>
295    <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span>
296    <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
297
298    <span class="keyword">struct</span> <span class="identifier">quoted_string_class</span><span class="special">;</span>
299    <span class="keyword">struct</span> <span class="identifier">person_class</span><span class="special">;</span>
300    <span class="keyword">struct</span> <span class="identifier">employee_class</span><span class="special">;</span>
301
302    <span class="identifier">x3</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">quoted_string_class</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">quoted_string</span> <span class="special">=</span> <span class="string">"quoted_string"</span><span class="special">;</span>
303    <span class="identifier">x3</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">person_class</span><span class="special">,</span> <span class="identifier">ast</span><span class="special">::</span><span class="identifier">person</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">person</span> <span class="special">=</span> <span class="string">"person"</span><span class="special">;</span>
304    <span class="identifier">x3</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">employee_class</span><span class="special">,</span> <span class="identifier">ast</span><span class="special">::</span><span class="identifier">employee</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">employee</span> <span class="special">=</span> <span class="string">"employee"</span><span class="special">;</span>
305
306    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">quoted_string_def</span> <span class="special">=</span> <span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</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="char">'"'</span><span class="special">];</span>
307    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">person_def</span> <span class="special">=</span> <span class="identifier">quoted_string</span> <span class="special">&gt;</span> <span class="char">','</span> <span class="special">&gt;</span> <span class="identifier">quoted_string</span><span class="special">;</span>
308
309    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">employee_def</span> <span class="special">=</span>
310            <span class="char">'{'</span>
311        <span class="special">&gt;</span>   <span class="identifier">int_</span> <span class="special">&gt;</span> <span class="char">','</span>
312        <span class="special">&gt;</span>   <span class="identifier">person</span> <span class="special">&gt;</span> <span class="char">','</span>
313        <span class="special">&gt;</span>   <span class="identifier">double_</span>
314        <span class="special">&gt;</span>   <span class="char">'}'</span>
315        <span class="special">;</span>
316
317    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">employees</span> <span class="special">=</span> <span class="identifier">employee</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="char">','</span> <span class="special">&gt;&gt;</span> <span class="identifier">employee</span><span class="special">);</span>
318
319    <span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">quoted_string</span><span class="special">,</span> <span class="identifier">person</span><span class="special">,</span> <span class="identifier">employee</span><span class="special">);</span>
320
321    <span class="keyword">struct</span> <span class="identifier">quoted_string_class</span> <span class="special">{};</span>
322    <span class="keyword">struct</span> <span class="identifier">person_class</span> <span class="special">:</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">annotate_on_success</span> <span class="special">{};</span>
323    <span class="keyword">struct</span> <span class="identifier">employee_class</span> <span class="special">:</span> <span class="identifier">error_handler</span><span class="special">,</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">annotate_on_success</span> <span class="special">{};</span>
324<span class="special">}</span>
325</pre>
326<p>
327        Go back and review the <a class="link" href="annotation.html#__tutorial_annotated_employee_parser__">annotated
328        employee parser</a>. What has changed? It is almost identical, except:
329      </p>
330<p>
331        Where appropriate, we're using the expectation operator (Expectation operator)
332        in place of the sequence operator (Sequence):
333      </p>
334<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">person_def</span> <span class="special">=</span> <span class="identifier">quoted_string</span> <span class="special">&gt;</span> <span class="char">','</span> <span class="special">&gt;</span> <span class="identifier">quoted_string</span><span class="special">;</span>
335
336<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">employee_def</span> <span class="special">=</span>
337        <span class="char">'{'</span>
338    <span class="special">&gt;</span>   <span class="identifier">int_</span> <span class="special">&gt;</span> <span class="char">','</span>
339    <span class="special">&gt;</span>   <span class="identifier">person</span> <span class="special">&gt;</span> <span class="char">','</span>
340    <span class="special">&gt;</span>   <span class="identifier">double_</span>
341    <span class="special">&gt;</span>   <span class="char">'}'</span>
342    <span class="special">;</span>
343</pre>
344<p>
345        You will have some "deterministic points" in the grammar. Those
346        are the places where backtracking <span class="bold"><strong>cannot</strong></span>
347        occur. For our example above, when you get a <code class="computeroutput"><span class="char">'{'</span></code>,
348        you definitely must see an <code class="computeroutput"><span class="identifier">int_</span></code>
349        next. After that, you definitely must have a <code class="computeroutput"><span class="char">','</span></code>
350        next and then a <code class="computeroutput"><span class="identifier">person</span></code> and
351        so on until the final <code class="computeroutput"><span class="char">'}'</span></code>. Otherwise,
352        there is no point in proceeding and trying other branches, regardless where
353        they are. The input is definitely erroneous. When this happens, an expectation_failure
354        exception is thrown. Somewhere outward, the error handler will catch the
355        exception. In our case, it is caught in our <code class="computeroutput"><span class="identifier">on_error</span></code>
356        handler.
357      </p>
358<p>
359        Notice too that we subclass the <code class="computeroutput"><span class="identifier">employee_class</span></code>
360        from our <code class="computeroutput"><span class="identifier">error_handler</span></code>. By
361        doing so, we tell X3 that we want to call our <code class="computeroutput"><span class="identifier">error_handler</span></code>
362        whenever an exception is thrown somewhere inside the <code class="computeroutput"><span class="identifier">employee</span></code>
363        rule and whatever else it calls (i.e. the <code class="computeroutput"><span class="identifier">person</span></code>
364        and <code class="computeroutput"><span class="identifier">quoted_string</span></code> rules).
365      </p>
366<h5>
367<a name="spirit_x3.tutorials.error_handling.h5"></a>
368        <span class="phrase"><a name="spirit_x3.tutorials.error_handling.let_s_parse"></a></span><a class="link" href="error_handling.html#spirit_x3.tutorials.error_handling.let_s_parse">Let's
369        Parse</a>
370      </h5>
371<p>
372        Now we have the complete parse mechanism with error handling:
373      </p>
374<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">parse</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">input</span><span class="special">)</span>
375<span class="special">{</span>
376    <span class="keyword">using</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><span class="identifier">space</span><span class="special">;</span>
377    <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">iterator_type</span><span class="special">;</span>
378
379    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><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">&gt;</span> <span class="identifier">ast</span><span class="special">;</span>
380    <span class="identifier">iterator_type</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">input</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>
381    <span class="identifier">iterator_type</span> <span class="keyword">const</span> <span class="identifier">end</span> <span class="special">=</span> <span class="identifier">input</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span>
382
383    <span class="keyword">using</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">with</span><span class="special">;</span>
384    <span class="keyword">using</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">error_handler_tag</span><span class="special">;</span>
385    <span class="keyword">using</span> <span class="identifier">error_handler_type</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">error_handler</span><span class="special">&lt;</span><span class="identifier">iterator_type</span><span class="special">&gt;;</span>
386
387    <span class="comment">// Our error handler</span>
388    <span class="identifier">error_handler_type</span> <span class="identifier">error_handler</span><span class="special">(</span><span class="identifier">iter</span><span class="special">,</span> <span class="identifier">end</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span><span class="special">);</span>
389
390    <span class="comment">// Our parser</span>
391    <span class="keyword">using</span> <span class="identifier">client</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">employees</span><span class="special">;</span>
392    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser</span> <span class="special">=</span>
393        <span class="comment">// we pass our error handler to the parser so we can access</span>
394        <span class="comment">// it later in our on_error and on_sucess handlers</span>
395        <span class="identifier">with</span><span class="special">&lt;</span><span class="identifier">error_handler_tag</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">error_handler</span><span class="special">))</span>
396        <span class="special">[</span>
397            <span class="identifier">employees</span>
398        <span class="special">];</span>
399
400    <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">phrase_parse</span><span class="special">(</span><span class="identifier">iter</span><span class="special">,</span> <span class="identifier">end</span><span class="special">,</span> <span class="identifier">parser</span><span class="special">,</span> <span class="identifier">space</span><span class="special">,</span> <span class="identifier">ast</span><span class="special">);</span>
401
402    <span class="comment">// ... Some final reports here</span>
403<span class="special">}</span>
404</pre>
405<p>
406        Prior to calling <code class="computeroutput"><span class="identifier">phrase_parse</span></code>,
407        we first create an AST where parsed data will be stored:
408      </p>
409<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><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">&gt;</span> <span class="identifier">ast</span><span class="special">;</span>
410</pre>
411<p>
412        We also create the actual error handler, sending message to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span></code>:
413      </p>
414<pre class="programlisting"><span class="identifier">error_handler_type</span> <span class="identifier">error_handler</span><span class="special">(</span><span class="identifier">iter</span><span class="special">,</span> <span class="identifier">end</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span><span class="special">);</span>
415</pre>
416<p>
417        Then, we inject a reference to <code class="computeroutput"><span class="identifier">error_handler</span></code>,
418        using the <code class="computeroutput"><span class="identifier">with</span></code> directive
419        similar to what we did in the <a class="link" href="annotation.html#__tutorial_with_directive__">annotations
420        example</a>:
421      </p>
422<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser</span> <span class="special">=</span>
423    <span class="comment">// we pass our error handler to the parser so we can access</span>
424    <span class="comment">// it later in our on_error and on_sucess handlers</span>
425    <span class="identifier">with</span><span class="special">&lt;</span><span class="identifier">error_handler_tag</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">error_handler</span><span class="special">))</span>
426    <span class="special">[</span>
427        <span class="identifier">employees</span>
428    <span class="special">];</span>
429</pre>
430<p>
431        Now, if we give the parser an erroneous input:
432      </p>
433<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">bad_input</span> <span class="special">=</span> <span class="identifier">R</span><span class="string">"(
434{
435    23,
436    "</span><span class="identifier">Amanda</span><span class="string">",
437    "</span><span class="identifier">Stefanski</span><span class="string">",
438    1000.99
439},
440{
441    35,
442    "</span><span class="identifier">Angie</span><span class="string">",
443    "</span><span class="identifier">Chilcote</span><span class="string">",
444    2000.99
445},
446{
447    43,
448    'I am not a person!'    &lt;--- this should be a person
449    3000.99
450},
451{
452    22,
453    "</span><span class="identifier">Dorene</span><span class="string">",
454    "</span><span class="identifier">Dole</span><span class="string">",
455    2500.99
456},
457{
458    38,
459    "</span><span class="identifier">Rossana</span><span class="string">",
460    "</span><span class="identifier">Rafferty</span><span class="string">",
461    5000.99
462}
463)"</span><span class="special">;</span>
464</pre>
465<p>
466        The parser will complain as expected:
467      </p>
468<pre class="programlisting">-------------------------
469Now we have some errors
470In line 16:
471Error! Expecting: person here:
472    'I am not a person!'    &lt;--- this should be a person
473____^_
474-------------------------
475Parsing failed
476-------------------------
477</pre>
478</div>
479<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
480<td align="left"></td>
481<td align="right"><div class="copyright-footer">Copyright © 2001-2018 Joel de Guzman,
482      Hartmut Kaiser<p>
483        Distributed under the Boost Software License, Version 1.0. (See accompanying
484        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>)
485      </p>
486</div></td>
487</tr></table>
488<hr>
489<div class="spirit-nav">
490<a accesskey="p" href="rexpr.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="../quick_reference.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
491</div>
492</body>
493</html>
494