list_parsers.html 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2. <html>
  3. <head>
  4. <title>List Parsers</title>
  5. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  6. <link href="theme/style.css" rel="stylesheet" type="text/css">
  7. </head>
  8. <body>
  9. <table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
  10. <tr>
  11. <td width="10"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>&nbsp;</b></font></td>
  12. <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>List Parsers</b></font></td>
  13. <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td>
  14. </tr>
  15. </table>
  16. <br>
  17. <table border="0">
  18. <tr>
  19. <td width="10"></td>
  20. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  21. <td width="30"><a href="confix.html"><img src="theme/l_arr.gif" border="0"></a></td>
  22. <td width="30"><a href="functor_parser.html"><img src="theme/r_arr.gif" border="0"></a></td>
  23. </tr>
  24. </table>
  25. <p>List Parsers are generated by the special predefined parser generator object
  26. <tt>list_p</tt>, which generates parsers recognizing list structures
  27. of the type </p>
  28. <pre><span class=identifier> item </span><span class=special>&gt;&gt; </span><span class=special>*(</span><span class=identifier>delimiter </span><span class=special>&gt;&gt; </span><span class=identifier>item</span><span class=special>) </span><span class=special>&gt;&gt; </span><span class=special>!</span><span class=identifier>end</span></pre>
  29. <p>where <tt>item</tt> is an expression, delimiter is a delimiter and end is an
  30. optional closing expression. As you can see, the <tt>list_p</tt> generated parser
  31. does not recognize empty lists, i.e. the parser must find at least one item
  32. in the input stream to return a successful match. If you wish to also match
  33. an empty list, you can make your list_p optional with operator! An example where
  34. this utility parser is helpful is parsing comma separated C/C++ strings, which
  35. can be easily formulated as:</p>
  36. <pre><span class=special> </span><span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class=identifier>list_of_c_strings_rule
  37. </span><span class=special>= </span><span class=identifier>list_p</span><span class=special>(</span><span class=identifier>confix_p</span><span class=special>(</span><span class=literal>'\"'</span><span class=special>, </span><span class=special>*</span><span class=identifier>c_escape_char_p</span><span class=special>, </span><span class=literal>'\"'</span><span class=special>), </span><span class=literal>','</span><span class=special>)
  38. </span><span class=special>;</span></pre>
  39. <p>The <tt>confix_p</tt> and <tt>c_escape_char_p</tt> parser generators
  40. are described <a href="confix.html">here</a> and <a href="escape_char_parser.html">here</a>.</p>
  41. <p>The <tt>list_p</tt> parser generator object can be used to generate the following
  42. different types of List Parsers:</p>
  43. <table width="90%" border="0" align="center">
  44. <tr>
  45. <td colspan="2" class="table_title"><b>List Parsers</b></td>
  46. </tr>
  47. <tr>
  48. <td width="29%" height="27" class="table_cells"><b>list_p</b></td>
  49. <td width="71%" class="table_cells"><p><tt>list_p</tt> used by itself parses
  50. comma separated lists without special item formatting, i.e. everything
  51. in between two commas is matched as an <tt>item</tt>, no <tt>end</tt>
  52. of list token is matched</p></td>
  53. </tr>
  54. <tr>
  55. <td height="27" class="table_cells"><strong>list_p(delimiter)</strong></td>
  56. <td class="table_cells"><p>generates a list parser, which recognizes lists
  57. with the given <tt>delimiter</tt> and matches everything in between them
  58. as an <tt>item</tt>, no <tt>end</tt> of list token is matched</p></td>
  59. </tr>
  60. <tr>
  61. <td height="27" class="table_cells"><strong>list_p(item, delimiter)</strong></td>
  62. <td class="table_cells"><p>generates a list parser, which recognizes lists
  63. with the given <tt>delimiter</tt> and matches items based on the given
  64. item parser, no <tt>end</tt> of list token is matched</p></td>
  65. </tr>
  66. <tr>
  67. <td height="27" class="table_cells"><strong>list_p(item, delimiter, end)</strong></td>
  68. <td class="table_cells"><p>generates a list parser, which recognizes lists
  69. with the given <tt>delimiter</tt> and matches items based on the given
  70. <tt>item</tt> parser and additionally recognizes an optional <tt>end</tt>
  71. expression</p></td>
  72. </tr>
  73. </table>
  74. <p>All of the parameters to list_p can be single characters, strings
  75. or, if more complex parsing logic is required, auxiliary parsers, each of which
  76. is automatically converted to the corresponding parser type needed for successful
  77. parsing.</p>
  78. <p>If the <tt>item</tt> parser is an <tt>action_parser_category</tt> type (parser
  79. with an attached semantic action) we have to do something special. This happens,
  80. if the user wrote something like:</p>
  81. <pre><span class=special> </span><span class=identifier>list_p</span><span class=special>(</span><span class=identifier>item</span><span class=special>[</span><span class=identifier>func</span><span class=special>], </span><span class=identifier>delim</span><span class=special>)</span></pre>
  82. <p> where <tt>item</tt> is the parser matching one item of the list sequence and
  83. <tt>func</tt> is a functor to be called after matching one item. If we would
  84. do nothing, the resulting code would parse the sequence as follows:</p>
  85. <pre><span class=special> </span><span class=special>(</span><span class=identifier>item</span><span class=special>[</span><span class=identifier>func</span><span class=special>] </span><span class=special>- </span><span class=identifier>delim</span><span class=special>) </span><span class=special>&gt;&gt; </span><span class=special>*(</span><span class=identifier>delim </span><span class=special>&gt;&gt; </span><span class=special>(</span><span class=identifier>item</span><span class=special>[</span><span class=identifier>func</span><span class=special>] </span><span class=special>- </span><span class=identifier>delim</span><span class=special>))</span></pre>
  86. <p> what in most cases is not what the user expects. (If this <u>is</u> what you've
  87. expected, then please use one of the <tt>list_p</tt> generator
  88. functions <tt>direct()</tt>, which will inhibit refactoring of the <tt>item</tt>
  89. parser). To make the list parser behave as expected:</p>
  90. <pre><span class=special> </span><span class=special>(</span><span class=identifier>item </span><span class=special>- </span><span class=identifier>delim</span><span class=special>)[</span><span class=identifier>func</span><span class=special>] </span><span class=special>&gt;&gt; </span><span class=special>*(</span><span class=identifier>delim </span><span class=special>&gt;&gt; </span><span class=special>(</span><span class=identifier>item </span><span class=special>- </span><span class=identifier>delim</span><span class=special>)[</span><span class=identifier>func</span><span class=special>])</span></pre>
  91. <p> the actor attached to the item parser has to be re-attached to the <tt>(item
  92. - delim)</tt> parser construct, which will make the resulting list parser 'do
  93. the right thing'. This refactoring is done by the help of the <a href="refactoring.html">Refactoring
  94. Parsers</a>. Additionally special care must be taken, if the item parser is
  95. a <tt>unary_parser_category</tt> type parser as for instance:</p>
  96. <pre><span class=special> </span><span class=identifier>list_p</span><span class=special>(*</span><span class=identifier>anychar_p</span><span class=special>, </span><span class=literal>','</span><span class=special>)</span></pre>
  97. <p> which without any refactoring would result in </p>
  98. <pre><span class=special> </span><span class=special>(*</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>','</span><span class=special>))
  99. </span><span class=special>&gt;&gt; </span><span class=special>*( </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>','</span><span class=special>) </span><span class=special>&gt;&gt; </span><span class=special>(*</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>','</span><span class=special>)) </span><span class=special>)</span></pre>
  100. <p> and will not give the expected result (the first <tt>*anychar_p</tt> will
  101. eat up all the input up to the end of the input stream). So we have to refactor
  102. this into:</p>
  103. <pre><span class=special> </span><span class=special>*(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>','</span><span class=special>))
  104. </span><span class=special>&gt;&gt; </span><span class=special>*( </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>','</span><span class=special>) </span><span class=special>&gt;&gt; </span><span class=special>*(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>','</span><span class=special>)) </span><span class=special>)</span></pre>
  105. <p> what will give the correct result.</p>
  106. <p> The case, where the item parser is a combination of the two mentioned problems
  107. (i.e. the item parser is a unary parser with an attached action), is handled
  108. accordingly too:</p>
  109. <pre><span class=special> </span><span class=identifier>list_p</span><span class=special>((*</span><span class=identifier>anychar_p</span><span class=special>)[</span><span class=identifier>func</span><span class=special>], </span><span class=literal>','</span><span class=special>)</span></pre>
  110. <p> will be parsed as expected:</p>
  111. <pre><span class=special> </span><span class=special>(*(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>','</span><span class=special>)))[</span><span class=identifier>func</span><span class=special>]
  112. </span><span class=special>&gt;&gt; </span><span class=special>*( </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>','</span><span class=special>) </span><span class=special>&gt;&gt; </span><span class=special>(*(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>','</span><span class=special>)))[</span><span class=identifier>func</span><span class=special>] </span><span class=special>)</span></pre>
  113. <p>The required refactoring is implemented with the help of the <a href="refactoring.html">Refactoring
  114. Parsers</a>.</p>
  115. <table width="90%" border="0" align="center">
  116. <tr>
  117. <td colspan="2" class="table_title"><b>Summary of List Parser refactorings</b></td>
  118. </tr>
  119. <tr class="table_title">
  120. <td width="34%"><b>You write it as:</b></td>
  121. <td width="66%"><code><font face="Verdana, Arial, Helvetica, sans-serif">It
  122. is refactored to:</font></code></td>
  123. </tr>
  124. <tr>
  125. <td width="34%" class="table_cells"><code><span class=identifier>list_p</span><span class=special>(</span><span class=identifier>item</span><span class=special>,
  126. </span><span class=identifier>delimiter</span><span class=special>)</span></code></td>
  127. <td width="66%" class="table_cells"> <code><span class=special> (</span><span class=identifier>item
  128. </span><span class=special>- </span><span class=identifier>delimiter</span><span class=special>)
  129. <br>
  130. &gt;&gt; *(</span><span class=identifier>delimiter </span><span class=special>
  131. &gt;&gt; (</span><span class=identifier>item </span><span class=special>-
  132. </span><span class=identifier>delimiter</span><span class=special>))</span></code></td>
  133. </tr>
  134. <tr>
  135. <td width="34%" class="table_cells"><code><span class=identifier>list_p</span><span class=special>(</span><span class=identifier>item</span><span class=special>[</span><span class=identifier>func</span><span class=special>],
  136. </span><span class=identifier>delimiter</span><span class=special>)</span></code></td>
  137. <td width="66%" class="table_cells"> <code><span class=special> (</span><span class=identifier>item
  138. </span><span class=special> - </span><span class=identifier>delimiter</span><span class=special>)[</span><span class=identifier>func</span><span class=special>]
  139. <br>
  140. &gt;&gt; *(</span><span class=identifier>delimiter </span><span class=special>&gt;&gt;
  141. (</span><span class=identifier>item </span><span class=special>- </span><span class=identifier>delimiter</span><span class=special>)[</span><span class=identifier>func</span><span class=special>])</span></code></td>
  142. </tr>
  143. <tr>
  144. <td width="34%" class="table_cells"><code><span class=identifier>list_p</span><span class=special>(*</span><span class=identifier>item</span><span class=special>,
  145. </span><span class=identifier>delimiter</span><span class=special>)</span></code></td>
  146. <td width="66%" class="table_cells"> <code><span class=special>*(</span><span class=identifier>item
  147. </span><span class=special>- </span><span class=identifier>delimiter</span><span class=special>)
  148. <br>
  149. &gt;&gt; *(</span><span class=identifier>delimiter </span><span class=special>&gt;&gt;
  150. *(</span><span class=identifier>item </span><span class=special>- </span><span class=identifier>delimiter</span><span class=special>))</span></code></td>
  151. </tr>
  152. <tr>
  153. <td width="34%" class="table_cells"><code><span class=identifier>list_p</span><span class=special>((*</span><span class=identifier>item</span><span class=special>)[</span><span class=identifier>func</span><span class=special>],
  154. </span><span class=identifier>delimiter</span><span class=special>)</span></code></td>
  155. <td width="66%" class="table_cells"> <code><span class=special>(*(</span><span class=identifier>item
  156. </span><span class=special>- </span><span class=identifier>delimiter</span><span class=special>))[</span><span class=identifier>func</span><span class=special>]
  157. <br>
  158. &gt;&gt; *(</span><span class=identifier>delimiter </span><span class=special>&gt;&gt;
  159. (*(</span><span class=identifier>item </span><span class=special>- </span><span class=identifier>delimiter</span><span class=special>))[</span><span class=identifier>func</span><span class=special>])</span></code></td>
  160. </tr>
  161. </table>
  162. <p> <img height="16" width="15" src="theme/lens.gif"> <a href="../example/fundamental/list_parser.cpp">list_parser.cpp </a> sample shows the usage of the list_p utility parser:</p>
  163. <ol>
  164. <li>parsing a simple ',' delimited list w/o item formatting</li>
  165. <li> parsing a CSV list (comma separated values - strings, integers or reals)</li>
  166. <li>parsing a token list (token separated values - strings, integers or reals) <br>
  167. with an action parser directly attached to the item part of the list_p generated parser</li>
  168. </ol>
  169. <p>This is part of the Spirit distribution.</p>
  170. <table border="0">
  171. <tr>
  172. <td width="10"></td>
  173. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  174. <td width="30"><a href="confix.html"><img src="theme/l_arr.gif" border="0"></a></td>
  175. <td width="30"><a href="functor_parser.html"><img src="theme/r_arr.gif" border="0"></a></td>
  176. </tr>
  177. </table>
  178. <br>
  179. <hr size="1">
  180. <p class="copyright">Copyright &copy; 2001-2003 Hartmut Kaiser<br>
  181. <br>
  182. <font size="2">Use, modification and distribution is subject to the Boost Software
  183. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  184. http://www.boost.org/LICENSE_1_0.txt) </font> </p>
  185. </body>
  186. </html>