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 unsucessful 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> |
---|