rexpr.html 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>RExpressions - Recursive ASTs!</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="annotation.html" title="Annotations - Decorating the ASTs">
  10. <link rel="next" href="error_handling.html" title="Error Handling">
  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="annotation.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="error_handling.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.rexpr"></a><a class="link" href="rexpr.html" title="RExpressions - Recursive ASTs!">RExpressions - Recursive ASTs!</a>
  28. </h3></div></div></div>
  29. <p>
  30. In this example, we'll explore more on how to create heierarchical ASTs.
  31. We will parse a minimalistic JSON-like language and compile the results into
  32. our data structures in the form of a tree.
  33. </p>
  34. <p>
  35. <span class="emphasis"><em>rexpr</em></span> is a parser for RExpressions, a language resembling
  36. a minimal subset of json, limited to a dictionary (composed of key=value
  37. pairs) where the value can itself be a string or a recursive dictionary.
  38. </p>
  39. <p>
  40. Here's an Example:
  41. </p>
  42. <pre class="programlisting"><span class="special">{</span>
  43. <span class="string">"color"</span> <span class="special">=</span> <span class="string">"blue"</span>
  44. <span class="string">"size"</span> <span class="special">=</span> <span class="string">"29 cm."</span>
  45. <span class="string">"position"</span> <span class="special">=</span> <span class="special">{</span>
  46. <span class="string">"x"</span> <span class="special">=</span> <span class="string">"123"</span>
  47. <span class="string">"y"</span> <span class="special">=</span> <span class="string">"456"</span>
  48. <span class="special">}</span>
  49. <span class="special">}</span>
  50. </pre>
  51. <p>
  52. This simple parser for X3 is intended as a minimal starting point. It is
  53. minimal, yet complete with all things necessary parts that make up rules
  54. (and grammars), except error handling and reporting.
  55. </p>
  56. <p>
  57. The example can be found here: <a href="../../../../../example/x3/rexpr/rexpr_min/rexpr.cpp" target="_top">rexpr.cpp</a>
  58. </p>
  59. <p>
  60. The same parser, but complete with error handling and reporting, better file
  61. organization, separate compilation of grammars, and a full test harness,
  62. can be found in this directory:
  63. </p>
  64. <p>
  65. <a href="../../../../../example/x3/rexpr/rexpr_full/" target="_top">rexpr/rexpr_full/</a>
  66. </p>
  67. <div class="note"><table border="0" summary="Note">
  68. <tr>
  69. <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td>
  70. <th align="left">Note</th>
  71. </tr>
  72. <tr><td align="left" valign="top"><p>
  73. rexpr_full is the canonical structure proposed as best practice on how
  74. parsers are written using Spirit X3.
  75. </p></td></tr>
  76. </table></div>
  77. <h5>
  78. <a name="spirit_x3.tutorials.rexpr.h0"></a>
  79. <span class="phrase"><a name="spirit_x3.tutorials.rexpr.the_ast"></a></span><a class="link" href="rexpr.html#spirit_x3.tutorials.rexpr.the_ast">The
  80. AST</a>
  81. </h5>
  82. <p>
  83. Here's the AST:
  84. </p>
  85. <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">client</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">ast</span>
  86. <span class="special">{</span>
  87. <span class="keyword">namespace</span> <span class="identifier">x3</span> <span class="special">=</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>
  88. <span class="keyword">struct</span> <span class="identifier">rexpr</span><span class="special">;</span>
  89. <span class="keyword">struct</span> <span class="identifier">rexpr_value</span> <span class="special">:</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span>
  90. <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span>
  91. <span class="special">,</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">forward_ast</span><span class="special">&lt;</span><span class="identifier">rexpr</span><span class="special">&gt;</span>
  92. <span class="special">&gt;</span>
  93. <span class="special">{</span>
  94. <span class="keyword">using</span> <span class="identifier">base_type</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">;</span>
  95. <span class="keyword">using</span> <span class="identifier">base_type</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=;</span>
  96. <span class="special">};</span>
  97. <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">rexpr_value</span><span class="special">&gt;</span> <span class="identifier">rexpr_map</span><span class="special">;</span>
  98. <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">rexpr_value</span><span class="special">&gt;</span> <span class="identifier">rexpr_key_value</span><span class="special">;</span>
  99. <span class="keyword">struct</span> <span class="identifier">rexpr</span>
  100. <span class="special">{</span>
  101. <span class="identifier">rexpr_map</span> <span class="identifier">entries</span><span class="special">;</span>
  102. <span class="special">};</span>
  103. <span class="special">}}</span>
  104. </pre>
  105. <p>
  106. <code class="computeroutput"><span class="identifier">x3</span><span class="special">::</span><span class="identifier">variant</span></code> is a support utility in Spirit
  107. X3 that extends <a href="http://www.boost.org/doc/html/variant.html" target="_top">Boost.Variant</a>.
  108. Typically, you use <a href="http://www.boost.org/doc/html/variant.html" target="_top">Boost.Variant</a>
  109. right out of the box and refer to a particular template instantiation using
  110. a typedef. For example:
  111. </p>
  112. <pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">my_variant</span><span class="special">;</span>
  113. </pre>
  114. <p>
  115. Instead of doing that, we create a <code class="computeroutput"><span class="keyword">class</span></code>
  116. (or <code class="computeroutput"><span class="keyword">struct</span></code> in the case) that
  117. subclasses from <code class="computeroutput"><span class="identifier">x3</span><span class="special">::</span><span class="identifier">variant</span></code>. By making the variant a subclass,
  118. you have a distinct type in your namespace. You also have control of the
  119. constructors and assignment operators, as well as giving you the freedom
  120. to add more functionality.
  121. </p>
  122. <p>
  123. <code class="computeroutput"><span class="identifier">rexpr_value</span></code> has two variant
  124. elements. It can either be a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
  125. or a <code class="computeroutput"><span class="identifier">rexpr</span></code>. Since <code class="computeroutput"><span class="identifier">rexpr</span></code> recursively contains a <code class="computeroutput"><span class="identifier">rexpr_value</span></code>, it has to be forward declared.
  126. This recursive data structure requires <code class="computeroutput"><span class="identifier">rexpr</span></code>
  127. to be wrapped in a <code class="computeroutput"><span class="identifier">x3</span><span class="special">::</span><span class="identifier">forward_ast</span></code> as shown in the declaration.
  128. </p>
  129. <p>
  130. We need to tell fusion about our <code class="computeroutput"><span class="identifier">rexpr</span></code>
  131. struct to make it a first-class fusion citizen:
  132. </p>
  133. <pre class="programlisting"><span class="identifier">BOOST_FUSION_ADAPT_STRUCT</span><span class="special">(</span>
  134. <span class="identifier">client</span><span class="special">::</span><span class="identifier">ast</span><span class="special">::</span><span class="identifier">rexpr</span><span class="special">,</span>
  135. <span class="identifier">entries</span>
  136. <span class="special">)</span>
  137. </pre>
  138. <p>
  139. So essentially, a <code class="computeroutput"><span class="identifier">rexpr_value</span></code>
  140. value is either a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> or a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">rexpr_value</span><span class="special">&gt;</span></code>.
  141. </p>
  142. <h5>
  143. <a name="spirit_x3.tutorials.rexpr.h1"></a>
  144. <span class="phrase"><a name="spirit_x3.tutorials.rexpr.walking_the_ast"></a></span><a class="link" href="rexpr.html#spirit_x3.tutorials.rexpr.walking_the_ast">Walking
  145. the AST</a>
  146. </h5>
  147. <p>
  148. We add a utility to print out the AST:
  149. </p>
  150. <pre class="programlisting"><span class="keyword">int</span> <span class="keyword">const</span> <span class="identifier">tabsize</span> <span class="special">=</span> <span class="number">4</span><span class="special">;</span>
  151. <span class="keyword">struct</span> <span class="identifier">rexpr_printer</span>
  152. <span class="special">{</span>
  153. <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span>
  154. <span class="identifier">rexpr_printer</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span>
  155. <span class="special">:</span> <span class="identifier">indent</span><span class="special">(</span><span class="identifier">indent</span><span class="special">)</span> <span class="special">{}</span>
  156. <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">rexpr</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">ast</span><span class="special">)</span> <span class="keyword">const</span>
  157. <span class="special">{</span>
  158. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="char">'{'</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>
  159. <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">entry</span> <span class="special">:</span> <span class="identifier">ast</span><span class="special">.</span><span class="identifier">entries</span><span class="special">)</span>
  160. <span class="special">{</span>
  161. <span class="identifier">tab</span><span class="special">(</span><span class="identifier">indent</span><span class="special">+</span><span class="identifier">tabsize</span><span class="special">);</span>
  162. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="char">'"'</span> <span class="special">&lt;&lt;</span> <span class="identifier">entry</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">"\" = "</span><span class="special">;</span>
  163. <span class="identifier">boost</span><span class="special">::</span><span class="identifier">apply_visitor</span><span class="special">(</span><span class="identifier">rexpr_printer</span><span class="special">(</span><span class="identifier">indent</span><span class="special">+</span><span class="identifier">tabsize</span><span class="special">),</span> <span class="identifier">entry</span><span class="special">.</span><span class="identifier">second</span><span class="special">);</span>
  164. <span class="special">}</span>
  165. <span class="identifier">tab</span><span class="special">(</span><span class="identifier">indent</span><span class="special">);</span>
  166. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="char">'}'</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>
  167. <span class="special">}</span>
  168. <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">text</span><span class="special">)</span> <span class="keyword">const</span>
  169. <span class="special">{</span>
  170. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="char">'"'</span> <span class="special">&lt;&lt;</span> <span class="identifier">text</span> <span class="special">&lt;&lt;</span> <span class="char">'"'</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>
  171. <span class="special">}</span>
  172. <span class="keyword">void</span> <span class="identifier">tab</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">spaces</span><span class="special">)</span> <span class="keyword">const</span>
  173. <span class="special">{</span>
  174. <span class="keyword">for</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="identifier">spaces</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
  175. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="char">' '</span><span class="special">;</span>
  176. <span class="special">}</span>
  177. <span class="keyword">int</span> <span class="identifier">indent</span><span class="special">;</span>
  178. <span class="special">};</span>
  179. </pre>
  180. <p>
  181. Traversing the AST is a recursive excercise. <code class="computeroutput"><span class="identifier">rexpr_printer</span></code>
  182. is a function object and the main entry point is <code class="computeroutput"><span class="keyword">void</span>
  183. <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">rexpr</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">ast</span><span class="special">)</span></code>. Notice how it recursively calls an instance
  184. of itself for each of the key value pairs, using <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">apply_visitor</span></code>.
  185. Before and after iterating through all the elements in the map, the braces
  186. are printed to surround the entire body, taking care of correct indentation
  187. at each point in the recursive traversal.
  188. </p>
  189. <p>
  190. The <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>
  191. for <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> should be self explanatory. It simply
  192. prints the text inside double quotes.
  193. </p>
  194. <h5>
  195. <a name="spirit_x3.tutorials.rexpr.h2"></a>
  196. <span class="phrase"><a name="spirit_x3.tutorials.rexpr.the_grammar"></a></span><a class="link" href="rexpr.html#spirit_x3.tutorials.rexpr.the_grammar">The
  197. Grammar</a>
  198. </h5>
  199. <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">client</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">parser</span>
  200. <span class="special">{</span>
  201. <span class="keyword">namespace</span> <span class="identifier">x3</span> <span class="special">=</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>
  202. <span class="keyword">namespace</span> <span class="identifier">ascii</span> <span class="special">=</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">ascii</span><span class="special">;</span>
  203. <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span>
  204. <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span>
  205. <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
  206. <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">string</span><span class="special">;</span>
  207. <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">rexpr_value</span><span class="special">,</span> <span class="identifier">ast</span><span class="special">::</span><span class="identifier">rexpr_value</span><span class="special">&gt;</span>
  208. <span class="identifier">rexpr_value</span> <span class="special">=</span> <span class="string">"rexpr_value"</span><span class="special">;</span>
  209. <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">rexpr</span><span class="special">,</span> <span class="identifier">ast</span><span class="special">::</span><span class="identifier">rexpr</span><span class="special">&gt;</span>
  210. <span class="identifier">rexpr</span> <span class="special">=</span> <span class="string">"rexpr"</span><span class="special">;</span>
  211. <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">rexpr_key_value</span><span class="special">,</span> <span class="identifier">ast</span><span class="special">::</span><span class="identifier">rexpr_key_value</span><span class="special">&gt;</span>
  212. <span class="identifier">rexpr_key_value</span> <span class="special">=</span> <span class="string">"rexpr_key_value"</span><span class="special">;</span>
  213. <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">quoted_string</span> <span class="special">=</span>
  214. <span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="char">'"'</span><span class="special">];</span>
  215. <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">rexpr_value_def</span> <span class="special">=</span>
  216. <span class="identifier">quoted_string</span> <span class="special">|</span> <span class="identifier">rexpr</span><span class="special">;</span>
  217. <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">rexpr_key_value_def</span> <span class="special">=</span>
  218. <span class="identifier">quoted_string</span> <span class="special">&gt;&gt;</span> <span class="char">'='</span> <span class="special">&gt;&gt;</span> <span class="identifier">rexpr_value</span><span class="special">;</span>
  219. <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">rexpr_def</span> <span class="special">=</span>
  220. <span class="char">'{'</span> <span class="special">&gt;&gt;</span> <span class="special">*</span><span class="identifier">rexpr_key_value</span> <span class="special">&gt;&gt;</span> <span class="char">'}'</span><span class="special">;</span>
  221. <span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">rexpr_value</span><span class="special">,</span> <span class="identifier">rexpr</span><span class="special">,</span> <span class="identifier">rexpr_key_value</span><span class="special">);</span>
  222. <span class="special">}}</span>
  223. </pre>
  224. <p>
  225. We declare three rules <code class="computeroutput"><span class="identifier">rexpr_value</span></code>,
  226. <code class="computeroutput"><span class="identifier">rexpr</span></code> and <code class="computeroutput"><span class="identifier">rexpr_key_value</span></code>.
  227. Same deal as before. The attributes declared for each rule are the same structures
  228. we declared in our AST above. These are the structures our rules will produce.
  229. </p>
  230. <p>
  231. So, going top-down (from the start rule), <code class="computeroutput"><span class="identifier">rexpr</span></code>
  232. is defined as zero or more <code class="computeroutput"><span class="identifier">rexpr_key_value</span></code>s
  233. enclosed inside the curly braces. That's the kleene star in action there:
  234. <code class="computeroutput"><span class="special">*</span><span class="identifier">rexpr_key_value</span></code>.
  235. </p>
  236. <div class="note"><table border="0" summary="Note">
  237. <tr>
  238. <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td>
  239. <th align="left">Note</th>
  240. </tr>
  241. <tr><td align="left" valign="top"><p>
  242. Take note of the convention: we use <code class="computeroutput"><span class="identifier">rexpr</span></code>
  243. name as the rule name and <code class="computeroutput"><span class="identifier">rexpr_def</span></code>
  244. as the rule definition name.
  245. </p></td></tr>
  246. </table></div>
  247. <p>
  248. To make the grammar clean, we capture the <code class="computeroutput"><span class="identifier">quoted_string</span></code>
  249. production using C++ <code class="computeroutput"><span class="keyword">auto</span></code>.
  250. </p>
  251. <p>
  252. <code class="computeroutput"><span class="identifier">rexpr_value</span></code> is a <code class="computeroutput"><span class="identifier">quoted_string</span></code> followed by the assignment
  253. operator <code class="computeroutput"><span class="char">'='</span></code>, followed by a <code class="computeroutput"><span class="identifier">rexpr_value</span></code>. <code class="computeroutput"><span class="identifier">rexpr_value</span></code>
  254. is a <code class="computeroutput"><span class="identifier">quoted_string</span></code> <span class="emphasis"><em>OR</em></span>
  255. a <code class="computeroutput"><span class="identifier">rexpr</span></code>. This uses the alternative
  256. operator <code class="computeroutput"><span class="special">|</span></code>, and maps nicely
  257. to the variant AST the rule is associated with.
  258. </p>
  259. <p>
  260. Finally, we associate the rules and their definitions:
  261. </p>
  262. <pre class="programlisting"><span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">rexpr_value</span><span class="special">,</span> <span class="identifier">rexpr</span><span class="special">,</span> <span class="identifier">rexpr_key_value</span><span class="special">);</span>
  263. </pre>
  264. </div>
  265. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  266. <td align="left"></td>
  267. <td align="right"><div class="copyright-footer">Copyright &#169; 2001-2018 Joel de Guzman,
  268. Hartmut Kaiser<p>
  269. Distributed under the Boost Software License, Version 1.0. (See accompanying
  270. 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>)
  271. </p>
  272. </div></td>
  273. </tr></table>
  274. <hr>
  275. <div class="spirit-nav">
  276. <a accesskey="p" href="annotation.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="error_handling.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
  277. </div>
  278. </body>
  279. </html>