numerics.html 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. <html>
  2. <head>
  3. <title>Numerics</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%">
  13. <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Numerics</b></font>
  14. </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="operators.html"><img src="theme/l_arr.gif" border="0"></a></td>
  24. <td width="30"><a href="rule.html"><img src="theme/r_arr.gif" border="0"></a></td>
  25. </tr>
  26. </table>
  27. <p>Similar to <tt>chlit</tt>, <tt>strlit</tt> etc. numeric parsers are also primitives.
  28. Numeric parsers are placed on
  29. a section of their own
  30. to give this important building
  31. block better focus. The framework includes a couple of predefined objects for
  32. parsing signed and unsigned integers and real numbers. These parsers are fully
  33. parametric. Most of the important aspects of numeric parsing can be finely adjusted
  34. to suit. This includes the radix base, the minimum and maximum number of allowable
  35. digits, the exponent, the fraction etc. Policies control the real number parsers'
  36. behavior. There are some predefined policies covering the most common real number
  37. formats but the user can supply her own when needed. </p>
  38. <h2>uint_parser</h2>
  39. <p>This class is the simplest among the members of the numerics package. The <tt>uint_parser</tt>
  40. can parse unsigned integers of arbitrary length and size. The <tt>uint_parser</tt>
  41. parser can be used to parse ordinary primitive C/C++ integers or even user defined
  42. scalars such as bigints (unlimited precision integers). Like most of the classes
  43. in Spirit, the <tt>uint_parser</tt> is a template class. Template parameters
  44. fine tune its behavior. The uint_parser is so flexible that the other numeric
  45. parsers are implemented using it as the backbone.</p>
  46. <pre><code><font color="#000000"><span class=identifier> </span><span class=keyword>template </span><span class=special>&lt;
  47. </span><span class=keyword>typename </span><span class=identifier>T </span><span class=special>= </span><span class="keyword">unsigned</span><span class=special>,
  48. </span><span class=keyword>int </span><span class=identifier>Radix </span><span class=special>= </span><span class=number>10</span><span class=special>,
  49. </span><span class=keyword>unsigned </span><span class=identifier>MinDigits </span><span class=special>= </span><span class=number>1</span><span class=special>,
  50. </span><span class=keyword>int </span><span class=identifier>MaxDigits </span><span class=special>= -</span><span class=number>1</span><span class=special>&gt;
  51. </span><span class=keyword>struct </span><span class=identifier>uint_parser </span><span class=special>{ </span><span class=comment>/*...*/ </span><span class=special>};</span></font></code></pre>
  52. <table width="90%" border="0" align="center">
  53. <tr>
  54. <td colspan="2" class="table_title">uint_parser template parameters</td>
  55. </tr>
  56. <tr>
  57. <td class="table_cells" width="21%"><b>T</b></td>
  58. <td class="table_cells" width="79%">The numeric base type of the numeric parser.
  59. Defaults to <tt>unsigned</tt></td>
  60. </tr>
  61. <tr>
  62. <td class="table_cells" width="21%"><b>Radix</b></td>
  63. <td class="table_cells" width="79%">The radix base. This can be either 2:
  64. binary, 8: octal, 10: decimal and 16: hexadecimal. Defaults to 10; decimal</td>
  65. </tr>
  66. <tr>
  67. <td class="table_cells" width="21%"><b>MinDigits</b></td>
  68. <td class="table_cells" width="79%">The minimum number of digits allowable</td>
  69. </tr>
  70. <tr>
  71. <td class="table_cells" width="21%"><b>MaxDigits</b></td>
  72. <td class="table_cells" width="79%">The maximum number of digits allowable.
  73. If this is -1, then the maximum limit becomes unbounded</td>
  74. </tr>
  75. </table>
  76. <br>
  77. <table width="90%" border="0" align="center">
  78. <tr>
  79. <td colspan="2" class="table_title">Predefined uint_parsers</td>
  80. </tr>
  81. <tr>
  82. <td class="table_cells" width="21%"><b>bin_p</b></td>
  83. <td class="table_cells" width="79%"><code><span class=identifier>uint_parser</span><span class=special>&lt;</span><span class=keyword>unsigned</span><span class=special>,
  84. </span><span class=number>2</span><span class=special>, </span><span class=number>1</span><span class=special>,
  85. -</span><span class=number>1</span><span class=special>&gt; </span><span class=keyword>const</span></code></td>
  86. </tr>
  87. <tr>
  88. <td class="table_cells" width="21%"><b>oct_p</b></td>
  89. <td class="table_cells" width="79%"><code><span class=identifier>uint_parser</span><span class=special>&lt;</span><span class=keyword>unsigned</span><span class=special>,
  90. </span><span class=number>8</span><span class=special>, </span><span class=number>1</span><span class=special>,
  91. -</span><span class=number>1</span><span class=special>&gt; </span><span class=keyword>const</span></code></td>
  92. </tr>
  93. <tr>
  94. <td class="table_cells" width="21%"><b>uint_p</b></td>
  95. <td class="table_cells" width="79%"><code><span class=identifier>uint_parser</span><span class=special>&lt;</span><span class=keyword>unsigned</span><span class=special>,
  96. </span><span class=number>10</span><span class=special>, </span><span class=number>1</span><span class=special>,
  97. -</span><span class=number>1</span><span class=special>&gt; </span><span class=keyword>const</span></code></td>
  98. </tr>
  99. <tr>
  100. <td class="table_cells" width="21%"><b>hex_p</b></td>
  101. <td class="table_cells" width="79%"><code><span class=identifier>uint_parser</span><span class=special>&lt;</span><span class=keyword>unsigned</span><span class=special>,
  102. </span><span class=number>16</span><span class=special>, </span><span class=number>1</span><span class=special>,
  103. -</span><span class=number>1</span><span class=special>&gt; </span><span class=keyword>const</span></code></td>
  104. </tr>
  105. </table>
  106. <p>The following example shows how the uint_parser can be used to parse thousand
  107. separated numbers. The example can correctly parse numbers such as 1,234,567,890.</p>
  108. <pre><span class=keyword> </span><span class=identifier>uint_parser</span><span class=special>&lt;</span><span class=keyword>unsigned</span><span class=special>, </span><span class=number>10</span><span class=special>, </span><span class=number>1</span><span class=special>, </span><span class=number>3</span><span class=special>&gt; </span><span class=identifier>uint3_p</span><span class=special>; </span><span class=comment>// 1..3 digits
  109. </span><span class=identifier>uint_parser</span><span class=special>&lt;</span><span class=keyword>unsigned</span><span class=special>, </span><span class=number>10</span><span class=special>, </span><span class=number>3</span><span class=special>, </span><span class=number>3</span><span class=special>&gt; </span><span class=identifier>uint3_3_p</span><span class=special>; </span><span class=comment>// exactly 3 digits
  110. </span><span class=identifier>ts_num_p </span><span class=special>= </span><span class=special>(</span><span class=identifier>uint3_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>uint3_3_p</span><span class=special>)); </span><span class=comment>// our thousand separated number parser</span></pre>
  111. <p><tt>bin_p</tt>, <tt>oct_p</tt>, <tt>uint_p</tt> and <tt>hex_p</tt> are parser
  112. generator objects designed to be used within expressions. Here's an example
  113. of a rule that parses comma delimited list of numbers (We've seen this <a href="quick_start.html#list_of_numbers">before</a>):</p>
  114. <pre><code><span class=identifier> </span><span class=identifier>list_of_numbers </span><span class=special>=</span> <span class=identifier>real_p </span><span class=special>&gt;&gt; *(</span><span class=literal>','</span> <span class=special>&gt;&gt; </span><span class=identifier>real_p</span><span class=special>)</span></code>;
  115. </pre>
  116. <p></p>
  117. <p>Later, we shall see how we can extract the actual numbers parsed by the numeric
  118. parsers. We shall deal with this when we get to the section on <a href="semantic_actions.html#specialized_actions">specialized
  119. actions</a>.</p>
  120. <h2>int_parser</h2>
  121. <p>The <tt>int_parser</tt> can parse signed integers of arbitrary length and size.
  122. This is almost the same as the <tt>uint_parser</tt>. The only difference is
  123. the additional task of parsing the <tt><span class="quotes">'+'</span></tt>
  124. or <tt class="quotes">'-'</tt> sign preceding the number. The class interface
  125. is the same as that of the uint_parser.<br>
  126. </p>
  127. <table width="90%" border="0" align="center">
  128. <tr>
  129. <td colspan="2" class="table_title">A predefined int_parser</td>
  130. </tr>
  131. <tr>
  132. <td class="table_cells" width="21%"><b>int_p</b></td>
  133. <td class="table_cells" width="79%"><span class=identifier><code>int_parser</code></span><code><span class=special>&lt;</span><span class=keyword>int</span><span class=special>,
  134. </span><span class=number>10</span><span class=special>, </span><span class=number>1</span><span class=special>,
  135. -</span><span class=number>1</span><span class=special>&gt; </span><span class=keyword>const</span></code></td>
  136. </tr>
  137. </table>
  138. <h2>real_parser</h2>
  139. <p>The <tt>real_parser</tt> can parse real numbers of arbitrary length and size
  140. limited by its parametric type <tt>T</tt>. The <tt>real_parser</tt> is a template
  141. class with 2 template parameters. Here's the <tt>real_parser</tt> template interface:</p>
  142. <pre><span class=keyword> template</span><span class=special>&lt;
  143. </span><span class=keyword>typename </span><span class=identifier>T </span><span class=special>= </span><span class=keyword>double</span><span class=special>,
  144. </span><span class=keyword>typename </span><span class=identifier>RealPoliciesT </span><span class=special>= </span><span class=identifier>ureal_parser_policies</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt; </span><span class=special>&gt;
  145. </span><span class=keyword> struct </span><span class=identifier>real_parser</span><span class=special>;</span></pre>
  146. <p>The first template parameter is its numeric base type <tt>T</tt>. This defaults
  147. to <tt>double</tt>. </p>
  148. <table width="80%" border="0" align="center">
  149. <tr>
  150. <td class="note_box"><img src="theme/bulb.gif" width="13" height="18"><b>
  151. Parsing special numeric types</b><br>
  152. <br>
  153. Notice that the numeric base type <tt>T</tt> can be specified by the user.
  154. This means that we can use the numeric parsers to parse user defined numeric
  155. types such as <tt>fixed_point</tt> (fixed point reals) and <tt>bigint</tt>
  156. (unlimited precision integers).</td>
  157. </tr>
  158. </table>
  159. <p>The second template parameter is a class that groups all the policies and defaults
  160. to <tt>ureal_parser_policies&lt;T&gt;</tt>. Policies control the real number
  161. parsers' behavior. The default policies provided are designed to parse C/C++
  162. style real numbers of the form <b>nnn.fff.Eeee</b> where <b>nnn</b> is the whole
  163. number part, <b>fff</b> is the fractional part, <b>E</b> is <tt class="quotes">'e'</tt>
  164. or <tt class="quotes">'E'</tt> and <b>eee</b> is the exponent optionally preceded
  165. by <tt class="quotes">'-'</tt> or <tt><span class="quotes">'+'</span></tt>.
  166. This corresponds to the following grammar, with the exception that plain integers
  167. without the decimal point are also accepted by default.</p>
  168. <pre><code><font color="#000000"><span class=keyword> </span><span class=identifier>floatingliteral
  169. </span><span class=special>= </span><span class=identifier>fractionalconstant </span><span class=special>&gt;&gt; </span><span class=special>!</span><span class=identifier>exponentpart
  170. </span><span class=special>| </span><span class=special>+</span><span class=identifier>digit_p </span><span class=special>&gt;&gt; </span><span class=identifier>exponentpart
  171. </span><span class=special>;
  172. </span><span class=identifier>fractionalconstant
  173. </span><span class=special>= </span><span class=special>*</span><span class=identifier>digit_p </span><span class=special>&gt;&gt; </span><span class=literal>'.' </span><span class=special>&gt;&gt; </span><span class=special>+</span><span class=identifier>digit_p
  174. </span><span class=special>| </span><span class=special>+</span><span class=identifier>digit_p </span><span class=special>&gt;&gt; </span><span class=literal>'.'
  175. </span><span class=special>;
  176. </span><span class=identifier>exponentpart
  177. </span><span class=special>= </span><span class=special>(</span><span class=literal>'e' </span><span class=special>| </span><span class=literal>'E'</span><span class=special>) </span><span class=special>&gt;&gt; </span><span class=special>!(</span><span class=literal>'+' </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>digit_p
  178. </span><span class=special>;</span></font></code></pre>
  179. <p>The default policies are provided to take care of the most common case (there
  180. are many ways to represent, and hence parse, real numbers). In most cases, the
  181. default setting of the <tt>real_parser</tt> is sufficient and can be used straight
  182. out of the box. Actually, there are four <tt>real_parser</tt>s pre-defined for
  183. immediate use:</p>
  184. <table width="90%" border="0" align="center">
  185. <tr>
  186. <td colspan="2" class="table_title">Predefined real_parsers</td>
  187. </tr>
  188. <tr>
  189. <td class="table_cells" width="21%"><b>ureal_p</b></td>
  190. <td class="table_cells" width="79%"><span class=identifier><code>real_parser</code></span><code><span class=special>&lt;</span><span class=keyword>double</span><span class=special>,
  191. </span><span class=identifier>ureal_parser_policies</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>&gt;
  192. &gt; </span><span class=keyword>const</span></code></td>
  193. </tr>
  194. <tr>
  195. <td class="table_cells" width="21%"><b>real_p</b></td>
  196. <td class="table_cells" width="79%"><span class=identifier><code>real_parser</code></span><code><span class=special>&lt;</span><span class=keyword>double</span><span class=special>,
  197. </span><span class=identifier>real_parser_policies</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>&gt;
  198. &gt; </span><span class=keyword>const</span></code></td>
  199. </tr>
  200. <tr>
  201. <td class="table_cells" width="21%"><b>strict_ureal_p</b></td>
  202. <td class="table_cells" width="79%"><span class=identifier><code>real_parser</code></span><code><span class=special>&lt;</span><span class=keyword>double</span><span class=special>,
  203. </span><span class=identifier>strict_ureal_parser_policies</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>&gt;
  204. &gt; </span><span class=keyword>const</span></code></td>
  205. </tr>
  206. <tr>
  207. <td class="table_cells" width="21%"><b>strict_real_p</b></td>
  208. <td class="table_cells" width="79%"><span class=identifier><code>real_parser</code></span><code><span class=special>&lt;</span><span class=keyword>double</span><span class=special>,
  209. </span><span class=identifier>strict_real_parser_policies</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>&gt;
  210. &gt; </span><span class=keyword>const</span></code></td>
  211. </tr>
  212. </table>
  213. <p>We've seen <tt>real_p</tt> before. <tt>ureal_p</tt> is its unsigned variant.</p>
  214. <h3><a name="strict_reals"></a>Strict Reals </h3>
  215. <p>Integer numbers are considered a subset of real numbers, so <tt>real_p</tt>
  216. and <tt>ureal_p</tt> recognize integer numbers (without a dot) as real numbers.
  217. <tt>strict_real_p</tt> and <tt>strict_ureal_p</tt> are the equivalent parsers
  218. that <strong>require</strong> a dot to be present for a number to be considered
  219. a successful match.</p>
  220. <h2>Advanced: real_parser policies</h2>
  221. <p>The parser policies break down real number parsing into 6 steps:</p>
  222. <table width="90%" border="0" align="center">
  223. <tr>
  224. <td class="table_cells">1</td>
  225. <td class="table_cells"><b>parse_sign</b></td>
  226. <td class="table_cells">Parse the prefix sign</td>
  227. </tr>
  228. <tr>
  229. <td class="table_cells">2</td>
  230. <td class="table_cells"><b>parse_n</b></td>
  231. <td class="table_cells">Parse the integer at the left of the decimal point</td>
  232. </tr>
  233. <tr>
  234. <td class="table_cells">3</td>
  235. <td class="table_cells"><b>parse_dot</b></td>
  236. <td class="table_cells">Parse the decimal point</td>
  237. </tr>
  238. <tr>
  239. <td class="table_cells">4</td>
  240. <td class="table_cells"><b>parse_frac_n</b></td>
  241. <td class="table_cells">Parse the fraction after the decimal point</td>
  242. </tr>
  243. <tr>
  244. <td class="table_cells">5</td>
  245. <td class="table_cells"><b>parse_exp</b></td>
  246. <td class="table_cells">Parse the exponent prefix (e.g. 'e')</td>
  247. </tr>
  248. <tr>
  249. <td class="table_cells">6</td>
  250. <td class="table_cells"><b>parse_exp_n</b></td>
  251. <td class="table_cells">Parse the actual exponent</td>
  252. </tr>
  253. </table>
  254. <p>And the interaction of these sub-parsing tasks is further controlled by these
  255. 3 policies:</p>
  256. <table width="90%" border="0" align="center">
  257. <tr>
  258. <td class="table_cells">1</td>
  259. <td class="table_cells"><b>allow_leading_dot</b></td>
  260. <td class="table_cells">Allow a leading dot to be present (&quot;.1&quot; becomes
  261. equivalent to &quot;0.1&quot;)</td>
  262. </tr>
  263. <tr>
  264. <td class="table_cells">2</td>
  265. <td class="table_cells"><b>allow_trailing_dot</b></td>
  266. <td class="table_cells">Allow a trailing dot to be present (&quot;1.&quot; becomes
  267. equivalent to &quot;1.0&quot;)</td>
  268. </tr>
  269. <tr>
  270. <td class="table_cells">3</td>
  271. <td class="table_cells"><b>expect_dot</b></td>
  272. <td class="table_cells">Require a dot to be present (disallows &quot;1&quot; to
  273. be equivalent to &quot;1.0&quot;)</td>
  274. </tr>
  275. </table>
  276. <p>[ <img src="theme/lens.gif" width="15" height="16"> From here on, required
  277. reading: <a href="scanner.html">The Scanner</a>, <a href="indepth_the_parser.html">In-depth
  278. The Parser</a> and <a href="indepth_the_scanner.html">In-depth The Scanner</a>
  279. ]</p>
  280. <h2>sign_parser and sign_p</h2>
  281. <p>Before we move on, a small utility parser is included here to ease the parsing
  282. of the <span class="quotes">'-'</span> or <span class="quotes">'+'</span> sign.
  283. While it is easy to write one:</p>
  284. <pre> <span class=identifier>sign_p </span><span class=special>= </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=literal>'-'</span><span class="special">)</span><span class=literal>;</span></pre>
  285. <p>it is not possible to extract the actual sign (positive or negative) without
  286. resorting to semantic actions. The sign_p parser has a bool attribute returned
  287. to the caller through the match object which, after parsing, is set to <strong>true</strong>
  288. if the parsed sign is negative. This attribute detects if the negative sign
  289. has been parsed. Examples:</p>
  290. <pre><span class=special> </span><span class=keyword>bool </span><span class=identifier>is_negative</span><span class=special>;
  291. </span><span class=identifier>r </span><span class=special>= </span><span class=identifier>sign_p</span><span class=special>[</span><span class=identifier>assign_a</span><span class=special>(</span><span class=identifier>is_negative</span><span class=special>)]</span><span class=special>;</span></pre>
  292. <p><span class=special></span>or simply...</p>
  293. <pre> <span class=comment>// directly extract the result from the match result's value</span>
  294. <span class=keyword>bool </span><span class=identifier>is_negative </span><span class=special>= </span><span class=identifier>sign_p</span><span class=special>.</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>scan</span><span class=special>).</span><span class=identifier>value</span><span class=special>();</span><span class=comment> </span></pre>
  295. <p>The sign_p parser expects attached semantic actions to have a signature (see
  296. <a href="semantic_actions.html#specialized_actions">Specialized Actions</a>
  297. for further detail) compatible with: </p>
  298. <p><b>Signature for functions:</b></p>
  299. <pre><code><font color="#000000"><span class=identifier> </span><span class=keyword>void </span><span class=identifier>func</span><span class=special>(</span><span class="keyword">bool</span><span class=identifier> is_negative</span><span class=special>);</span></font></code></pre>
  300. <p><b>Signature for functors:</b> </p>
  301. <pre><code><font color="#000000"><span class=special> </span><span class=keyword>struct </span><span class=identifier>ftor
  302. </span><span class=special>{
  303. </span><span class=keyword>void </span><span class=keyword>operator</span><span class=special>()(</span><span class="keyword">bool</span><span class=identifier> is_negative</span><span class=special>) </span><span class=keyword>const</span><span class=special>;
  304. </span><span class=special>};</span></font></code></pre>
  305. <h2><span class=identifier>ureal_parser_policies</span></h2>
  306. <pre><span class=comment> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>T</span><span class=special>&gt;
  307. </span><span class=keyword>struct </span><span class=identifier>ureal_parser_policies
  308. </span><span class=special>{
  309. </span><span class=keyword>typedef </span><span class=identifier>uint_parser</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>, </span><span class=number>10</span><span class=special>, </span><span class=number>1</span><span class=special>, -</span><span class=number>1</span><span class=special>&gt; </span><span class=identifier>uint_parser_t</span><span class=special>;
  310. </span><span class=keyword>typedef </span><span class=identifier>int_parser</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>, </span><span class=number>10</span><span class=special>, </span><span class=number>1</span><span class=special>, -</span><span class=number>1</span><span class=special>&gt; </span><span class=identifier>int_parser_t</span><span class=special>;
  311. </span><span class=keyword>static const bool</span> <span class=identifier>allow_leading_dot</span> <span class=special> =</span> <span class=literal>true</span><span class=special>;</span><span class=special>
  312. </span><span class=keyword>static const bool</span> <span class=identifier>allow_trailing_dot </span><span class=special>=</span> <span class=literal>true</span><span class=special>;</span><span class=special></span>
  313. <span class=special> </span><span class=keyword>static const bool</span> <span class=identifier>expect_dot</span> <span class=special> =</span> <span class=literal>false</span><span class=special>;</span><span class=special></span><span class=special><br>
  314. </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;
  315. </span><span class=keyword>static typename </span><span class=identifier>match_result</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>, </span><span class="identifier">nil_t</span><span class=special>&gt;::</span><span class=identifier>type
  316. parse_sign</span><span class=special>(</span><span class=identifier>ScannerT</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>)
  317. { </span><span class=keyword>return </span><span class=identifier>scan</span><span class=special>.</span><span class=identifier>no_match</span><span class=special>(); }
  318. </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;
  319. </span><span class=keyword>static typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>uint_parser_t</span><span class=special>, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type
  320. parse_n</span><span class=special>(</span><span class=identifier>ScannerT</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>)
  321. { </span><span class=keyword>return </span><span class=identifier>uint_parser_t</span><span class=special>().</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>scan</span><span class=special>); }
  322. </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;
  323. </span><span class=keyword>static typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>chlit</span><span class=special>&lt;&gt;, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type
  324. parse_dot</span><span class=special>(</span><span class=identifier>ScannerT</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>)
  325. { </span><span class=keyword>return </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>'.'</span><span class=special>).</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>scan</span><span class=special>); }
  326. </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;
  327. </span><span class=keyword>static typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>uint_parser_t</span><span class=special>, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type
  328. parse_frac_n</span><span class=special>(</span><span class=identifier>ScannerT</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>)
  329. { </span><span class=keyword>return </span><span class=identifier>uint_parser_t</span><span class=special>().</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>scan</span><span class=special>); }
  330. </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;
  331. </span><span class=keyword>static typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>chlit</span><span class=special>&lt;&gt;, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type
  332. parse_exp</span><span class=special>(</span><span class=identifier>ScannerT</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>)
  333. { </span><span class=keyword>return </span><span class=identifier>as_lower_d</span><span class=special>[</span><span class=literal>'e'</span><span class=special>].</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>scan</span><span class=special>); }
  334. </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;
  335. </span><span class=keyword>static typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=keyword>int</span><span class=identifier>_parser_t</span><span class=special>, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type
  336. parse_exp_n</span><span class=special>(</span><span class=identifier>ScannerT</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>)
  337. { </span><span class=keyword>return int</span><span class=identifier>_parser_t</span><span class=special>().</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>scan</span><span class=special>); }
  338. };
  339. </span></pre>
  340. <p><span class=special></span><span class=identifier>The default ureal_parser_policies
  341. uses the lower level integer numeric parsers to do its job. </span></p>
  342. <h2><span class=identifier>real_parser_policies</span></h2>
  343. <pre> <span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>T</span><span class=special>&gt;
  344. </span><span class=keyword>struct </span><span class=identifier>real_parser_policies </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>ureal_parser_policies</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;
  345. </span><span class=special>{
  346. </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;
  347. </span><span class=keyword>static </span><span class=keyword>typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>sign_parser</span><span class=special>, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type
  348. </span><span class=identifier>parse_sign</span><span class=special>(</span><span class=identifier>ScannerT</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>)
  349. </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>sign_p</span><span class=special>.</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>scan</span><span class=special>); </span><span class=special>}
  350. </span><span class=special>};</span></pre>
  351. <p>Notice how the real_parser_policies replaced <b><tt>parse_sign</tt></b> of
  352. the <b>u</b>real_parser_policies from which it is subclassed. The default real_parser_policies
  353. simply uses a <tt>sign_p</tt> instead of <tt>scan.no_match()</tt> in the <tt>parse_sign
  354. </tt> step. </p>
  355. <h2><span class=identifier>strict_ureal_parser_policies and strict_real_parser_policies</span></h2>
  356. <pre> <span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>T</span><span class=special>&gt;
  357. </span><span class=keyword>struct </span><span class=identifier>strict_ureal_parser_policies </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>ureal_parser_policies</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;
  358. </span><span class=special>{</span>
  359. <span class=special> </span><span class=keyword>static const bool</span> <span class=identifier>expect_dot</span><span class=special> =</span> <span class=literal>true</span><span class=special>;</span><span class=special></span><span class=special></span>
  360. <span class=special>};</span>
  361. <span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>T</span><span class=special>&gt;
  362. </span><span class=keyword>struct </span><span class=identifier>strict_real_parser_policies </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>real_parser_policies</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;
  363. </span><span class=special>{</span>
  364. <span class=special> </span><span class=keyword>static const bool</span> <span class=identifier>expect_dot</span><span class=special> =</span> <span class=literal>true</span><span class=special>;</span><span class=special></span><span class=special></span>
  365. <span class=special>};</span></pre>
  366. <p>Again, these policies replaced just the policies they wanted different from
  367. their superclasses.</p>
  368. <p><i>Specialized</i> real parser policies can reuse some of the defaults while
  369. replacing a few. For example, the following is a real number parser policy that
  370. parses thousands separated numbers with at most two decimal places and no exponent.
  371. </p>
  372. <p><img src="theme/lens.gif" width="15" height="16">The full source code can be
  373. viewed <a href="../example/fundamental/thousand_separated.cpp">here</a>. </p>
  374. <pre>
  375. <span class=identifier> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>T</span><span class=special>&gt;
  376. </span><span class=keyword>struct </span><span class=identifier>ts_real_parser_policies </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>ureal_parser_policies</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;
  377. {
  378. </span><span class=comment>// These policies can be used to parse thousand separated
  379. // numbers with at most 2 decimal digits after the decimal
  380. // point. e.g. 123,456,789.01
  381. </span><span class=keyword>typedef </span><span class=identifier>uint_parser</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>, </span><span class=number>10</span><span class=special>, </span><span class=number>1</span><span class=special>, </span><span class=number>2</span><span class=special>&gt; </span><span class=identifier>uint2_t</span><span class=special>;
  382. </span><span class=keyword>typedef </span><span class=identifier>uint_parser</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>, </span><span class=number>10</span><span class=special>, </span><span class=number>1</span><span class=special>, -</span><span class=number>1</span><span class=special>&gt; </span><span class=identifier>uint_parser_t</span><span class=special>;
  383. </span><span class=keyword>typedef </span><span class=identifier>int_parser</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>, </span><span class=number>10</span><span class=special>, </span><span class=number>1</span><span class=special>, -</span><span class=number>1</span><span class=special>&gt; </span><span class=identifier>int_parser_t</span><span class=special>;
  384. </span><span class=comment>////////////////////////////////// 2 decimal places Max
  385. </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;
  386. </span><span class=keyword>static typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>uint2_t</span><span class=special>, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type
  387. parse_frac_n</span><span class=special>(</span><span class=identifier>ScannerT</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>)
  388. { </span><span class=keyword>return </span><span class=identifier>uint2_t</span><span class=special>().</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>scan</span><span class=special>); }
  389. </span><span class=special> </span><span class=comment>////////////////////////////////// No exponent<br></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;
  390. </span><span class=keyword>static typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>chlit</span><span class=special>&lt;&gt;, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type
  391. parse_exp</span><span class=special>(</span><span class=identifier>ScannerT</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>)
  392. { </span><span class=keyword>return </span><span class=identifier>scan</span><span class=special>.</span><span class=identifier>no_match</span><span class=special>(); }
  393. </span><span class=special> </span><span class=comment>////////////////////////////////// No exponent<br></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;
  394. </span><span class=keyword>static typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>int_parser_t</span><span class=special>, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type
  395. parse_exp_n</span><span class=special>(</span><span class=identifier>ScannerT</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>)
  396. { </span><span class=keyword>return </span><span class=identifier>scan</span><span class=special>.</span><span class=identifier>no_match</span><span class=special>(); }
  397. </span><span class=comment>////////////////////////////////// Thousands separated numbers
  398. </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;
  399. </span><span class=keyword>static typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>uint_parser_t</span><span class=special>, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type
  400. <a name="scanner_save"></a>parse_n</span><span class=special>(</span><span class=identifier>ScannerT</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>)
  401. {
  402. </span><span class=keyword>typedef typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>uint_parser_t</span><span class=special>, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type RT</span><span class=special>;
  403. </span><span class="keyword">static </span><span class=identifier>uint_parser</span><span class=special>&lt;</span><span class=keyword>unsigned</span><span class=special>, </span><span class=number>10</span><span class=special>, </span><span class=number>1</span><span class=special>, </span><span class=number>3</span><span class=special>&gt; </span><span class=identifier>uint3_p</span><span class=special>;
  404. </span><span class="keyword">static </span><span class=identifier>uint_parser</span><span class=special>&lt;</span><span class=keyword>unsigned</span><span class=special>, </span><span class=number>10</span><span class=special>, </span><span class=number>3</span><span class=special>, </span><span class=number>3</span><span class=special>&gt; </span><span class=identifier>uint3_3_p</span><span class=special>;
  405. </span><span class=keyword>if </span><span class=special>(</span><span class=identifier>RT hit </span><span class=special>= </span><span class=identifier>uint3_p</span><span class=special>.</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>scan</span><span class=special>))
  406. {
  407. </span><span class=identifier>T n</span><span class=special>;
  408. </span><span class="keyword">typedef typename </span>ScannerT<span class="special">::</span>iterator_t iterator_t;<span class=special>
  409. </span>iterator_t save<span class="special"> = </span>scan.first<span class="special">;
  410. </span><span class=keyword>while </span><span class=special>(</span><span class=identifier>match</span><span class=special>&lt;&gt; </span><span class=identifier>next </span><span class=special>= (</span><span class=literal>',' </span><span class=special>&gt;&gt; </span><span class=identifier>uint3_3_p</span><span class=special>[</span><span class=identifier>assign_a</span><span class=special>(</span><span class=identifier>n</span><span class=special>)]).</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>scan</span><span class=special>))
  411. {
  412. </span><span class=identifier>hit</span><span class=special>.</span><span class=identifier>value</span><span class=special>() *= </span><span class=number>1000</span><span class=special>;
  413. </span><span class=identifier>hit</span><span class=special>.</span><span class=identifier>value</span><span class=special>() += </span><span class=identifier>n</span><span class=special>;
  414. </span><span class=identifier>scan</span><span class=special>.</span><span class=identifier>concat_match</span><span class=special>(</span><span class=identifier>hit</span><span class=special>, </span><span class=identifier>next</span><span class=special>);
  415. </span><span class="identifier">save </span><span class=special><span class="special">= </span></span><span class="identifier">scan</span><span class="special">.</span><span class="identifier">first</span><span class=special><span class="special">;</span>
  416. }
  417. </span>scan<span class="special">.</span>first<span class="special"> = </span>save<span class="special">;
  418. </span><span class=keyword>return </span><span class=identifier>hit</span><span class=special>;
  419. </span><span class=special> // Note: On erroneous input such as &quot;123,45&quot;, the result should<br> // be a partial match &quot;123&quot;. 'save' is used to makes sure that<br> // the scanner position is placed at the last *valid* parse<br> // position.<br> }
  420. </span><span class=keyword>return </span><span class=identifier>scan</span><span class=special>.</span><span class=identifier>no_match</span><span class=special>();
  421. }
  422. };</span></pre>
  423. <table border="0">
  424. <tr>
  425. <td width="10"></td>
  426. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  427. <td width="30"><a href="operators.html"><img src="theme/l_arr.gif" border="0"></a></td>
  428. <td width="30"><a href="rule.html"><img src="theme/r_arr.gif" border="0"></a></td>
  429. </tr>
  430. </table>
  431. <br>
  432. <hr size="1">
  433. <p class="copyright">Copyright &copy; 1998-2002 Joel de Guzman<br>
  434. <br>
  435. <font size="2">Use, modification and distribution is subject to the Boost Software
  436. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  437. http://www.boost.org/LICENSE_1_0.txt) </font> </p>
  438. <p>&nbsp;</p>
  439. </body>
  440. </html>