parametric_parsers.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <html>
  2. <head>
  3. <title>Parametric Parsers</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>Parametric
  13. Parsers</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="predefined_actors.html"><img src="theme/l_arr.gif" border="0"></a></td>
  23. <td width="30"><a href="functional.html"><img src="theme/r_arr.gif" border="0"></a></td>
  24. </tr>
  25. </table>
  26. <p>We already have a hint of the dynamic nature of the Spirit framework. This
  27. capability is fundamental to Spirit. Dynamic parsing is a very powerful concept.
  28. We shall take this concept further through run-time parametric parsers. We are
  29. able to handle parsing tasks that are impossible to do with any EBNF syntax
  30. alone.</p>
  31. <h2>A Little Secret</h2>
  32. <p> A little critter called <tt>boost::ref</tt> lurking in the boost distribution
  33. is quite powerful beast when used with Spirit's primitive parsers. We are used
  34. to seeing the Spirit primitive parsers created with string or character literals
  35. such as:</p>
  36. <pre>
  37. <code><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>'A'</span><span class=special>)
  38. </span><span class=identifier>range_p</span><span class=special>(</span><span class=literal>'A'</span><span class=special>, </span><span class=literal>'Z'</span><span class=special>)
  39. </span><span class=identifier>str_p</span><span class=special>(</span><span class=string>&quot;Hello World&quot;</span><span class=special>)</span></code></pre>
  40. <p> str_p has a second form that accepts two iterators over the string:</p>
  41. <pre>
  42. <code><span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>first </span><span class=special>= </span><span class=string>&quot;My oh my&quot;</span><span class=special>;
  43. </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>last </span><span class=special>= </span><span class=identifier>first </span><span class=special>+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>strlen</span><span class=special>(</span><span class=identifier>first</span><span class=special>);
  44. </span><span class=identifier>str_p</span><span class=special>(</span><span class=identifier>first</span><span class=special>, </span><span class=identifier>last</span><span class=special>)</span></code></pre>
  45. <p> What is not obvious is that we can use <tt>boost::ref</tt> as well:</p>
  46. <pre>
  47. <code><span class=keyword>char </span><span class=identifier>ch </span><span class=special>= </span><span class=literal>'A'</span><span class=special>;
  48. </span><span class=keyword>char </span><span class=identifier>from </span><span class=special>= </span><span class=literal>'A'</span><span class=special>;
  49. </span><span class=keyword>char </span><span class=identifier>to </span><span class=special>= </span><span class=literal>'Z'</span><span class=special>;
  50. </span><span class=identifier>ch_p</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>ref</span><span class=special>(</span><span class=identifier>ch</span><span class=special>))
  51. </span><span class=identifier>range_p</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>ref</span><span class=special>(</span><span class=identifier>from</span><span class=special>), </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>ref</span><span class=special>(</span><span class=identifier>to</span><span class=special>))</span></code></pre>
  52. <p> When <tt>boost::ref</tt> is used, the actual parameters to <tt>ch_p</tt> and
  53. <tt>range_p</tt> are held by reference. This means that we can change the values
  54. of <tt>ch</tt>, <tt>from</tt> and <tt>to</tt> anytime and the corresponding
  55. <tt>ch_p</tt> and <tt>range_p</tt> parser will follow their dynamic values.
  56. Of course, since they are held by reference, you must make sure that the referenced
  57. object is not destructed while parsing.</p>
  58. <p> What about <tt>str_p</tt>?</p>
  59. <p> While the first form of <tt>str_p</tt> (the single argument form) is reserved
  60. for null terminated string constants, the second form (the two argument first/last
  61. iterator form) may be used:</p>
  62. <pre>
  63. <code><span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>first </span><span class=special>= </span><span class=string>&quot;My oh my&quot;</span><span class=special>;
  64. </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>last </span><span class=special>= </span><span class=identifier>first </span><span class=special>+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>strlen</span><span class=special>(</span><span class=identifier>first</span><span class=special>);
  65. </span><span class=identifier>str_p</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>ref</span><span class=special>(</span><span class=identifier>first</span><span class=special>), </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>ref</span><span class=special>(</span><span class=identifier>last</span><span class=special>))</span></code></pre>
  66. <table width="80%" border="0" align="center">
  67. <tr>
  68. <td class="note_box"> <img src="theme/note.gif" width="16" height="16"> Hey,
  69. don't forget <tt>chseq_p</tt>. All these apply to this seldom used primitive
  70. as well. </td>
  71. </tr>
  72. </table>
  73. <h2>Functional Parametric Primitives</h2>
  74. <pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>attribute<span class="special">/</span><span class="identifier">parametric</span><span class="special">.</span>hpp<span class="special">&gt;</span></pre>
  75. <p> Taking this further, Spirit includes functional versions of the primitives.
  76. Rather than taking in characters, strings or references to characters and strings
  77. (using boost::ref), the functional versions take in functions or functors.</p>
  78. <h3>f_chlit and f_ch_p</h3>
  79. <p> The functional version of <tt>chlit</tt>. This parser takes in a function
  80. or functor (function object). The function is expected to have an interface
  81. compatible with:</p>
  82. <pre>
  83. <code><span class=identifier>CharT </span><span class=identifier>func</span><span class=special>()</span></code></pre>
  84. <p> where CharT is the character type (e.g. <tt>char</tt>, <tt>int</tt>, <tt>wchar_t</tt>).</p>
  85. <p> The functor is expected to have an interface compatible with:</p>
  86. <pre>
  87. <code><span class=keyword>struct </span><span class=identifier>functor
  88. </span><span class=special>{
  89. </span><span class=identifier>CharT </span><span class=keyword>operator</span><span class=special>()() </span><span class=keyword>const</span><span class=special>;
  90. </span><span class=special>};</span></code></pre>
  91. <p> where CharT is the character type (e.g. <tt>char</tt>, <tt>int</tt>, <tt>wchar_t</tt>).</p>
  92. <p> Here's a contrived example:</p>
  93. <pre>
  94. <code><span class=keyword>struct </span><span class=identifier>X
  95. </span><span class=special>{
  96. </span><span class=keyword>char </span><span class=keyword>operator</span><span class=special>()() </span><span class=keyword>const
  97. </span><span class=special>{
  98. </span><span class=keyword>return </span><span class=literal>'X'</span><span class=special>; </span><span class=special>
  99. }
  100. </span><span class=special>};</span></code></pre>
  101. <p> Now we can use X to create our f_chlit parser:</p>
  102. <pre>
  103. <code><span class=identifier>f_ch_p</span><span class=special>(</span><span class=identifier>X</span><span class=special>())</span></code></pre>
  104. <h3>f_range and f_range_p</h3>
  105. <p> The functional version of <tt>range</tt>. This parser takes in a function
  106. or functor compatible with the interfaces above. The difference is that <tt>f_range</tt>
  107. (and <tt>f_range_p</tt>) expects two functors. One for the start and one for
  108. the end of the range.</p>
  109. <h3>f_chseq and f_chseq_p</h3>
  110. <p> The functional version of <tt>chseq</tt>. This parser takes in two functions
  111. or functors. One for the begin iterator and one for the end iterator. The function
  112. is expected to have an interface compatible with:</p>
  113. <pre>
  114. <code><span class=identifier>IteratorT </span><span class=identifier>func</span><span class=special>()</span></code></pre>
  115. <p> where <tt>IteratorT</tt> is the iterator type (e.g. <tt>char const*</tt>,
  116. <tt>wchar_t const*</tt>).</p>
  117. <p> The functor is expected to have an interface compatible with:</p>
  118. <pre>
  119. <code><span class=keyword>struct </span><span class=identifier>functor
  120. </span><span class=special>{
  121. </span><span class=identifier>IteratorT </span><span class=keyword>operator</span><span class=special>()() </span><span class=keyword>const</span><span class=special>;
  122. </span><span class=special>};</span></code></pre>
  123. <p> where <tt>IteratorT</tt> is the iterator type (e.g. <tt>char const*</tt>,
  124. <tt>wchar_t const*</tt>).</p>
  125. <h3>f_strlit and f_str_p</h3>
  126. <p> The functional version of <tt>strlit</tt>. This parser takes in two functions
  127. or functors compatible with the interfaces that <tt>f_chseq</tt> expects.</p>
  128. <table border="0">
  129. <tr>
  130. <td width="10"></td>
  131. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  132. <td width="30"><a href="predefined_actors.html"><img src="theme/l_arr.gif" border="0"></a></td>
  133. <td width="30"><a href="functional.html"><img src="theme/r_arr.gif" border="0"></a></td>
  134. </tr>
  135. </table>
  136. <br>
  137. <hr size="1">
  138. <p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
  139. <br>
  140. <font size="2">Use, modification and distribution is subject to the Boost Software
  141. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  142. http://www.boost.org/LICENSE_1_0.txt)</font></p>
  143. <p class="copyright">&nbsp;</p>
  144. </body>
  145. </html>