1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 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"><</span><span class="keyword">unsigned</span><span class="special">></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 94<span class="special">}</span> <span class="identifier">hundreds</span><span class="special">;</span> 95</pre> 96<p> 97 Here's a parser for roman tens (10..90): 98 </p> 99<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"><</span><span class="keyword">unsigned</span><span class="special">></span> 100<span class="special">{</span> 101 <span class="identifier">tens_</span><span class="special">()</span> 102 <span class="special">{</span> 103 <span class="identifier">add</span> 104 <span class="special">(</span><span class="string">"X"</span> <span class="special">,</span> <span class="number">10</span><span class="special">)</span> 105 <span class="special">(</span><span class="string">"XX"</span> <span class="special">,</span> <span class="number">20</span><span class="special">)</span> 106 <span class="special">(</span><span class="string">"XXX"</span> <span class="special">,</span> <span class="number">30</span><span class="special">)</span> 107 <span class="special">(</span><span class="string">"XL"</span> <span class="special">,</span> <span class="number">40</span><span class="special">)</span> 108 <span class="special">(</span><span class="string">"L"</span> <span class="special">,</span> <span class="number">50</span><span class="special">)</span> 109 <span class="special">(</span><span class="string">"LX"</span> <span class="special">,</span> <span class="number">60</span><span class="special">)</span> 110 <span class="special">(</span><span class="string">"LXX"</span> <span class="special">,</span> <span class="number">70</span><span class="special">)</span> 111 <span class="special">(</span><span class="string">"LXXX"</span> <span class="special">,</span> <span class="number">80</span><span class="special">)</span> 112 <span class="special">(</span><span class="string">"XC"</span> <span class="special">,</span> <span class="number">90</span><span class="special">)</span> 113 <span class="special">;</span> 114 <span class="special">}</span> 115 116<span class="special">}</span> <span class="identifier">tens</span><span class="special">;</span> 117</pre> 118<p> 119 and, finally, for ones (1..9): 120 </p> 121<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"><</span><span class="keyword">unsigned</span><span class="special">></span> 122<span class="special">{</span> 123 <span class="identifier">ones_</span><span class="special">()</span> 124 <span class="special">{</span> 125 <span class="identifier">add</span> 126 <span class="special">(</span><span class="string">"I"</span> <span class="special">,</span> <span class="number">1</span><span class="special">)</span> 127 <span class="special">(</span><span class="string">"II"</span> <span class="special">,</span> <span class="number">2</span><span class="special">)</span> 128 <span class="special">(</span><span class="string">"III"</span> <span class="special">,</span> <span class="number">3</span><span class="special">)</span> 129 <span class="special">(</span><span class="string">"IV"</span> <span class="special">,</span> <span class="number">4</span><span class="special">)</span> 130 <span class="special">(</span><span class="string">"V"</span> <span class="special">,</span> <span class="number">5</span><span class="special">)</span> 131 <span class="special">(</span><span class="string">"VI"</span> <span class="special">,</span> <span class="number">6</span><span class="special">)</span> 132 <span class="special">(</span><span class="string">"VII"</span> <span class="special">,</span> <span class="number">7</span><span class="special">)</span> 133 <span class="special">(</span><span class="string">"VIII"</span> <span class="special">,</span> <span class="number">8</span><span class="special">)</span> 134 <span class="special">(</span><span class="string">"IX"</span> <span class="special">,</span> <span class="number">9</span><span class="special">)</span> 135 <span class="special">;</span> 136 <span class="special">}</span> 137 138<span class="special">}</span> <span class="identifier">ones</span><span class="special">;</span> 139</pre> 140<p> 141 Now we can use <code class="computeroutput"><span class="identifier">hundreds</span></code>, 142 <code class="computeroutput"><span class="identifier">tens</span></code> and <code class="computeroutput"><span class="identifier">ones</span></code> 143 anywhere in our parser expressions. They are all parsers. 144 </p> 145<h5> 146<a name="spirit_x3.tutorials.roman.h1"></a> 147 <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> 148 </h5> 149<p> 150 Up until now, we've been inlining our parser expressions, passing them directly 151 to the <code class="computeroutput"><span class="identifier">phrase_parse</span></code> function. 152 The expression evaluates into a temporary, unnamed parser which is passed 153 into the <code class="computeroutput"><span class="identifier">phrase_parse</span></code> function, 154 used, and then destroyed. This is fine for small parsers. When the expressions 155 get complicated, you'd want to break the expressions into smaller easier-to-understand 156 pieces, name them, and refer to them from other parser expressions by name. 157 </p> 158<p> 159 A parser expression can be assigned to what is called a "rule". 160 There are various ways to declare rules. The simplest form is: 161 </p> 162<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">ID</span><span class="special">></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> 163</pre> 164<h5> 165<a name="spirit_x3.tutorials.roman.h2"></a> 166 <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 167 ID</a> 168 </h5> 169<p> 170 At the very least, the rule needs an identification tag. This ID can be any 171 struct or class type and need not be defined. Forward declaration would suffice. 172 In subsequent tutorials, we will see that the rule ID can have additional 173 functionalities for error handling and annotation. 174 </p> 175<h5> 176<a name="spirit_x3.tutorials.roman.h3"></a> 177 <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 178 Name</a> 179 </h5> 180<p> 181 The name is optional, but is useful for debugging and error handling, as 182 we'll see later. Notice that rule <code class="computeroutput"><span class="identifier">r</span></code> 183 is declared <code class="computeroutput"><span class="keyword">const</span></code>. Rules are 184 immutable and are best declared as <code class="computeroutput"><span class="keyword">const</span></code>. 185 Rules are lightweight and can be passed around by value. Its only member 186 variable is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>: its name. 187 </p> 188<div class="note"><table border="0" summary="Note"> 189<tr> 190<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td> 191<th align="left">Note</th> 192</tr> 193<tr><td align="left" valign="top"><p> 194 Unlike Qi (Spirit V2), X3 rules can be used with both <code class="computeroutput"><span class="identifier">phrase_parse</span></code> 195 and <code class="computeroutput"><span class="identifier">parse</span></code> without having 196 to specify the skip parser 197 </p></td></tr> 198</table></div> 199<h5> 200<a name="spirit_x3.tutorials.roman.h4"></a> 201 <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 202 Attributes</a> 203 </h5> 204<p> 205 For our next example, there's one more rule form you should know about: 206 </p> 207<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">ID</span><span class="special">,</span> <span class="identifier">Attribute</span><span class="special">></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> 208</pre> 209<p> 210 The Attribute parameter specifies the attribute type of the rule. You've 211 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> 212 attributes. The parser "synthesizes" the attribute value. If the 213 parser is a function, think of them as function return values. 214 </p> 215<h5> 216<a name="spirit_x3.tutorials.roman.h5"></a> 217 <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 218 Definition</a> 219 </h5> 220<p> 221 After having declared a rule, you need a definition for the rule. Example: 222 </p> 223<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">>></span> <span class="special">*(</span><span class="char">','</span> <span class="special">>></span> <span class="identifier">double_</span><span class="special">);</span> 224</pre> 225<p> 226 By convention, rule definitions have a _def suffix. Like rules, rule definitions 227 are immutable and are best declared as <code class="computeroutput"><span class="keyword">const</span></code>. 228 </p> 229<a name="__tutorial_spirit_define__"></a><h5> 230<a name="spirit_x3.tutorials.roman.h6"></a> 231 <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> 232 </h5> 233<p> 234 Now that we have a rule and its definition, we tie the rule with a rule definition 235 using the <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code> 236 macro: 237 </p> 238<pre class="programlisting"><span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">r</span><span class="special">);</span> 239</pre> 240<p> 241 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 242 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 243 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> 244 expands to this code: 245 </p> 246<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</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">></span> 247<span class="keyword">inline</span> <span class="keyword">bool</span> <span class="identifier">parse_rule</span><span class="special">(</span> 248 <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">my_rule</span><span class="special">)</span> 249 <span class="special">,</span> <span class="identifier">Iterator</span><span class="special">&</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">last</span> 250 <span class="special">,</span> <span class="identifier">Context</span> <span class="keyword">const</span><span class="special">&</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">&</span> <span class="identifier">attr</span><span class="special">)</span> 251<span class="special">{</span> 252 <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> 253 <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> 254 <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> 255<span class="special">}</span> 256</pre> 257<p> 258 And so for each rule defined using <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code>, 259 there is an overloaded <code class="computeroutput"><span class="identifier">parse_rule</span></code> 260 function. At parse time, Spirit X3 recursively calls the appropriate <code class="computeroutput"><span class="identifier">parse_rule</span></code> function. 261 </p> 262<div class="note"><table border="0" summary="Note"> 263<tr> 264<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td> 265<th align="left">Note</th> 266</tr> 267<tr><td align="left" valign="top"><p> 268 <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code> is 269 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> 270 </p></td></tr> 271</table></div> 272<h5> 273<a name="spirit_x3.tutorials.roman.h7"></a> 274 <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> 275 </h5> 276<p> 277 Unlike Qi (Spirit V2), X3 discards the notion of a grammar as a concrete 278 entity for encapsulating rules. In X3, a grammar is simply a logical group 279 of rules that work together, typically with a single top-level start rule 280 which serves as the main entry point. X3 grammars are grouped using namespaces. 281 The roman numeral grammar is a very nice and simple example of a grammar: 282 </p> 283<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">parser</span> 284<span class="special">{</span> 285 <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">eps</span><span class="special">;</span> 286 <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span> 287 <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">_val</span><span class="special">;</span> 288 <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">_attr</span><span class="special">;</span> 289 <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> 290 291 <span class="keyword">auto</span> <span class="identifier">set_zero</span> <span class="special">=</span> <span class="special">[&](</span><span class="keyword">auto</span><span class="special">&</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> 292 <span class="keyword">auto</span> <span class="identifier">add1000</span> <span class="special">=</span> <span class="special">[&](</span><span class="keyword">auto</span><span class="special">&</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> 293 <span class="keyword">auto</span> <span class="identifier">add</span> <span class="special">=</span> <span class="special">[&](</span><span class="keyword">auto</span><span class="special">&</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> 294 295 <span class="identifier">x3</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">roman</span><span class="special">,</span> <span class="keyword">unsigned</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">roman</span> <span class="special">=</span> <span class="string">"roman"</span><span class="special">;</span> 296 297 <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">roman_def</span> <span class="special">=</span> 298 <span class="identifier">eps</span> <span class="special">[</span><span class="identifier">set_zero</span><span class="special">]</span> 299 <span class="special">>></span> 300 <span class="special">(</span> 301 <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> 302 <span class="special">>></span> <span class="special">-</span><span class="identifier">hundreds</span> <span class="special">[</span><span class="identifier">add</span><span class="special">]</span> 303 <span class="special">>></span> <span class="special">-</span><span class="identifier">tens</span> <span class="special">[</span><span class="identifier">add</span><span class="special">]</span> 304 <span class="special">>></span> <span class="special">-</span><span class="identifier">ones</span> <span class="special">[</span><span class="identifier">add</span><span class="special">]</span> 305 <span class="special">)</span> 306 <span class="special">;</span> 307 308 <span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">roman</span><span class="special">);</span> 309<span class="special">}</span> 310</pre> 311<p> 312 Things to take notice of: 313 </p> 314<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 315<li class="listitem"> 316 The start rule's attribute is <code class="computeroutput"><span class="keyword">unsigned</span></code>. 317 </li> 318<li class="listitem"> 319 <code class="computeroutput"><span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code> 320 gets a reference to the rule's synthesized attribute. 321 </li> 322<li class="listitem"> 323 <code class="computeroutput"><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code> 324 gets a reference to the parser's synthesized attribute. 325 </li> 326<li class="listitem"> 327 <code class="computeroutput"><span class="identifier">eps</span></code> is a special spirit 328 parser that consumes no input but is always successful. We use it to 329 initialize the rule's synthesized attribute, to zero before anything 330 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 331 roman thousands. Using <code class="computeroutput"><span class="identifier">eps</span></code> 332 this way is good for doing pre and post initializations. 333 </li> 334<li class="listitem"> 335 The rule <code class="computeroutput"><span class="identifier">roman</span></code> and the 336 definition <code class="computeroutput"><span class="identifier">roman_def</span></code> 337 are const objects. 338 </li> 339<li class="listitem"> 340 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 341 class in the actual template declaration as you can see in the example: 342 </li> 343</ul></div> 344<pre class="programlisting"><span class="identifier">x3</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">roman</span><span class="special">,</span> <span class="keyword">unsigned</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">roman</span> <span class="special">=</span> <span class="string">"roman"</span><span class="special">;</span> 345</pre> 346<h5> 347<a name="spirit_x3.tutorials.roman.h8"></a> 348 <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 349 Parse!</a> 350 </h5> 351<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> 352 353<span class="keyword">if</span> <span class="special">(</span><span class="identifier">r</span> <span class="special">&&</span> <span class="identifier">iter</span> <span class="special">==</span> <span class="identifier">end</span><span class="special">)</span> 354<span class="special">{</span> 355 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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"><<</span> <span class="string">"Parsing succeeded\n"</span><span class="special">;</span> 357 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"result = "</span> <span class="special"><<</span> <span class="identifier">result</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 358 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"-------------------------\n"</span><span class="special">;</span> 359<span class="special">}</span> 360<span class="keyword">else</span> 361<span class="special">{</span> 362 <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> 363 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"-------------------------\n"</span><span class="special">;</span> 364 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Parsing failed\n"</span><span class="special">;</span> 365 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"stopped at: \": "</span> <span class="special"><<</span> <span class="identifier">rest</span> <span class="special"><<</span> <span class="string">"\"\n"</span><span class="special">;</span> 366 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"-------------------------\n"</span><span class="special">;</span> 367<span class="special">}</span> 368</pre> 369<p> 370 <code class="computeroutput"><span class="identifier">roman</span></code> is our roman numeral 371 parser. This time around we are using the no-skipping version of the parse 372 functions. We do not want to skip any spaces! We are also passing in an attribute, 373 <code class="computeroutput"><span class="keyword">unsigned</span> <span class="identifier">result</span></code>, 374 which will receive the parsed value. 375 </p> 376<p> 377 The full cpp file for this example can be found here: <a href="../../../../../example/x3/roman.cpp" target="_top">roman.cpp</a> 378 </p> 379</div> 380<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 381<td align="left"></td> 382<td align="right"><div class="copyright-footer">Copyright © 2001-2018 Joel de Guzman, 383 Hartmut Kaiser<p> 384 Distributed under the Boost Software License, Version 1.0. (See accompanying 385 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>) 386 </p> 387</div></td> 388</tr></table> 389<hr> 390<div class="spirit-nav"> 391<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> 392</div> 393</body> 394</html> 395