grammar.html 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <html>
  2. <head>
  3. <title>The Grammar</title>
  4. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  5. <link rel="stylesheet" href="theme/style.css" type="text/css">
  6. </head>
  7. <body>
  8. <table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
  9. <tr>
  10. <td width="10">
  11. </td>
  12. <td width="85%">
  13. <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>The Grammar</b></font>
  14. </td>
  15. <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td>
  16. </tr>
  17. </table>
  18. <br>
  19. <table border="0">
  20. <tr>
  21. <td width="10"></td>
  22. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  23. <td width="30"><a href="scanner.html"><img src="theme/l_arr.gif" border="0"></a></td>
  24. <td width="30"><a href="subrules.html"><img src="theme/r_arr.gif" border="0"></a></td>
  25. </tr>
  26. </table>
  27. <p>The <b>grammar</b> encapsulates a set of rules. The <tt>grammar</tt> class
  28. is a protocol base class. It is essentially an interface contract. The <tt>grammar</tt>
  29. is a template class that is parameterized by its derived class, <tt>DerivedT</tt>,
  30. and its context, <tt>ContextT</tt>. The template parameter ContextT defaults
  31. to <tt>parser_context</tt>, a predefined context. </p>
  32. <p>You need not be concerned at all with the ContextT template parameter unless
  33. you wish to tweak the low level behavior of the grammar. Detailed information
  34. on the ContextT template parameter is provided <a href="indepth_the_parser_context.html">elsewhere</a>.
  35. The <tt>grammar</tt> relies on the template parameter DerivedT, a grammar subclass
  36. to define the actual rules.</p>
  37. <p>Presented below is the public API. There may actually be more template parameters
  38. after <tt>ContextT</tt>. Everything after the <tt>ContextT</tt> parameter should
  39. not be of concern to the client and are strictly for internal use only.</p>
  40. <pre><code><font color="#000000"><span class=identifier> </span><span class=keyword>template</span><span class=special>&lt;
  41. </span><span class=keyword>typename </span><span class=identifier>DerivedT</span><span class=special>,
  42. </span><span class=keyword>typename </span><span class=identifier>ContextT </span><span class=special>= </span><span class=identifier>parser_context</span><span class=special>&lt;</span><span class=special>&gt; &gt;
  43. </span><span class=keyword>struct </span><span class=identifier>grammar</span><span class=special>;</span></font></code></pre>
  44. <h2>Grammar definition</h2>
  45. <p>A concrete sub-class inheriting from <tt>grammar</tt> is expected to have a
  46. nested template class (or struct) named <tt>definition</tt>:</p>
  47. <blockquote>
  48. <p><img src="theme/bullet.gif" width="13" height="13"> It is a nested template
  49. class with a typename <tt>ScannerT</tt> parameter.<br>
  50. <img src="theme/bullet.gif" width="13" height="13"> Its constructor defines
  51. the grammar rules.<br>
  52. <img src="theme/bullet.gif" width="13" height="13"> Its constructor is passed
  53. in a reference to the actual grammar <tt>self</tt>.<br>
  54. <img src="theme/bullet.gif" width="13" height="13"> It has a member function
  55. named <tt>start</tt> that returns a reference to the start <tt>rule</tt>.</p>
  56. </blockquote>
  57. <h2>Grammar skeleton</h2>
  58. <pre><code><font color="#000000"><span class=special> </span><span class=keyword>struct </span><span class=identifier>my_grammar </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>grammar</span><span class=special>&lt;</span><span class=identifier>my_grammar</span><span class=special>&gt;
  59. </span><span class=special>{
  60. </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>&gt;
  61. </span><span class=keyword>struct </span><span class=identifier>definition
  62. </span><span class=special>{
  63. </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt; </span><span class=identifier>r</span><span class=special>;
  64. </span><span class=identifier>definition</span><span class=special>(</span><span class=identifier>my_grammar </span><span class=keyword>const</span><span class=special>& </span><span class=identifier>self</span><span class=special>) </span><span class=special>{ </span><span class=identifier>r </span><span class=special>= </span><span class=comment>/*..define here..*/</span><span class=special>; </span><span class=special>}
  65. </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>& </span><span class=identifier>start</span><span class=special>() </span><span class=keyword>const </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>r</span><span class=special>; </span><span class=special>}
  66. </span><span class=special>};
  67. </span><span class=special>};</span></font></code></pre>
  68. <p>Decoupling the scanner type from the rules that form a grammar allows the grammar
  69. to be used in different contexts possibly using different scanners. We do not
  70. care what scanner we are dealing with. The user-defined <tt>my_grammar</tt>
  71. can be used with <b>any</b> type of scanner. Unlike the rule, the grammar is
  72. not tied to a specific scanner type. See <a href="faq.html#scanner_business">&quot;Scanner
  73. Business&quot;</a> to see why this is important and to gain further understanding
  74. on this scanner-rule coupling problem.</p>
  75. <h2>Instantiating and using my_grammar</h2>
  76. <p>Our grammar above may be instantiated and put into action:</p>
  77. <pre><code><font color="#000000"><span class=special> </span><span class=identifier>my_grammar </span><span class=identifier>g</span><span class=special>;
  78. </span><span class=keyword>if </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>g</span><span class=special>, </span><span class=identifier>space_p</span><span class=special>).</span><span class=identifier>full</span><span class=special>)
  79. </span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>"parsing succeeded\n"</span><span class=special>;
  80. </span><span class=keyword>else
  81. </span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>"parsing failed\n"</span><span class=special>;</span></font></code></pre>
  82. <p><tt>my_grammar</tt> <b>IS-A </b>parser and can be used anywhere a parser is
  83. expected, even referenced by another rule:</p>
  84. <pre><code><font color="#000000"><span class=special> </span><span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class=identifier>r </span><span class=special>= </span><span class=identifier>g </span><span class=special>&gt;&gt; </span><span class=identifier>str_p</span><span class=special>(</span><span class=string>"cool huh?"</span><span class=special>);</span></font></code></pre>
  85. <table width="80%" border="0" align="center">
  86. <tr>
  87. <td class="note_box"><img src="theme/alert.gif" width="16" height="16"> <b>Referencing
  88. grammars<br>
  89. </b><br>
  90. Like the rule, the grammar is also held by reference when it is placed in
  91. the right hand side of an EBNF expression. It is the responsibility of the
  92. client to ensure that the referenced grammar stays in scope and does not
  93. get destructed while it is being referenced. </td>
  94. </tr>
  95. </table>
  96. <h2><a name="full_grammar"></a>Full Grammar Example</h2>
  97. <p>Recalling our original calculator example, here it is now rewritten using a
  98. grammar:</p>
  99. <pre><code><font color="#000000"><span class=special> </span><span class=keyword>struct </span><span class=identifier>calculator </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>grammar</span><span class=special>&lt;</span><span class=identifier>calculator</span><span class=special>&gt;
  100. </span><span class=special>{
  101. </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>&gt;
  102. </span><span class=keyword>struct </span><span class=identifier>definition
  103. </span><span class=special>{
  104. </span><span class=identifier>definition</span><span class=special>(</span><span class=identifier>calculator </span><span class=keyword>const</span><span class=special>& </span><span class=identifier>self</span><span class=special>)
  105. </span><span class=special>{
  106. </span><span class=identifier>group </span><span class=special>= </span><span class=literal>'(' </span><span class=special>&gt;&gt; </span><span class=identifier>expression </span><span class=special>&gt;&gt; </span><span class=literal>')'</span><span class=special>;
  107. </span><span class=identifier>factor </span><span class=special>= </span><span class=identifier>integer </span><span class=special>| </span><span class=identifier>group</span><span class=special>;
  108. </span><span class=identifier>term </span><span class=special>= </span><span class=identifier>factor </span><span class=special>&gt;&gt; </span><span class=special>*((</span><span class=literal>'*' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>) </span><span class=special>| </span><span class=special>(</span><span class=literal>'/' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>));
  109. </span><span class=identifier>expression </span><span class=special>= </span><span class=identifier>term </span><span class=special>&gt;&gt; </span><span class=special>*((</span><span class=literal>'+' </span><span class=special>&gt;&gt; </span><span class=identifier>term</span><span class=special>) </span><span class=special>| </span><span class=special>(</span><span class=literal>'-' </span><span class=special>&gt;&gt; </span><span class=identifier>term</span><span class=special>));
  110. </span><span class=special>}
  111. </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt; </span><span class=identifier>expression</span><span class=special>, </span><span class=identifier>term</span><span class=special>, </span><span class=identifier>factor</span><span class=special>, </span><span class=identifier>group</span><span class=special>;
  112. </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&
  113. </span><span class=identifier>start</span><span class=special>() </span><span class=keyword>const </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>expression</span><span class=special>; </span><span class=special>}
  114. </span><span class=special>};
  115. </span><span class=special>};</span></font></code></pre>
  116. <p><img src="theme/lens.gif" width="15" height="16"> A fully working example with
  117. <a href="semantic_actions.html">semantic actions</a> can be <a href="../example/fundamental/calc_plain.cpp">viewed
  118. here</a>. This is part of the Spirit distribution. </p>
  119. <table width="80%" border="0" align="center">
  120. <tr>
  121. <td class="note_box"><img src="theme/lens.gif" width="15" height="16"> <b>self</b><br>
  122. <br>
  123. You might notice that the definition of the grammar has a constructor that
  124. accepts a const reference to the outer grammar. In the example above, notice
  125. that <tt>calculator::definition</tt> takes in a <tt>calculator const&amp;
  126. self</tt>. While this is unused in the example above, in many cases, this
  127. is very useful. The self argument is the definition's window to the outside
  128. world. For example, the calculator class might have a reference to some
  129. state information that the definition can update while parsing proceeds
  130. through <a href="semantic_actions.html">semantic actions</a>. </td>
  131. </tr>
  132. </table>
  133. <h2>Grammar Capsules</h2>
  134. <p>As a grammar becomes complicated, it is a good idea to group parts into logical
  135. modules. For instance, when writing a language, it might be wise to put expressions
  136. and statements into separate grammar capsules. The grammar takes advantage of
  137. the encapsulation properties of C++ classes. The declarative nature of classes
  138. makes it a perfect fit for the definition of grammars. Since the grammar is
  139. nothing more than a class declaration, we can conveniently publish it in header
  140. files. The idea is that once written and fully tested, a grammar can be reused
  141. in many contexts. We now have the notion of grammar libraries.</p>
  142. <h2><a name="multithreading"></a>Reentrancy and multithreading</h2>
  143. <p>An instance of a grammar may be used in different places multiple times without
  144. any problem. The implementation is tuned to allow this at the expense of some
  145. overhead. However, we can save considerable cycles and bytes if we are certain
  146. that a grammar will only have a single instance. If this is desired, simply
  147. define <tt>BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE</tt> before including any spirit
  148. header files.</p>
  149. <pre><font face="Courier New, Courier, mono"><code><span class="preprocessor"> #define</span></code></font><span class="preprocessor"><code><font face="Courier New, Courier, mono"> </font><tt>BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE</tt></code></span></pre>
  150. <p> On the other hand, if a grammar is intended to be used in multithreaded code,
  151. we should then define <tt>BOOST_SPIRIT_THREADSAFE</tt> before including any
  152. spirit header files. In this case it will also be required to link against <a href="http://www.boost.org/libs/thread/doc/index.html">Boost.Threads</a></p>
  153. <pre><font face="Courier New, Courier, mono"><span class="preprocessor"> #define</span></font> <span class="preprocessor"><tt>BOOST_SPIRIT_THREADSAFE</tt></span></pre>
  154. <h2>Using more than one grammar start rule </h2>
  155. <p>Sometimes it is desirable to have more than one visible entry point to a grammar
  156. (apart from the start rule). To allow additional start points, Spirit provides
  157. a helper template <tt>grammar_def</tt>, which may be used as a base class for
  158. the <tt>definition</tt> subclass of your <tt>grammar</tt>. Here's an example:</p>
  159. <pre><code> <span class="comment">// this header has to be explicitly included</span>
  160. <span class="preprocessor">#include</span> <span class="string">&lt;boost/spirit/utility/grammar_def.hpp&gt;</span>
  161. </span><span class=keyword>struct </span><span class=identifier>calculator2 </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>grammar</span><span class=special>&lt;</span><span class=identifier>calculator2</span><span class=special>&gt;
  162. {
  163. </span> <span class="keyword">enum</span>
  164. {
  165. expression = 0,
  166. term = 1,
  167. factor = 2,
  168. };
  169. <span class=special> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>&gt;
  170. </span><span class=keyword>struct </span><span class=identifier>definition
  171. </span><span class="special">:</span> <span class="keyword">public</span><span class=identifier> grammar_def</span><span class="special">&lt;</span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt;,</span> same<span class="special">,</span> same<span class="special">&gt;</span>
  172. <span class=special>{</span>
  173. <span class=identifier>definition</span><span class=special>(</span><span class=identifier>calculator2 </span><span class=keyword>const</span><span class=special>& </span><span class=identifier>self</span><span class=special>)
  174. {
  175. </span><span class=identifier>group </span><span class=special>= </span><span class=literal>'(' </span><span class=special>&gt;&gt; </span><span class=identifier>expression </span><span class=special>&gt;&gt; </span><span class=literal>')'</span><span class=special>;
  176. </span><span class=identifier>factor </span><span class=special>= </span><span class=identifier>integer </span><span class=special>| </span><span class=identifier>group</span><span class=special>;
  177. </span><span class=identifier>term </span><span class=special>= </span><span class=identifier>factor </span><span class=special>&gt;&gt; *((</span><span class=literal>'*' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>) | (</span><span class=literal>'/' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>));
  178. </span><span class=identifier>expression </span><span class=special>= </span><span class=identifier>term </span><span class=special>&gt;&gt; *((</span><span class=literal>'+' </span><span class=special>&gt;&gt; </span><span class=identifier>term</span><span class=special>) | (</span><span class=literal>'-' </span><span class=special>&gt;&gt; </span><span class=identifier>term</span><span class=special>));</span>
  179. <span class="keyword">this</span><span class="special">-&gt;</span>start_parsers<span class="special">(</span>expression<span class="special">,</span> term<span class="special">,</span> factor<span class="special">);</span>
  180. <span class="special">}</span>
  181. <span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt; </span><span class=identifier>expression</span><span class=special>, </span><span class=identifier>term</span><span class=special>, </span><span class=identifier>factor, group</span><span class=special>;
  182. </span><span class=special> };
  183. };</span></font></code></pre>
  184. <p>The <tt>grammar_def</tt> template has to be instantiated with the types of
  185. all the rules you wish to make visible from outside the <tt>grammar</tt>:</p>
  186. <pre><code><span class=identifier> </span><span class=identifier>grammar_def</span><span class="special">&lt;</span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt;,</span> same<span class="special">,</span> same<span class="special">&gt;</span></code> </pre>
  187. <p>The shorthand notation <tt>same</tt> is used to indicate that the same type
  188. be used as specified by the previous template parameter (e.g. <code><tt>rule&lt;ScannerT&gt;</tt></code>).
  189. Obviously, <tt>same</tt> may not be used as the first template parameter. </p>
  190. <table width="80%" border="0" align="center">
  191. <tr>
  192. <td class="note_box"> <img src="theme/bulb.gif" width="13" height="18"> <strong>grammar_def
  193. start types</strong><br>
  194. <br>
  195. It may not be obvious, but it is interesting to note that aside from rule&lt;&gt;s,
  196. any parser type may be specified (e.g. chlit&lt;&gt;, strlit&lt;&gt;, int_parser&lt;&gt;,
  197. etc.).</td>
  198. </tr>
  199. </table>
  200. <p>Using the grammar_def class, there is no need to provide a <tt>start()</tt>member
  201. function anymore. Instead, you'll have to insert a call to the <tt>this-&gt;start_parsers()</tt>
  202. (which is a member function of the <tt>grammar_def</tt> template) to define
  203. the start symbols for your <tt>grammar</tt>. <img src="theme/note.gif" width="16" height="16">
  204. Note that the number and the sequence of the rules used as the parameters to
  205. the <tt>start_parsers()</tt> function should match the types specified in the
  206. <tt>grammar_def</tt> template:</p>
  207. <pre><code> <span class="keyword">this</span><span class="special">-&gt;</span>start_parsers<span class="special">(</span>expression<span class="special">,</span> term<span class="special">,</span> factor<span class="special">);</span></code></pre>
  208. <p> The grammar entry point may be specified using the following syntax:</p>
  209. <pre><code><font color="#000000"><span class=identifier> g</span><span class="special">.</span><span class=identifier>use_parser</span><span class="special">&lt;</span><span class=identifier>N</span><span class=special>&gt;() </span><span class="comment">// Where g is your grammar and N is the Nth entry.</span></font></code></pre>
  210. <p>This sample shows how to use the <tt>term</tt> rule from the <tt>calculator2</tt>
  211. grammar above:</p>
  212. <pre><code><font color="#000000"><span class=identifier> calculator2 g</span><span class=special>;
  213. </span><span class=keyword>if </span><span class=special>(</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>
  214. first</span><span class=special>, </span><span class=identifier>last</span><span class=special>,
  215. </span><span class=identifier>g</span><span class="special">.</span><span class=identifier>use_parser</span><span class="special">&lt;</span><span class=identifier>calculator2::term</span><span class=special>&gt;(),</span><span class=identifier>
  216. space_p</span><span class=special>
  217. ).</span><span class=identifier>full</span><span class=special>)
  218. {
  219. </span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>"parsing succeeded\n"</span><span class=special>;
  220. }
  221. </span><span class=keyword>else</span> <span class="special">{</span>
  222. <span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>"parsing failed\n"</span><span class=special>;
  223. }</span></font></code></pre>
  224. <p>The template parameter for the <tt>use_parser&lt;&gt;</tt> template type should
  225. be the zero based index into the list of rules specified in the <tt>start_parsers()</tt>
  226. function call. </p>
  227. <table width="80%" border="0" align="center">
  228. <tr>
  229. <td class="note_box"><img src="theme/note.gif" width="16" height="16"> <tt><strong>use_parser&lt;0&gt;</strong></tt><br>
  230. <br>
  231. Note, that using <span class="literal">0</span> (zero) as the template parameter
  232. to <tt>use_parser</tt> is equivalent to using the start rule, exported by
  233. conventional means through the <tt>start()</tt> function, as shown in the
  234. first <tt><a href="grammar.html#full_grammar">calculator</a></tt> sample
  235. above. So this notation may be used even for grammars exporting one rule
  236. through its <tt>start()</tt> function only. On the other hand, calling a
  237. <tt>grammar</tt> without the <tt>use_parser</tt> notation will execute the
  238. rule specified as the first parameter to the <tt>start_parsers()</tt> function.
  239. </td>
  240. </tr>
  241. </table>
  242. <p>The maximum number of usable start rules is limited by the preprocessor constant:</p>
  243. <pre> <span class="identifier">BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT</span> <span class="comment">// defaults to 3</span></pre>
  244. <table border="0">
  245. <tr>
  246. <td width="10"></td>
  247. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  248. <td width="30"><a href="scanner.html"><img src="theme/l_arr.gif" border="0"></a></td>
  249. <td width="30"><a href="subrules.html"><img src="theme/r_arr.gif" border="0"></a></td>
  250. </tr>
  251. </table>
  252. <br>
  253. <hr size="1">
  254. <p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
  255. Copyright &copy; 2003-2004 Hartmut Kaiser <br>
  256. <br>
  257. <font size="2">Use, modification and distribution is subject to the Boost Software
  258. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  259. http://www.boost.org/LICENSE_1_0.txt) </font> </p>
  260. <p>&nbsp;</p>
  261. </body>
  262. </html>