minimal.html 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>X3 Program Structure</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="employee.html" title="Employee - Parsing into structs">
  10. <link rel="next" href="annotation.html" title="Annotations - Decorating the ASTs">
  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="employee.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="annotation.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.minimal"></a><a class="link" href="minimal.html" title="X3 Program Structure">X3 Program Structure</a>
  28. </h3></div></div></div>
  29. <p>
  30. As a prerequisite in understanding this tutorial, please review the previous
  31. <a class="link" href="employee.html" title="Employee - Parsing into structs">employee example</a>. This
  32. example builds on top of that example.
  33. </p>
  34. <p>
  35. So far, to keep things simple, all of the tutorial programs are self contained
  36. in one cpp file. In reality, you will want to separate various logical modules
  37. of the parser into separate cpp and header files, decoupling the interface
  38. from the implememtation.
  39. </p>
  40. <p>
  41. There are many ways to structure an X3 parser, but the "minimal"
  42. example in this tutorial shows the preferred way. This example basically
  43. reuses the same parser as the <a class="link" href="employee.html" title="Employee - Parsing into structs">employee
  44. example</a> for the sake of familiarity, but structured to allow separate
  45. compilation of the actual parser in its own definition file and cpp file.
  46. The cpp files, including main see only the header files --the interfaces.
  47. This is a good example on how X3 parsers are structured in a C++ application.
  48. </p>
  49. <h5>
  50. <a name="spirit_x3.tutorials.minimal.h0"></a>
  51. <span class="phrase"><a name="spirit_x3.tutorials.minimal.structure"></a></span><a class="link" href="minimal.html#spirit_x3.tutorials.minimal.structure">Structure</a>
  52. </h5>
  53. <p>
  54. The program is structured in a directory with the following header and cpp
  55. files:
  56. </p>
  57. <div class="informaltable"><table class="table">
  58. <colgroup>
  59. <col>
  60. <col>
  61. </colgroup>
  62. <thead><tr>
  63. <th>
  64. <p>
  65. <code class="computeroutput"><span class="identifier">File</span></code>
  66. </p>
  67. </th>
  68. <th>
  69. <p>
  70. Description
  71. </p>
  72. </th>
  73. </tr></thead>
  74. <tbody>
  75. <tr>
  76. <td>
  77. <p>
  78. <a href="../../../../../example/x3/minimal/ast.hpp" target="_top">ast.hpp</a>
  79. </p>
  80. </td>
  81. <td>
  82. <p>
  83. The AST
  84. </p>
  85. </td>
  86. </tr>
  87. <tr>
  88. <td>
  89. <p>
  90. <a href="../../../../../example/x3/minimal/ast_adapted.hpp" target="_top">ast_adapted.hpp</a>
  91. </p>
  92. </td>
  93. <td>
  94. <p>
  95. Fusion adapters
  96. </p>
  97. </td>
  98. </tr>
  99. <tr>
  100. <td>
  101. <p>
  102. <a href="../../../../../example/x3/minimal/config.hpp" target="_top">config.hpp</a>
  103. </p>
  104. </td>
  105. <td>
  106. <p>
  107. Configuration
  108. </p>
  109. </td>
  110. </tr>
  111. <tr>
  112. <td>
  113. <p>
  114. <a href="../../../../../example/x3/minimal/employee.hpp" target="_top">employee.hpp</a>
  115. </p>
  116. </td>
  117. <td>
  118. <p>
  119. Main parser API
  120. </p>
  121. </td>
  122. </tr>
  123. <tr>
  124. <td>
  125. <p>
  126. <a href="../../../../../example/x3/minimal/employee_def.hpp" target="_top">employee_def.hpp</a>
  127. </p>
  128. </td>
  129. <td>
  130. <p>
  131. Parser definitions
  132. </p>
  133. </td>
  134. </tr>
  135. <tr>
  136. <td>
  137. <p>
  138. <a href="../../../../../example/x3/minimal/employee.cpp" target="_top">employee.cpp</a>
  139. </p>
  140. </td>
  141. <td>
  142. <p>
  143. Parser instantiation
  144. </p>
  145. </td>
  146. </tr>
  147. <tr>
  148. <td>
  149. <p>
  150. <a href="../../../../../example/x3/minimal/main.cpp" target="_top">main.cpp</a>
  151. </p>
  152. </td>
  153. <td>
  154. <p>
  155. Main program
  156. </p>
  157. </td>
  158. </tr>
  159. </tbody>
  160. </table></div>
  161. <p>
  162. The contents of the files should already be familiar. It's essentially the
  163. same <a class="link" href="employee.html" title="Employee - Parsing into structs">employee example</a>.
  164. So I will skip the details on how the parser works and focus only on the
  165. features needed for refactoring the program into a modular structure suitable
  166. for real-world deployment.
  167. </p>
  168. <h5>
  169. <a name="spirit_x3.tutorials.minimal.h1"></a>
  170. <span class="phrase"><a name="spirit_x3.tutorials.minimal.ast"></a></span><a class="link" href="minimal.html#spirit_x3.tutorials.minimal.ast">AST</a>
  171. </h5>
  172. <p>
  173. We place the AST declaration here:
  174. </p>
  175. <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>
  176. <span class="special">{</span>
  177. <span class="keyword">struct</span> <span class="identifier">employee</span>
  178. <span class="special">{</span>
  179. <span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span>
  180. <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">forename</span><span class="special">;</span>
  181. <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">surname</span><span class="special">;</span>
  182. <span class="keyword">double</span> <span class="identifier">salary</span><span class="special">;</span>
  183. <span class="special">};</span>
  184. <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fusion</span><span class="special">::</span><span class="keyword">operator</span><span class="special">&lt;&lt;;</span>
  185. <span class="special">}}</span>
  186. </pre>
  187. <h5>
  188. <a name="spirit_x3.tutorials.minimal.h2"></a>
  189. <span class="phrase"><a name="spirit_x3.tutorials.minimal.fusion_adapters"></a></span><a class="link" href="minimal.html#spirit_x3.tutorials.minimal.fusion_adapters">Fusion
  190. adapters</a>
  191. </h5>
  192. <p>
  193. Here, we adapt the AST for Fusion, making it a first-class fusion citizen:
  194. </p>
  195. <pre class="programlisting"><span class="identifier">BOOST_FUSION_ADAPT_STRUCT</span><span class="special">(</span><span class="identifier">client</span><span class="special">::</span><span class="identifier">ast</span><span class="special">::</span><span class="identifier">employee</span><span class="special">,</span>
  196. <span class="identifier">age</span><span class="special">,</span> <span class="identifier">forename</span><span class="special">,</span> <span class="identifier">surname</span><span class="special">,</span> <span class="identifier">salary</span>
  197. <span class="special">)</span>
  198. </pre>
  199. <h5>
  200. <a name="spirit_x3.tutorials.minimal.h3"></a>
  201. <span class="phrase"><a name="spirit_x3.tutorials.minimal.main_parser_api"></a></span><a class="link" href="minimal.html#spirit_x3.tutorials.minimal.main_parser_api">Main
  202. parser API</a>
  203. </h5>
  204. <p>
  205. This is the main header file that all other cpp files need to include.
  206. </p>
  207. <a name="__tutorial_spirit_declare__"></a><h5>
  208. <a name="spirit_x3.tutorials.minimal.h4"></a>
  209. <span class="phrase"><a name="spirit_x3.tutorials.minimal.boost_spirit_declare"></a></span><a class="link" href="minimal.html#spirit_x3.tutorials.minimal.boost_spirit_declare">BOOST_SPIRIT_DECLARE</a>
  210. </h5>
  211. <p>
  212. Remember <a class="link" href="roman.html#__tutorial_spirit_define__"><code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code></a>?
  213. If not, then you probably want to go back and review that section to get
  214. a better understanding of what's happening.
  215. </p>
  216. <p>
  217. Here in the header file, instead of <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code>,
  218. we use <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DECLARE</span></code>
  219. for the <span class="bold"><strong>top</strong></span> rule. Behind the scenes, what's
  220. actually happening is that we are declaring a <code class="computeroutput"><span class="identifier">parse_rule</span></code>
  221. function in the client namespace. For example, given a rule named <code class="computeroutput"><span class="identifier">my_rule</span></code>, <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DECLARE</span><span class="special">(</span><span class="identifier">my_rule</span><span class="special">)</span></code> expands to this code:
  222. </p>
  223. <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>
  224. <span class="keyword">bool</span> <span class="identifier">parse_rule</span><span class="special">(</span>
  225. <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">my_rule</span><span class="special">)</span>
  226. <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>
  227. <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>
  228. </pre>
  229. <p>
  230. If you went back and reviewed <a class="link" href="roman.html#__tutorial_spirit_define__">BOOST_SPIRIT_DEFINE</a>,
  231. you'll see why it is exactly what we need to use for header files. <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DECLARE</span></code> generates function
  232. declarations that are meant to be placed in hpp (header) files while <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code> generates function
  233. definitions that are meant to be placed in cpp files.
  234. </p>
  235. <div class="note"><table border="0" summary="Note">
  236. <tr>
  237. <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td>
  238. <th align="left">Note</th>
  239. </tr>
  240. <tr><td align="left" valign="top"><p>
  241. <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DECLARE</span></code> is
  242. variadic and may be used for one or more rules. Example: <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DECLARE</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>
  243. </p></td></tr>
  244. </table></div>
  245. <p>
  246. In this example, the top rule is <code class="computeroutput"><span class="identifier">employee</span></code>.
  247. We declare <code class="computeroutput"><span class="identifier">employee</span></code> in this
  248. header file:
  249. </p>
  250. <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">client</span>
  251. <span class="special">{</span>
  252. <span class="keyword">namespace</span> <span class="identifier">parser</span>
  253. <span class="special">{</span>
  254. <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>
  255. <span class="keyword">using</span> <span class="identifier">employee_type</span> <span class="special">=</span> <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">employee</span><span class="special">,</span> <span class="identifier">ast</span><span class="special">::</span><span class="identifier">employee</span><span class="special">&gt;;</span>
  256. <span class="identifier">BOOST_SPIRIT_DECLARE</span><span class="special">(</span><span class="identifier">employee_type</span><span class="special">);</span>
  257. <span class="special">}</span>
  258. <span class="identifier">parser</span><span class="special">::</span><span class="identifier">employee_type</span> <span class="identifier">employee</span><span class="special">();</span>
  259. <span class="special">}</span>
  260. </pre>
  261. <p>
  262. We also provide a function that returns an <code class="computeroutput"><span class="identifier">employee</span></code>
  263. object. This is the parser that we will use anywhere it is needed. X3 parser
  264. objects are very lightweight. They are basically simple tags with no data
  265. other than the name of the rule (e.g. "employee"). Notice that
  266. we are passing this by value.
  267. </p>
  268. <h5>
  269. <a name="spirit_x3.tutorials.minimal.h5"></a>
  270. <span class="phrase"><a name="spirit_x3.tutorials.minimal.parser_definitions"></a></span><a class="link" href="minimal.html#spirit_x3.tutorials.minimal.parser_definitions">Parser
  271. Definitions</a>
  272. </h5>
  273. <p>
  274. Here is where we place the actual rules that make up our grammar:
  275. </p>
  276. <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">parser</span>
  277. <span class="special">{</span>
  278. <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>
  279. <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>
  280. <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span>
  281. <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span>
  282. <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span>
  283. <span class="keyword">using</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span>
  284. <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
  285. <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">employee</span><span class="special">,</span> <span class="identifier">ast</span><span class="special">::</span><span class="identifier">employee</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">employee</span> <span class="special">=</span> <span class="string">"employee"</span><span class="special">;</span>
  286. <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">quoted_string</span> <span class="special">=</span> <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>
  287. <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">employee_def</span> <span class="special">=</span>
  288. <span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span>
  289. <span class="special">&gt;&gt;</span> <span class="char">'{'</span>
  290. <span class="special">&gt;&gt;</span> <span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
  291. <span class="special">&gt;&gt;</span> <span class="identifier">quoted_string</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
  292. <span class="special">&gt;&gt;</span> <span class="identifier">quoted_string</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
  293. <span class="special">&gt;&gt;</span> <span class="identifier">double_</span>
  294. <span class="special">&gt;&gt;</span> <span class="char">'}'</span>
  295. <span class="special">;</span>
  296. <span class="identifier">BOOST_SPIRIT_DEFINE</span><span class="special">(</span><span class="identifier">employee</span><span class="special">);</span>
  297. <span class="special">}</span>
  298. <span class="identifier">parser</span><span class="special">::</span><span class="identifier">employee_type</span> <span class="identifier">employee</span><span class="special">()</span>
  299. <span class="special">{</span>
  300. <span class="keyword">return</span> <span class="identifier">parser</span><span class="special">::</span><span class="identifier">employee</span><span class="special">;</span>
  301. <span class="special">}</span>
  302. </pre>
  303. <p>
  304. In the parser definition, we use <a class="link" href="roman.html#__tutorial_spirit_define__"><code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code></a> just like we
  305. did in the <a class="link" href="employee.html" title="Employee - Parsing into structs">employee example</a>.
  306. </p>
  307. <p>
  308. While this is another header file, it is not meant to be included by the
  309. client. Its purpose is to be included by an instantiations cpp file (see
  310. below). We place this in an <code class="computeroutput"><span class="special">.</span><span class="identifier">hpp</span></code> file for flexibility, so we have the
  311. freedom to instantiate the parser with different iterator types.
  312. </p>
  313. <a name="tutorial_configuration"></a><h5>
  314. <a name="spirit_x3.tutorials.minimal.h6"></a>
  315. <span class="phrase"><a name="spirit_x3.tutorials.minimal.configuration"></a></span><a class="link" href="minimal.html#spirit_x3.tutorials.minimal.configuration">Configuration</a>
  316. </h5>
  317. <p>
  318. Here, we declare some types for instatntaiting our X3 parser with. Rememeber
  319. that Spirit parsers can work with any <a href="http://en.cppreference.com/w/cpp/named_req/ForwardIterator" target="_top"><code class="computeroutput"><span class="identifier">ForwardIterator</span></code></a>. We'll also need
  320. to provide the initial context type. This is the context that X3 will use
  321. to initiate a parse. For calling <code class="computeroutput"><span class="identifier">phrase_parse</span></code>,
  322. you will need the <code class="computeroutput"><span class="identifier">phrase_parse_context</span></code>
  323. like we do below, passing in the skipper type.
  324. </p>
  325. <pre class="programlisting"><span class="keyword">using</span> <span class="identifier">iterator_type</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">const_iterator</span><span class="special">;</span>
  326. <span class="keyword">using</span> <span class="identifier">context_type</span> <span class="special">=</span> <span class="identifier">x3</span><span class="special">::</span><span class="identifier">phrase_parse_context</span><span class="special">&lt;</span><span class="identifier">x3</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">;</span>
  327. </pre>
  328. <p>
  329. For plain <code class="computeroutput"><span class="identifier">parse</span></code>, we simply
  330. use <code class="computeroutput"><span class="identifier">x3</span><span class="special">::</span><span class="identifier">unused_type</span></code>.
  331. </p>
  332. <h5>
  333. <a name="spirit_x3.tutorials.minimal.h7"></a>
  334. <span class="phrase"><a name="spirit_x3.tutorials.minimal.parser_instantiation"></a></span><a class="link" href="minimal.html#spirit_x3.tutorials.minimal.parser_instantiation">Parser
  335. Instantiation</a>
  336. </h5>
  337. <p>
  338. Now we instantiate our parser here, for our specific configuration:
  339. </p>
  340. <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>
  341. <span class="special">{</span>
  342. <span class="identifier">BOOST_SPIRIT_INSTANTIATE</span><span class="special">(</span><span class="identifier">employee_type</span><span class="special">,</span> <span class="identifier">iterator_type</span><span class="special">,</span> <span class="identifier">context_type</span><span class="special">);</span>
  343. <span class="special">}}</span>
  344. </pre>
  345. <p>
  346. For that, we use <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_INSTANTIATE</span></code>,
  347. passing in the parser type, the iterator type, and the context type.
  348. </p>
  349. <h5>
  350. <a name="spirit_x3.tutorials.minimal.h8"></a>
  351. <span class="phrase"><a name="spirit_x3.tutorials.minimal.boost_spirit_instantiate"></a></span><a class="link" href="minimal.html#spirit_x3.tutorials.minimal.boost_spirit_instantiate">BOOST_SPIRIT_INSTANTIATE</a>
  352. </h5>
  353. <p>
  354. Go back and review <a class="link" href="roman.html#__tutorial_spirit_define__"><code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code></a> and <a class="link" href="minimal.html#__tutorial_spirit_declare__"><code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DECLARE</span></code></a> to get a better
  355. grasp of what's happening with <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_INSTANTIATE</span></code>
  356. and why it is needed.
  357. </p>
  358. <p>
  359. So what the heck is <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_INSTANTIATE</span></code>?
  360. What we want is to isolate the instantiation of our parsers (rules and all
  361. that), into separate translation units (or cpp files, if you will). In this
  362. example, we want to place our x3 employee stuff in <a href="../../../../../example/x3/minimal/employee.cpp" target="_top">employee.cpp</a>.
  363. That way, we have separate compilation. Every time we update our employee
  364. parser source code, we only have to build the <code class="computeroutput"><span class="identifier">employee</span><span class="special">.</span><span class="identifier">cpp</span></code> file.
  365. All the rest will not be affected. By compiling only once in one translation
  366. unit, we save on build times and avoid code bloat. There is no code duplication,
  367. which can happen otherwise if you simply include the employee parser (<a href="../../../../../example/x3/minimal/employee.hpp" target="_top">employee.hpp</a>) everywhere.
  368. </p>
  369. <p>
  370. But how do you do that. Remember that our parser definitions are also placed
  371. in its own header file for flexibility, so we have the freedom to instantiate
  372. the parser with different iterator types.
  373. </p>
  374. <p>
  375. What we need to do is explicitly instantiate the <code class="computeroutput"><span class="identifier">parse_rule</span></code>
  376. function we declared and defined via <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DECLARE</span></code>
  377. and <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEFINE</span></code> respectively,
  378. using <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_INSTANTIATE</span></code>.
  379. For our particular example, <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_INSTANTIATE</span></code>
  380. expands to this code:
  381. </p>
  382. <pre class="programlisting"><span class="keyword">template</span> <span class="keyword">bool</span> <span class="identifier">parse_rule</span><span class="special">&lt;</span><span class="identifier">iterator_type</span><span class="special">,</span> <span class="identifier">context_type</span><span class="special">&gt;(</span>
  383. <span class="identifier">employee_type</span> <span class="identifier">rule_</span>
  384. <span class="special">,</span> <span class="identifier">iterator_type</span><span class="special">&amp;</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">iterator_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">last</span>
  385. <span class="special">,</span> <span class="identifier">context_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">employee_type</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>
  386. </pre>
  387. <h5>
  388. <a name="spirit_x3.tutorials.minimal.h9"></a>
  389. <span class="phrase"><a name="spirit_x3.tutorials.minimal.main_program"></a></span><a class="link" href="minimal.html#spirit_x3.tutorials.minimal.main_program">Main
  390. Program</a>
  391. </h5>
  392. <p>
  393. Finally, we have our main program. The code is the same as single cpp file
  394. <a class="link" href="employee.html" title="Employee - Parsing into structs">employee example</a>, but
  395. here, we simply include three header files:
  396. </p>
  397. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="string">"ast.hpp"</span>
  398. <span class="preprocessor">#include</span> <span class="string">"ast_adapted.hpp"</span>
  399. <span class="preprocessor">#include</span> <span class="string">"employee.hpp"</span>
  400. </pre>
  401. <div class="orderedlist"><ol class="orderedlist" type="1">
  402. <li class="listitem">
  403. <code class="computeroutput"><span class="identifier">ast</span><span class="special">.</span><span class="identifier">hpp</span></code> for the AST declaration
  404. </li>
  405. <li class="listitem">
  406. <code class="computeroutput"><span class="identifier">ast_adapted</span><span class="special">.</span><span class="identifier">hpp</span></code> if you need to traverse the AST
  407. using fusion
  408. </li>
  409. <li class="listitem">
  410. <code class="computeroutput"><span class="identifier">employee</span><span class="special">.</span><span class="identifier">hpp</span></code> the main parser API
  411. </li>
  412. </ol></div>
  413. </div>
  414. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  415. <td align="left"></td>
  416. <td align="right"><div class="copyright-footer">Copyright &#169; 2001-2018 Joel de Guzman,
  417. Hartmut Kaiser<p>
  418. Distributed under the Boost Software License, Version 1.0. (See accompanying
  419. 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>)
  420. </p>
  421. </div></td>
  422. </tr></table>
  423. <hr>
  424. <div class="spirit-nav">
  425. <a accesskey="p" href="employee.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="annotation.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
  426. </div>
  427. </body>
  428. </html>