1<html> 2<head> 3<title>Functor Parser</title> 4<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 5<link rel="stylesheet" href="theme/style.css" type="text/css"> 6</head> 7 8<body> 9<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2"> 10 <tr> 11 <td width="10"> 12 </td> 13 <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Functor 14 Parser</b></font> </td> 15 <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> 16 </tr> 17</table> 18<br> 19<table border="0"> 20 <tr> 21 <td width="10"></td> 22 <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> 23 <td width="30"><a href="list_parsers.html"><img src="theme/l_arr.gif" border="0"></a></td> 24 <td width="30"><a href="refactoring.html"><img src="theme/r_arr.gif" border="0"></a></td> 25 </tr> 26</table> 27<p>The simplest way to write your hand coded parser that works well with the rest 28 of the Spirit library is to simply write a functor parser.</p> 29<p> A functor parser is expected to have the interface:</p> 30<pre> 31 <code><span class=keyword>struct </span><span class=identifier>functor 32 </span><span class=special>{ 33 </span><span class=keyword>typedef </span><span class=identifier>T </span><span class=identifier>result_t</span><span class=special>; 34 35 </span><span class=keyword>template </span><span class=special><</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>> 36 </span><span class=keyword>std::ptrdiff_t 37 </span><span class=keyword>operator</span><span class=special>()(</span><span class=identifier>ScannerT </span><span class=keyword>const</span><span class=special>& </span><span class=identifier>scan</span><span class=special>, </span><span class=identifier>result_t</span><span class=special>& </span><span class=identifier>result</span><span class=special>) </span><span class=keyword>const</span><span class=special>; 38 </span><span class=special>}; 39</span></code></pre> 40<p> where typedef T result_t; is the attribute type of the parser that will be 41 passed back to the match result (see <a href="indepth_the_parser.html">In-depth: 42 The Parser</a>). If the parser does not need to return an attribute, this can 43 simply be nil_t. The <span class=keyword><tt>std::ptrdiff_t</tt></span> result 44 is the number of matching characters matched by your parser. A negative value 45 flags an unsuccessful match.</p> 46<p> A conforming functor parser can transformed into a well formed Spirit parser 47 by wrapping it in the functor_parser template:</p> 48<pre> 49 <code><span class=identifier>functor_parser</span><span class=special><</span><span class=identifier>functor</span><span class=special>> </span><span class=identifier>functor_p</span><span class=special>; 50</span></code></pre> 51 52<h2>Example</h2> 53<p> The following example puts the functor_parser into action:</p> 54<pre> 55 <code><span class=keyword>struct </span><span class=identifier>number_parser 56 </span><span class=special>{ 57 </span><span class=keyword>typedef </span><span class=keyword>int </span><span class=identifier>result_t</span><span class=special>; 58 </span><span class=keyword>template </span><span class=special><</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>> 59 </span><span class=keyword>std::ptrdiff_t</span> 60 <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>ScannerT </span><span class=keyword>const</span><span class=special>& </span><span class=identifier>scan</span><span class=special>, </span><span class=identifier>result_t</span><span class=special>& </span><span class=identifier>result</span><span class=special>) </span><span class=keyword>const 61 </span><span class=special>{ 62 </span><span class=keyword>if </span><span class=special>(</span><span class=identifier>scan</span><span class=special>.</span><span class=identifier>at_end</span><span class=special>()) 63 </span><span class=keyword>return </span><span class=special>-</span><span class=number>1</span><span class=special>; 64 65 </span><span class=keyword>char </span><span class=identifier>ch </span><span class=special>= </span><span class=special>*</span><span class=identifier>scan</span><span class=special>; 66 </span><span class=keyword>if </span><span class=special>(</span><span class=identifier>ch </span><span class=special>< </span><span class=literal>'0' </span><span class=special>|| </span><span class=identifier>ch </span><span class=special>> </span><span class=literal>'9'</span><span class=special>) 67 </span><span class=keyword>return </span><span class=special>-</span><span class=number>1</span><span class=special>; 68 69 </span><span class=identifier>result </span><span class=special>= </span><span class=number>0</span><span class=special>; 70 </span><span class=keyword>std::ptrdiff_t</span> <span class=identifier>len </span><span class=special>= </span><span class=number>0</span><span class=special>; 71 72 </span><span class=keyword>do 73 </span><span class=special>{ 74 </span><span class=identifier>result </span><span class=special>= </span><span class=identifier>result</span><span class=special>*</span><span class=number>10 </span><span class=special>+ </span><span class=keyword>int</span><span class=special>(</span><span class=identifier>ch </span><span class=special>- </span><span class=literal>'0'</span><span class=special>); 75 </span><span class=special>++</span><span class=identifier>len</span><span class=special>; 76 </span><span class=special>++</span><span class=identifier>scan</span><span class=special>; 77 </span><span class=special>} </span><span class=keyword>while </span><span class=special>(!</span><span class=identifier>scan</span><span class=special>.</span><span class=identifier>at_end</span><span class=special>() </span><span class=special>&& </span><span class=special>(</span><span class=identifier>ch </span><span class=special>= </span><span class=special>*</span><span class=identifier>scan</span><span class=special>, </span><span class=identifier>ch </span><span class=special>>= </span><span class=literal>'0' </span><span class=special>&& </span><span class=identifier>ch </span><span class=special><= </span><span class=literal>'9'</span><span class=special>)); 78 79 </span><span class=keyword>return </span><span class=identifier>len</span><span class=special>; 80 </span><span class=special>} 81 </span><span class=special>}; 82 83 </span><span class=identifier>functor_parser</span><span class=special><</span><span class=identifier>number_parser</span><span class=special>> </span><span class=identifier>number_parser_p</span><span class=special>; 84</span></code></pre> 85<p> <img src="theme/lens.gif" width="15" height="16"> The full source code can be <a href="../example/fundamental/functor_parser.cpp">viewed here</a>. This is part of the Spirit distribution. </p> 86<p>To further understand the implementation, see <a href="indepth_the_scanner.html">In-depth: 87 The Scanner</a> for the scanner API details. We now have a parser <tt>number_parser_p</tt> that we can use just like any other Spirit parser. Example:</p> 88<pre> 89 <code><span class=identifier>r </span><span class=special>= </span><span class=identifier>number_parser_p </span><span class=special>>> </span><span class=special>*(</span><span class=literal>',' </span><span class=special>>> </span><span class=identifier>number_parser_p</span><span class=special>); 90</span></code></pre> 91<table border="0"> 92 <tr> 93 <td width="10"></td> 94 <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> 95 <td width="30"><a href="list_parsers.html"><img src="theme/l_arr.gif" border="0"></a></td> 96 <td width="30"><a href="refactoring.html"><img src="theme/r_arr.gif" border="0"></a></td> 97 </tr> 98</table> 99<br> 100<hr size="1"> 101<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br> 102 <br> 103<font size="2">Use, modification and distribution is subject to the Boost Software 104 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 105 http://www.boost.org/LICENSE_1_0.txt)</font></p> 106<p class="copyright"> </p> 107</body> 108</html> 109