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">&</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">&</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!' <--- 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"><</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">></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">&</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">last</span> 179 <span class="special">,</span> <span class="identifier">Exception</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">Context</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">context</span><span class="special">)</span> 180 <span class="special">{</span> 181 <span class="keyword">auto</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">get</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><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">&</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"><</span><span class="identifier">error_handler_tag</span><span class="special">>(</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"><</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">></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"><</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">></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"><</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">></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">>></span> <span class="special">+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">>></span> <span class="char">'"'</span><span class="special">];</span> 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">></span> <span class="char">','</span> <span class="special">></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">></span> <span class="identifier">int_</span> <span class="special">></span> <span class="char">','</span> 312 <span class="special">></span> <span class="identifier">person</span> <span class="special">></span> <span class="char">','</span> 313 <span class="special">></span> <span class="identifier">double_</span> 314 <span class="special">></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">>></span> <span class="special">*(</span><span class="char">','</span> <span class="special">>></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">></span> <span class="char">','</span> <span class="special">></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">></span> <span class="identifier">int_</span> <span class="special">></span> <span class="char">','</span> 339 <span class="special">></span> <span class="identifier">person</span> <span class="special">></span> <span class="char">','</span> 340 <span class="special">></span> <span class="identifier">double_</span> 341 <span class="special">></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">&</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"><</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> <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"><</span><span class="identifier">iterator_type</span><span class="special">>;</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"><</span><span class="identifier">error_handler_tag</span><span class="special">>(</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"><</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> <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"><</span><span class="identifier">error_handler_tag</span><span class="special">>(</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!' <--- 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!' <--- 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