Sophie

Sophie

distrib > Mandriva > 9.1 > i586 > by-pkgid > b9ba69a436161613d8fb030c8c726a8e > files > 421

spirit-1.5.1-2mdk.noarch.rpm

<html>
<head>
<title>Functor Parser</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="theme/style.css" type="text/css">
</head>

<body>
<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
  <tr> 
    <td width="10"> 
    </td>
    <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Functor 
      Parser</b></font> </td>
    <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td>
  </tr>
</table>
<br>
<table border="0">
  <tr>
    <td width="10"></td>
    <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
    <td width="30"><a href="list_parsers.html"><img src="theme/l_arr.gif" border="0"></a></td>
    <td width="20"><a href="refactoring.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
</table>
<p>The simplest way to write your hand coded parser that works well with the rest 
  of the Spirit library is to simply write a functor parser.</p>
<p> A functor parser is expected to have the interface:</p>
<pre>
    <code><span class=keyword>struct </span><span class=identifier>functor
    </span><span class=special>{
        </span><span class=keyword>typedef </span><span class=identifier>T </span><span class=identifier>result_t</span><span class=special>;

        </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>&gt;
        </span><span class=keyword>int </span><span class=keyword>operator</span><span class=special>()(</span><span class=identifier>ScannerT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>, </span><span class=identifier>result_t</span><span class=special>&amp; </span><span class=identifier>result</span><span class=special>) </span><span class=keyword>const</span><span class=special>;
    </span><span class=special>};
</span></code></pre>
<p> where typedef T result_t; is the attribute type of the parser that will be 
  passed back to the match result (see <a href="indepth_the_parser.html">In-depth: 
  The Parser</a>). If the parser does not need to return an attribute, this can 
  simply be nil_t. The int result is the number of matching characters matched 
  by your parser. A negative value flags an unsucessful match.</p>
<p> A conforming functor parser can transformed into a well formed Spirit parser 
  by wrapping it in the functor_parser template:</p>
<pre>
    <code><span class=identifier>functor_parser</span><span class=special>&lt;</span><span class=identifier>functor</span><span class=special>&gt; </span><span class=identifier>functor_p</span><span class=special>;
</span></code></pre>
<a name="example"></a>
<h2>Example</h2>
<p> The following example puts the functor_parser into action:</p>
<pre>
    <code><span class=keyword>struct </span><span class=identifier>number_parser
    </span><span class=special>{
        </span><span class=keyword>typedef </span><span class=keyword>int </span><span class=identifier>result_t</span><span class=special>;
        </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>&gt;
        </span><span class=keyword>int
        </span><span class=keyword>operator</span><span class=special>()(</span><span class=identifier>ScannerT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>, </span><span class=identifier>result_t</span><span class=special>&amp; </span><span class=identifier>result</span><span class=special>) </span><span class=keyword>const
        </span><span class=special>{
            </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>())
                </span><span class=keyword>return </span><span class=special>-</span><span class=number>1</span><span class=special>;

            </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>;
            </span><span class=keyword>if </span><span class=special>(</span><span class=identifier>ch </span><span class=special>&lt; </span><span class=literal>'0' </span><span class=special>|| </span><span class=identifier>ch </span><span class=special>&gt; </span><span class=literal>'9'</span><span class=special>)
                </span><span class=keyword>return </span><span class=special>-</span><span class=number>1</span><span class=special>;

            </span><span class=identifier>result </span><span class=special>= </span><span class=number>0</span><span class=special>;
            </span><span class=keyword>int </span><span class=identifier>len </span><span class=special>= </span><span class=number>0</span><span class=special>;

            </span><span class=keyword>do
            </span><span class=special>{
                </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>);
                </span><span class=special>++</span><span class=identifier>len</span><span class=special>;
                </span><span class=special>++</span><span class=identifier>scan</span><span class=special>;
            </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>&amp;&amp; </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>&gt;= </span><span class=literal>'0' </span><span class=special>&amp;&amp; </span><span class=identifier>ch </span><span class=special>&lt;= </span><span class=literal>'9'</span><span class=special>));

            </span><span class=keyword>return </span><span class=identifier>len</span><span class=special>;
        </span><span class=special>}
    </span><span class=special>};

    </span><span class=identifier>functor_parser</span><span class=special>&lt;</span><span class=identifier>number_parser</span><span class=special>&gt; </span><span class=identifier>number_parser_p</span><span class=special>;
</span></code></pre>
<p> To further understand the implementation, see <a href="indepth_the_scanner.html">In-depth: 
  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>
<pre>
    <code><span class=identifier>r </span><span class=special>= </span><span class=identifier>number_parser_p </span><span class=special>&gt;&gt; </span><span class=special>*(</span><span class=literal>',' </span><span class=special>&gt;&gt; </span><span class=identifier>number_parser_p</span><span class=special>);
</span></code></pre>
<table border="0">
  <tr> 
    <td width="10"></td>
    <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
    <td width="30"><a href="list_parsers.html"><img src="theme/l_arr.gif" border="0"></a></td>
    <td width="20"><a href="refactoring.html"><img src="theme/r_arr.gif" border="0"></a></td>
  </tr>
</table>
<br>
<hr size="1">
<p class="copyright">Copyright &copy; 1998-2002 Joel de Guzman<br>
  <br>
  <font size="2">Permission to copy, use, modify, sell and distribute this document 
  is granted provided this copyright notice appears in all copies. This document 
  is provided &quot;as is&quot; without express or implied warranty, and with 
  no claim as to its suitability for any purpose.</font></p>
<p class="copyright">&nbsp;</p>
</body>
</html>