functor_parser.html 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. <body>
  8. <table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
  9. <tr>
  10. <td width="10">
  11. </td>
  12. <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Functor
  13. Parser</b></font> </td>
  14. <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td>
  15. </tr>
  16. </table>
  17. <br>
  18. <table border="0">
  19. <tr>
  20. <td width="10"></td>
  21. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  22. <td width="30"><a href="list_parsers.html"><img src="theme/l_arr.gif" border="0"></a></td>
  23. <td width="30"><a href="refactoring.html"><img src="theme/r_arr.gif" border="0"></a></td>
  24. </tr>
  25. </table>
  26. <p>The simplest way to write your hand coded parser that works well with the rest
  27. of the Spirit library is to simply write a functor parser.</p>
  28. <p> A functor parser is expected to have the interface:</p>
  29. <pre>
  30. <code><span class=keyword>struct </span><span class=identifier>functor
  31. </span><span class=special>{
  32. </span><span class=keyword>typedef </span><span class=identifier>T </span><span class=identifier>result_t</span><span class=special>;
  33. </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;
  34. </span><span class=keyword>std::ptrdiff_t
  35. </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>;
  36. </span><span class=special>};
  37. </span></code></pre>
  38. <p> where typedef T result_t; is the attribute type of the parser that will be
  39. passed back to the match result (see <a href="indepth_the_parser.html">In-depth:
  40. The Parser</a>). If the parser does not need to return an attribute, this can
  41. simply be nil_t. The <span class=keyword><tt>std::ptrdiff_t</tt></span> result
  42. is the number of matching characters matched by your parser. A negative value
  43. flags an unsucessful match.</p>
  44. <p> A conforming functor parser can transformed into a well formed Spirit parser
  45. by wrapping it in the functor_parser template:</p>
  46. <pre>
  47. <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>;
  48. </span></code></pre>
  49. <h2>Example</h2>
  50. <p> The following example puts the functor_parser into action:</p>
  51. <pre>
  52. <code><span class=keyword>struct </span><span class=identifier>number_parser
  53. </span><span class=special>{
  54. </span><span class=keyword>typedef </span><span class=keyword>int </span><span class=identifier>result_t</span><span class=special>;
  55. </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;
  56. </span><span class=keyword>std::ptrdiff_t</span>
  57. <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
  58. </span><span class=special>{
  59. </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>())
  60. </span><span class=keyword>return </span><span class=special>-</span><span class=number>1</span><span class=special>;
  61. </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>;
  62. </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>)
  63. </span><span class=keyword>return </span><span class=special>-</span><span class=number>1</span><span class=special>;
  64. </span><span class=identifier>result </span><span class=special>= </span><span class=number>0</span><span class=special>;
  65. </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>;
  66. </span><span class=keyword>do
  67. </span><span class=special>{
  68. </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>);
  69. </span><span class=special>++</span><span class=identifier>len</span><span class=special>;
  70. </span><span class=special>++</span><span class=identifier>scan</span><span class=special>;
  71. </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>));
  72. </span><span class=keyword>return </span><span class=identifier>len</span><span class=special>;
  73. </span><span class=special>}
  74. </span><span class=special>};
  75. </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>;
  76. </span></code></pre>
  77. <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>
  78. <p>To further understand the implementation, see <a href="indepth_the_scanner.html">In-depth:
  79. 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>
  80. <pre>
  81. <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>);
  82. </span></code></pre>
  83. <table border="0">
  84. <tr>
  85. <td width="10"></td>
  86. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  87. <td width="30"><a href="list_parsers.html"><img src="theme/l_arr.gif" border="0"></a></td>
  88. <td width="30"><a href="refactoring.html"><img src="theme/r_arr.gif" border="0"></a></td>
  89. </tr>
  90. </table>
  91. <br>
  92. <hr size="1">
  93. <p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
  94. <br>
  95. <font size="2">Use, modification and distribution is subject to the Boost Software
  96. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  97. http://www.boost.org/LICENSE_1_0.txt)</font></p>
  98. <p class="copyright">&nbsp;</p>
  99. </body>
  100. </html>