roman.html 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Roman Numerals</title>
  5. <link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../../index.html" title="Spirit X3 3.0.4">
  8. <link rel="up" href="../tutorials.html" title="Tutorials">
  9. <link rel="prev" href="number_list_attribute___one_more__with_style.html" title="Number List Attribute - one more, with style">
  10. <link rel="next" href="employee.html" title="Employee - Parsing into structs">
  11. </head>
  12. <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
  13. <table cellpadding="2" width="100%"><tr>
  14. <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
  15. <td align="center"><a href="../../../../../../../index.html">Home</a></td>
  16. <td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
  17. <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
  18. <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
  19. <td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
  20. </tr></table>
  21. <hr>
  22. <div class="spirit-nav">
  23. <a accesskey="p" href="number_list_attribute___one_more__with_style.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorials.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="employee.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
  24. </div>
  25. <div class="section">
  26. <div class="titlepage"><div><div><h3 class="title">
  27. <a name="spirit_x3.tutorials.roman"></a><a class="link" href="roman.html" title="Roman Numerals">Roman Numerals</a>
  28. </h3></div></div></div>
  29. <p>
  30. This example demonstrates:
  31. </p>
  32. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  33. <li class="listitem">
  34. The Symbol Table
  35. </li>
  36. <li class="listitem">
  37. Non-terminal rules
  38. </li>
  39. </ul></div>
  40. <h5>
  41. <a name="spirit_x3.tutorials.roman.h0"></a>
  42. <span class="phrase"><a name="spirit_x3.tutorials.roman.symbol_table"></a></span><a class="link" href="roman.html#spirit_x3.tutorials.roman.symbol_table">Symbol
  43. Table</a>
  44. </h5>
  45. <p>
  46. The symbol table holds a dictionary of symbols where each symbol is a sequence
  47. of characters. The template class, can work efficiently with 8, 16, 32 and
  48. even 64 bit characters. Mutable data of type T are associated with each symbol.
  49. </p>
  50. <p>
  51. Traditionally, symbol table management is maintained separately outside the
  52. BNF grammar through semantic actions. Contrary to standard practice, the
  53. Spirit symbol table class <code class="computeroutput"><span class="identifier">symbols</span></code>
  54. is a parser. An object of which may be used anywhere in the EBNF grammar
  55. specification. It is an example of a dynamic parser. A dynamic parser is
  56. characterized by its ability to modify its behavior at run time. Initially,
  57. an empty symbols object matches nothing. At any time, symbols may be added
  58. or removed, thus, dynamically altering its behavior.
  59. </p>
  60. <p>
  61. Each entry in a symbol table may have an associated mutable data slot. In
  62. this regard, one can view the symbol table as an associative container (or
  63. map) of key-value pairs where the keys are strings.
  64. </p>
  65. <p>
  66. The symbols class expects one template parameter to specify the data type
  67. associated with each symbol: its attribute. There are a couple of namespaces
  68. in X3 where you can find various versions of the symbols class for handling
  69. different character encoding including ascii, standard, standard_wide, iso8859_1,
  70. and unicode. The default symbol parser type in the main x3 namespace is standard.
  71. </p>
  72. <p>
  73. Here's a parser for roman hundreds (100..900) using the symbol table. Keep
  74. in mind that the data associated with each slot is the parser's attribute
  75. (which is passed to attached semantic actions).
  76. </p>
  77. <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hundreds_</span> <span class="special">:</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;</span>
  78. <span class="special">{</span>
  79. <span class="identifier">hundreds_</span><span class="special">()</span>
  80. <span class="special">{</span>
  81. <span class="identifier">add</span>
  82. <span class="special">(</span><span class="string">"C"</span> <span class="special">,</span> <span class="number">100</span><span class="special">)</span>
  83. <span class="special">(</span><span class="string">"CC"</span> <span class="special">,</span> <span class="number">200</span><span class="special">)</span>
  84. <span class="special">(</span><span class="string">"CCC"</span> <span class="special">,</span> <span class="number">300</span><span class="special">)</span>
  85. <span class="special">(</span><span class="string">"CD"</span> <span class="special">,</span> <span class="number">400</span><span class="special">)</span>
  86. <span class="special">(</span><span class="string">"D"</span> <span class="special">,</span> <span class="number">500</span><span class="special">)</span>
  87. <span class="special">(</span><span class="string">"DC"</span> <span class="special">,</span> <span class="number">600</span><span class="special">)</span>
  88. <span class="special">(</span><span class="string">"DCC"</span> <span class="special">,</span> <span class="number">700</span><span class="special">)</span>
  89. <span class="special">(</span><span class="string">"DCCC"</span> <span class="special">,</span> <span class="number">800</span><span class="special">)</span>
  90. <span class="special">(</span><span class="string">"CM"</span> <span class="special">,</span> <span class="number">900</span><span class="special">)</span>
  91. <span class="special">;</span>
  92. <span class="special">}</span>
  93. <span class="special">}</span> <span class="identifier">hundreds</span><span class="special">;</span>
  94. </pre>
  95. <p>
  96. Here's a parser for roman tens (10..90):
  97. </p>
  98. <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">tens_</span> <span class="special">:</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;</span>
  99. <span class="special">{</span>
  100. <span class="identifier">tens_</span><span class="special">()</span>
  101. <span class="special">{</span>
  102. <span class="identifier">add</span>
  103. <span class="special">(</span><span class="string">"X"</span> <span class="special">,</span> <span class="number">10</span><span class="special">)</span>
  104. <span class="special">(</span><span class="string">"XX"</span> <span class="special">,</span> <span class="number">20</span><span class="special">)</span>
  105. <span class="special">(</span><span class="string">"XXX"</span> <span class="special">,</span> <span class="number">30</span><span class="special">)</span>
  106. <span class="special">(</span><span class="string">"XL"</span> <span class="special">,</span> <span class="number">40</span><span class="special">)</span>
  107. <span class="special">(</span><span class="string">"L"</span> <span class="special">,</span> <span class="number">50</span><span class="special">)</span>
  108. <span class="special">(</span><span class="string">"LX"</span> <span class="special">,</span> <span class="number">60</span><span class="special">)</span>
  109. <span class="special">(</span><span class="string">"LXX"</span> <span class="special">,</span> <span class="number">70</span><span class="special">)</span>
  110. <span class="special">(</span><span class="string">"LXXX"</span> <span class="special">,</span> <span class="number">80</span><span class="special">)</span>
  111. <span class="special">(</span><span class="string">"XC"</span> <span class="special">,</span> <span class="number">90</span><span class="special">)</span>
  112. <span class="special">;</span>
  113. <span class="special">}</span>
  114. <span class="special">}</span> <span class="identifier">tens</span><span class="special">;</span>
  115. </pre>
  116. <p>
  117. and, finally, for ones (1..9):
  118. </p>
  119. <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">ones_</span> <span class="special">:</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;</span>
  120. <span class="special">{</span>
  121. <span class="identifier">ones_</span><span class="special">()</span>
  122. <span class="special">{</span>
  123. <span class="identifier">add</span>
  124. <span class="special">(</span><span class="string">"I"</span> <span class="special">,</span> <span class="number">1</span><span class="special">)</span>
  125. <span class="special">(</span><span class="string">"II"</span> <span class="special">,</span> <span class="number">2</span><span class="special">)</span>
  126. <span class="special">(</span><span class="string">"III"</span> <span class="special">,</span> <span class="number">3</span><span class="special">)</span>
  127. <span class="special">(</span><span class="string">"IV"</span> <span class="special">,</span> <span class="number">4</span><span class="special">)</span>
  128. <span class="special">(</span><span class="string">"V"</span> <span class="special">,</span> <span class="number">5</span><span class="special">)</span>
  129. <span class="special">(</span><span class="string">"VI"</span> <span class="special">,</span> <span class="number">6</span><span class="special">)</span>
  130. <span class="special">(</span><span class="string">"VII"</span> <span class="special">,</span> <span class="number">7</span><span class="special">)</span>
  131. <span class="special">(</span><span class="string">"VIII"</span> <span class="special">,</span> <span class="number">8</span><span class="special">)</span>
  132. <span class="special">(</span><span class="string">"IX"</span> <span class="special">,</span> <span class="number">9</span><span class="special">)</span>
  133. <span class="special">;</span>
  134. <span class="special">}</span>
  135. <span class="special">}</span> <span class="identifier">ones</span><span class="special">;</span>
  136. </pre>
  137. <p>
  138. Now we can use <code class="computeroutput"><span class="identifier">hundreds</span></code>,
  139. <code class="computeroutput"><span class="identifier">tens</span></code> and <code class="computeroutput"><span class="identifier">ones</span></code>
  140. anywhere in our parser expressions. They are all parsers.
  141. </p>
  142. <h5>
  143. <a name="spirit_x3.tutorials.roman.h1"></a>
  144. <span class="phrase"><a name="spirit_x3.tutorials.roman.rules"></a></span><a class="link" href="roman.html#spirit_x3.tutorials.roman.rules">Rules</a>
  145. </h5>
  146. <p>
  147. Up until now, we've been inlining our parser expressions, passing them directly
  148. to the <code class="computeroutput"><span class="identifier">phrase_parse</span></code> function.
  149. The expression evaluates into a temporary, unnamed parser which is passed
  150. into the <code class="computeroutput"><span class="identifier">phrase_parse</span></code> function,
  151. used, and then destroyed. This is fine for small parsers. When the expressions
  152. get complicated, you'd want to break the expressions into smaller easier-to-understand
  153. pieces, name them, and refer to them from other parser expressions by name.
  154. </p>
  155. <p>
  156. A parser expression can be assigned to what is called a "rule".
  157. There are various ways to declare rules. The simplest form is:
  158. </p>
  159. <pre class="programlisting"><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">ID</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">r</span> <span class="special">=</span> <span class="string">"some-name"</span><span class="special">;</span>
  160. </pre>
  161. <h5>
  162. <a name="spirit_x3.tutorials.roman.h2"></a>
  163. <span class="phrase"><a name="spirit_x3.tutorials.roman.rule_id"></a></span><a class="link" href="roman.html#spirit_x3.tutorials.roman.rule_id">Rule
  164. ID</a>
  165. </h5>
  166. <p>
  167. At the very least, the rule needs an identification tag. This ID can be any
  168. struct or class type and need not be defined. Forward declaration would suffice.
  169. In subsequent tutorials, we will see that the rule ID can have additional
  170. functionalities for error handling and annotation.
  171. </p>
  172. <h5>
  173. <a name="spirit_x3.tutorials.roman.h3"></a>
  174. <span class="phrase"><a name="spirit_x3.tutorials.roman.rule_name"></a></span><a class="link" href="roman.html#spirit_x3.tutorials.roman.rule_name">Rule
  175. Name</a>
  176. </h5>
  177. <p>
  178. The name is optional, but is useful for debugging and error handling, as
  179. we'll see later. Notice that rule <code class="computeroutput"><span class="identifier">r</span></code>
  180. is declared <code class="computeroutput"><span class="keyword">const</span></code>. Rules are
  181. immutable and are best declared as <code class="computeroutput"><span class="keyword">const</span></code>.
  182. Rules are lightweight and can be passed around by value. Its only member
  183. variable is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>: its name.
  184. </p>
  185. <div class="note"><table border="0" summary="Note">
  186. <tr>
  187. <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td>
  188. <th align="left">Note</th>
  189. </tr>
  190. <tr><td align="left" valign="top"><p>
  191. Unlike Qi (Spirit V2), X3 rules can be used with both <code class="computeroutput"><span class="identifier">phrase_parse</span></code>
  192. and <code class="computeroutput"><span class="identifier">parse</span></code> without having
  193. to specify the skip parser
  194. </p></td></tr>
  195. </table></div>
  196. <h5>
  197. <a name="spirit_x3.tutorials.roman.h4"></a>
  198. <span class="phrase"><a name="spirit_x3.tutorials.roman.rule_attributes"></a></span><a class="link" href="roman.html#spirit_x3.tutorials.roman.rule_attributes">Rule
  199. Attributes</a>
  200. </h5>
  201. <p>
  202. For our next example, there's one more rule form you should know about:
  203. </p>
  204. <pre class="programlisting"><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">ID</span><span class="special">,</span> <span class="identifier">Attribute</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">r</span> <span class="special">=</span> <span class="string">"some-name"</span><span class="special">;</span>
  205. </pre>
  206. <p>
  207. The Attribute parameter specifies the attribute type of the rule. You've
  208. seen that our parsers can have an attribute. Recall that the <code class="computeroutput"><span class="identifier">double_</span></code> parser has an attribute of <code class="computeroutput"><span class="keyword">double</span></code>. To be precise, these are <span class="emphasis"><em>synthesized</em></span>
  209. attributes. The parser "synthesizes" the attribute value. If the
  210. parser is a function, think of them as function return values.
  211. </p>
  212. <h5>
  213. <a name="spirit_x3.tutorials.roman.h5"></a>
  214. <span class="phrase"><a name="spirit_x3.tutorials.roman.rule_definition"></a></span><a class="link" href="roman.html#spirit_x3.tutorials.roman.rule_definition">Rule
  215. Definition</a>
  216. </h5>
  217. <p>
  218. After having declared a rule, you need a definition for the rule. Example:
  219. </p>
  220. <pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">r_def</span> <span class="special">=</span> <span class="identifier">double_</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="char">','</span> <span class="special">&gt;&gt;</span> <span class="identifier">double_</span><span class="special">);</span>
  221. </pre>
  222. <p>
  223. By convention, rule definitions have a _def suffix. Like rules, rule definitions
  224. are immutable and are best declared as <code class="computeroutput"><span class="keyword">const</span></code>.
  225. </p>
  226. <a name="__tutorial_spirit_define__"></a><h5>
  227. <a name="spirit_x3.tutorials.roman.h6"></a>
  228. <span class="phrase"><a name="spirit_x3.tutorials.roman.boost_spirit_define"></a></span><a class="link" href="roman.html#spirit_x3.tutorials.roman.boost_spirit_define">BOOST_SPIRIT_DEFINE</a>
  229. </h5>
  230. <p>
  231. Now that we have a rule and its definition, we tie the rule with a rule definition
  232. using the <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code>
  233. macro:
  234. </p>
  235. <pre class="programlisting"><span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">r</span><span class="special">);</span>
  236. </pre>
  237. <p>
  238. Behind the scenes, what's actually happening is that we are defining a <code class="computeroutput"><span class="identifier">parse_rule</span></code> function in the client namespace
  239. that tells X3 how to invoke the rule. For example, given a rule named <code class="computeroutput"><span class="identifier">my_rule</span></code> and a corresponding definition
  240. named <code class="computeroutput"><span class="identifier">my_rule_def</span></code>, <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">my_rule</span><span class="special">)</span></code>
  241. expands to this code:
  242. </p>
  243. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">&gt;</span>
  244. <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="identifier">parse_rule</span><span class="special">(</span>
  245. <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">my_rule</span><span class="special">)</span>
  246. <span class="special">,</span> <span class="identifier">Iterator</span><span class="special">&amp;</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">last</span>
  247. <span class="special">,</span> <span class="identifier">Context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">,</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">my_rule</span><span class="special">)::</span><span class="identifier">attribute_type</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">)</span>
  248. <span class="special">{</span>
  249. <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">x3</span><span class="special">::</span><span class="identifier">unused</span><span class="special">;</span>
  250. <span class="keyword">static</span> <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">def_</span> <span class="special">=</span> <span class="identifier">my_rule_def</span><span class="special">;</span>
  251. <span class="keyword">return</span> <span class="identifier">def_</span><span class="special">.</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">unused</span><span class="special">,</span> <span class="identifier">attr</span><span class="special">);</span>
  252. <span class="special">}</span>
  253. </pre>
  254. <p>
  255. And so for each rule defined using <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code>,
  256. there is an overloaded <code class="computeroutput"><span class="identifier">parse_rule</span></code>
  257. function. At parse time, Spirit X3 recursively calls the appropriate <code class="computeroutput"><span class="identifier">parse_rule</span></code> function.
  258. </p>
  259. <div class="note"><table border="0" summary="Note">
  260. <tr>
  261. <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td>
  262. <th align="left">Note</th>
  263. </tr>
  264. <tr><td align="left" valign="top"><p>
  265. <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code> is
  266. variadic and may be used for one or more rules. Example: <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">r1</span><span class="special">,</span> <span class="identifier">r2</span><span class="special">,</span> <span class="identifier">r3</span><span class="special">);</span></code>
  267. </p></td></tr>
  268. </table></div>
  269. <h5>
  270. <a name="spirit_x3.tutorials.roman.h7"></a>
  271. <span class="phrase"><a name="spirit_x3.tutorials.roman.grammars"></a></span><a class="link" href="roman.html#spirit_x3.tutorials.roman.grammars">Grammars</a>
  272. </h5>
  273. <p>
  274. Unlike Qi (Spirit V2), X3 discards the notion of a grammar as a concrete
  275. entity for encapsulating rules. In X3, a grammar is simply a logical group
  276. of rules that work together, typically with a single top-level start rule
  277. which serves as the main entry point. X3 grammars are grouped using namespaces.
  278. The roman numeral grammar is a very nice and simple example of a grammar:
  279. </p>
  280. <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">parser</span>
  281. <span class="special">{</span>
  282. <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">eps</span><span class="special">;</span>
  283. <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span>
  284. <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">_val</span><span class="special">;</span>
  285. <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">_attr</span><span class="special">;</span>
  286. <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
  287. <span class="keyword">auto</span> <span class="identifier">set_zero</span> <span class="special">=</span> <span class="special">[&amp;](</span><span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">){</span> <span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="special">};</span>
  288. <span class="keyword">auto</span> <span class="identifier">add1000</span> <span class="special">=</span> <span class="special">[&amp;](</span><span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">){</span> <span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">+=</span> <span class="number">1000</span><span class="special">;</span> <span class="special">};</span>
  289. <span class="keyword">auto</span> <span class="identifier">add</span> <span class="special">=</span> <span class="special">[&amp;](</span><span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">){</span> <span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">+=</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span> <span class="special">};</span>
  290. <span class="identifier">x3</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">roman</span><span class="special">,</span> <span class="keyword">unsigned</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">roman</span> <span class="special">=</span> <span class="string">"roman"</span><span class="special">;</span>
  291. <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">roman_def</span> <span class="special">=</span>
  292. <span class="identifier">eps</span> <span class="special">[</span><span class="identifier">set_zero</span><span class="special">]</span>
  293. <span class="special">&gt;&gt;</span>
  294. <span class="special">(</span>
  295. <span class="special">-(+</span><span class="identifier">lit</span><span class="special">(</span><span class="char">'M'</span><span class="special">)</span> <span class="special">[</span><span class="identifier">add1000</span><span class="special">])</span>
  296. <span class="special">&gt;&gt;</span> <span class="special">-</span><span class="identifier">hundreds</span> <span class="special">[</span><span class="identifier">add</span><span class="special">]</span>
  297. <span class="special">&gt;&gt;</span> <span class="special">-</span><span class="identifier">tens</span> <span class="special">[</span><span class="identifier">add</span><span class="special">]</span>
  298. <span class="special">&gt;&gt;</span> <span class="special">-</span><span class="identifier">ones</span> <span class="special">[</span><span class="identifier">add</span><span class="special">]</span>
  299. <span class="special">)</span>
  300. <span class="special">;</span>
  301. <span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">roman</span><span class="special">);</span>
  302. <span class="special">}</span>
  303. </pre>
  304. <p>
  305. Things to take notice of:
  306. </p>
  307. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  308. <li class="listitem">
  309. The start rule's attribute is <code class="computeroutput"><span class="keyword">unsigned</span></code>.
  310. </li>
  311. <li class="listitem">
  312. <code class="computeroutput"><span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>
  313. gets a reference to the rule's synthesized attribute.
  314. </li>
  315. <li class="listitem">
  316. <code class="computeroutput"><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>
  317. gets a reference to the parser's synthesized attribute.
  318. </li>
  319. <li class="listitem">
  320. <code class="computeroutput"><span class="identifier">eps</span></code> is a special spirit
  321. parser that consumes no input but is always successful. We use it to
  322. initialize the rule's synthesized attribute, to zero before anything
  323. else. The actual parser starts at <code class="computeroutput"><span class="special">+</span><span class="identifier">lit</span><span class="special">(</span><span class="char">'M'</span><span class="special">)</span></code>, parsing
  324. roman thousands. Using <code class="computeroutput"><span class="identifier">eps</span></code>
  325. this way is good for doing pre and post initializations.
  326. </li>
  327. <li class="listitem">
  328. The rule <code class="computeroutput"><span class="identifier">roman</span></code> and the
  329. definition <code class="computeroutput"><span class="identifier">roman_def</span></code>
  330. are const objects.
  331. </li>
  332. <li class="listitem">
  333. The rule's ID is <code class="computeroutput"><span class="keyword">class</span> <span class="identifier">roman</span></code>. C++ allows you to declare the
  334. class in the actual template declaration as you can see in the example:
  335. </li>
  336. </ul></div>
  337. <pre class="programlisting"><span class="identifier">x3</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">roman</span><span class="special">,</span> <span class="keyword">unsigned</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">roman</span> <span class="special">=</span> <span class="string">"roman"</span><span class="special">;</span>
  338. </pre>
  339. <h5>
  340. <a name="spirit_x3.tutorials.roman.h8"></a>
  341. <span class="phrase"><a name="spirit_x3.tutorials.roman.let_s_parse_"></a></span><a class="link" href="roman.html#spirit_x3.tutorials.roman.let_s_parse_">Let's
  342. Parse!</a>
  343. </h5>
  344. <pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">parse</span><span class="special">(</span><span class="identifier">iter</span><span class="special">,</span> <span class="identifier">end</span><span class="special">,</span> <span class="identifier">roman</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
  345. <span class="keyword">if</span> <span class="special">(</span><span class="identifier">r</span> <span class="special">&amp;&amp;</span> <span class="identifier">iter</span> <span class="special">==</span> <span class="identifier">end</span><span class="special">)</span>
  346. <span class="special">{</span>
  347. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"-------------------------\n"</span><span class="special">;</span>
  348. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parsing succeeded\n"</span><span class="special">;</span>
  349. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"result = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
  350. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"-------------------------\n"</span><span class="special">;</span>
  351. <span class="special">}</span>
  352. <span class="keyword">else</span>
  353. <span class="special">{</span>
  354. <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">rest</span><span class="special">(</span><span class="identifier">iter</span><span class="special">,</span> <span class="identifier">end</span><span class="special">);</span>
  355. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"-------------------------\n"</span><span class="special">;</span>
  356. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parsing failed\n"</span><span class="special">;</span>
  357. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"stopped at: \": "</span> <span class="special">&lt;&lt;</span> <span class="identifier">rest</span> <span class="special">&lt;&lt;</span> <span class="string">"\"\n"</span><span class="special">;</span>
  358. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"-------------------------\n"</span><span class="special">;</span>
  359. <span class="special">}</span>
  360. </pre>
  361. <p>
  362. <code class="computeroutput"><span class="identifier">roman</span></code> is our roman numeral
  363. parser. This time around we are using the no-skipping version of the parse
  364. functions. We do not want to skip any spaces! We are also passing in an attribute,
  365. <code class="computeroutput"><span class="keyword">unsigned</span> <span class="identifier">result</span></code>,
  366. which will receive the parsed value.
  367. </p>
  368. <p>
  369. The full cpp file for this example can be found here: <a href="../../../../../example/x3/roman.cpp" target="_top">roman.cpp</a>
  370. </p>
  371. </div>
  372. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  373. <td align="left"></td>
  374. <td align="right"><div class="copyright-footer">Copyright &#169; 2001-2018 Joel de Guzman,
  375. Hartmut Kaiser<p>
  376. Distributed under the Boost Software License, Version 1.0. (See accompanying
  377. file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
  378. </p>
  379. </div></td>
  380. </tr></table>
  381. <hr>
  382. <div class="spirit-nav">
  383. <a accesskey="p" href="number_list_attribute___one_more__with_style.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorials.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="employee.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
  384. </div>
  385. </body>
  386. </html>