Sophie

Sophie

distrib > Mandriva > 9.1 > ppc > by-pkgid > b9ba69a436161613d8fb030c8c726a8e > files > 425

spirit-1.5.1-2mdk.noarch.rpm

<html>
<head>
<title>Introduction</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="theme/style.css" type="text/css">
</head>

<body>
<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
  <tr> 
    <td width="10" height="49"> 
    </td>
    <td width="85%" height="49"> 
      <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Introduction</b></font>
    </td>
    <td width="112" height="49"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td>
  </tr>
</table>
<br>
<table border="0">
  <tr> 
    <td width="10"></td>
    <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
    <td width="30"><a href="preface.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
    <td width="20"><a href="quick_start.html"><img src="theme/r_arr.gif" border="0"></a></td>
  </tr>
</table>
<p>Spirit is an object-oriented recursive-descent parser generator framework implemented 
  using template meta-programming techniques. Expression templates allow us to 
  approximate the syntax of Extended Backus-Normal Form (EBNF) completely in C++.</p>
<p>The Spirit framework enables a target grammar to be written exclusively in 
  C++. Inline EBNF grammar specifications can mix freely with other C++ code and, 
  thanks to the generative power of C++ templates, are immediately executable. 
  In retrospect, conventional compiler-compilers or parser-generators have to 
  perform an additional translation step from the source EBNF code to C or C++ 
  code.</p>
<p>A simple EBNF grammar snippet:</p>
<pre><code><font color="#000000"><span class=identifier>    </span><span class=identifier>group       </span><span class=special>::= </span><span class=literal>'(' </span><span class=identifier>expression </span><span class=literal>')'
    </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=identifier>term        </span><span class=special>::= </span><span class=identifier>factor </span><span class=special>((</span><span class=literal>'*' </span><span class=identifier>factor</span><span class=special>) </span><span class=special>| </span><span class=special>(</span><span class=literal>'/' </span><span class=identifier>factor</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=literal>'+' </span><span class=identifier>term</span><span class=special>) </span><span class=special>| </span><span class=special>(</span><span class=literal>'-' </span><span class=identifier>term</span><span class=special>))*</span></font></code></pre>
<p>is approximated using Spirit's facilities as seen in this code snippet:<br>
</p>
<pre><code><font color="#000000"><span class=special>    </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>;
    </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>;
    </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>));
    </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>));</span></font></code></pre>
<p>Through the magic of expression templates, this is perfectly valid and executable 
  C++ code. The production rule <tt>expression</tt> is in fact an object that 
  has a member function parse that does the work given a source code written in 
  the grammar that we have just declared. Yes, it's a calculator. We shall simplify 
  for now by skipping the type declarations and the definition of the rule <tt>integer</tt> 
  invoked by <tt>factor</tt>. The production rule <tt>expression</tt> in our grammar 
  specification, traditionally called the start symbol, can recognize inputs such 
  as:</p>
<pre><span class=special>   </span><span class=number>12345
   </span><span class=special>-</span><span class=number>12345
   </span><span class=special>+</span><span class=number>12345
   </span><span class=number>1 </span><span class=special>+ </span><span class=number>2
   </span><span class=number>1 </span><span class=special>* </span><span class=number>2
   </span><span class=number>1</span><span class=special>/</span><span class=number>2 </span><span class=special>+ </span><span class=number>3</span><span class=special>/</span><span class=number>4
   </span><span class=number>1 </span><span class=special>+ </span><span class=number>2 </span><span class=special>+ </span><span class=number>3 </span><span class=special>+ </span><span class=number>4
   </span><span class=number>1 </span><span class=special>* </span><span class=number>2 </span><span class=special>* </span><span class=number>3 </span><span class=special>* </span><span class=number>4
   </span><span class=special>(</span><span class=number>1 </span><span class=special>+ </span><span class=number>2</span><span class=special>) </span><span class=special>* </span><span class=special>(</span><span class=number>3 </span><span class=special>+ </span><span class=number>4</span><span class=special>)
   </span><span class=special>(-</span><span class=number>1 </span><span class=special>+ </span><span class=number>2</span><span class=special>) </span><span class=special>* </span><span class=special>(</span><span class=number>3 </span><span class=special>+ </span><span class=special>-</span><span class=number>4</span><span class=special>)
   </span><span class=number>1 </span><span class=special>+ </span><span class=special>((</span><span class=number>6 </span><span class=special>* </span><span class=number>200</span><span class=special>) </span><span class=special>- </span><span class=number>20</span><span class=special>) </span><span class=special>/ </span><span class=number>6
   </span><span class=special>(</span><span class=number>1 </span><span class=special>+ </span><span class=special>(</span><span class=number>2 </span><span class=special>+ </span><span class=special>(</span><span class=number>3 </span><span class=special>+ </span><span class=special>(</span><span class=number>4 </span><span class=special>+ </span><span class=number>5</span><span class=special>))))</span></pre>
<p>Certainly we have done some modifications to the original EBNF syntax. This 
  is done so as to conform to C++ syntax rules. Most notably we see the abundance 
  of shift <tt class="operators">&gt;&gt;</tt> operators. Since there are no 'empty' 
  operators in C++, it is simply not possible to write something like:</p>
<pre>
<span class=special>   </span><span class=identifier>a </span><span class=identifier>b</span>
</pre>
<p>as seen in math syntax, for example, to mean multiplication or, in our case, 
  as seen in EBNF syntax to mean sequencing (b should follow a). The framework 
  uses the shift <tt class="operators">&gt;&gt;</tt> operator instead for this 
  purpose. We take the <tt class="operators">&gt;&gt;</tt> operator, with arrows 
  pointing to the right, to mean &quot;is followed by&quot;. Thus we write:</p>
<pre><span class=identifier>    </span><span class=identifier>a </span><span class=special>&gt;&gt; </span><span class=identifier>b</span></pre>
<p>The alternative operator <tt class="operators">|</tt> and the parentheses <tt class="operators">()</tt> 
  remain as is. The assignment operator <tt class="operators">=</tt> is used in 
  place of EBNF's <tt class="operators">::=</tt>. Last but not least, the Kleene 
  star <tt class="operators">*</tt> which used to be a postfix operator in EBNF 
  becomes a prefix. Instead of:</p>
<pre>    <span class=identifier>a</span><span class=special>* </span><span class="comment">//... in EBNF syntax,</span></pre>
<p>we write:</p>
<pre><span class=special>    *</span><span class=identifier>a </span><span class="comment">//... in Spirit.</span></pre>
<p>since there are no postfix stars, &quot;<tt class="operators">*</tt>&quot;, in C/C++. Finally, 
  we terminate each rule with the ubiquitous semi-colon, &quot;<tt>;</tt>&quot;.</p>
<table border="0">
  <tr> 
    <td width="10"></td>
    <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
    <td width="30"><a href="preface.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
    <td width="20"><a href="quick_start.html"><img src="theme/r_arr.gif" border="0"></a></td>
  </tr>
</table>
<br>
<hr size="1">
<p class="copyright">Copyright &copy; 1998-2002 Joel de Guzman<br>
  <br>
  <font size="2">Permission to copy, use, modify, sell and distribute this document 
  is granted provided this copyright notice appears in all copies. This document 
  is provided &quot;as is&quot; without express or implied warranty, and with 
  no claim as to its suitability for any purpose. </font> </p>
<p>&nbsp;</p>
</body>
</html>