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