• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Introduction</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="../index.html" title="Spirit X3 3.0.4">
9<link rel="prev" href="preface.html" title="Preface">
10<link rel="next" href="include.html" title="Include">
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="preface.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="include.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h2 class="title" style="clear: both">
27<a name="spirit_x3.introduction"></a><a class="link" href="introduction.html" title="Introduction">Introduction</a>
28</h2></div></div></div>
29<p>
30      Boost Spirit X3 is an object-oriented, recursive-descent parser for C++. It
31      allows you to write grammars using a format similar to Extended Backus Naur
32      Form (EBNF)<a href="#ftn.spirit_x3.introduction.f0" class="footnote" name="spirit_x3.introduction.f0"><sup class="footnote">[1]</sup></a> directly in C++. These inline grammar specifications can mix freely
33      with other C++ code and, thanks to the generative power of C++ templates, are
34      immediately executable. Conventional compiler-compilers or parser-generators
35      have to perform an additional translation step from the source EBNF code to
36      C or C++ code.
37    </p>
38<p>
39      Since the target input grammars are written entirely in C++ we do not need
40      any separate tools to compile, preprocess or integrate those into the build
41      process. <a href="http://boost-spirit.com" target="_top">Spirit</a> allows seamless
42      integration of the parsing process with other C++ code. This often allows for
43      simpler and more efficient code.
44    </p>
45<p>
46      The created parsers are fully attributed, which allows you to easily build
47      and handle hierarchical data structures in memory. These data structures resemble
48      the structure of the input data and can directly be used to generate arbitrarily-formatted
49      output.
50    </p>
51<p>
52      A simple EBNF grammar snippet:
53    </p>
54<pre class="programlisting"><span class="identifier">group</span>       <span class="special">::=</span> <span class="char">'('</span> <span class="identifier">expression</span> <span class="char">')'</span>
55<span class="identifier">factor</span>      <span class="special">::=</span> <span class="identifier">integer</span> <span class="special">|</span> <span class="identifier">group</span>
56<span class="identifier">term</span>        <span class="special">::=</span> <span class="identifier">factor</span> <span class="special">((</span><span class="char">'*'</span> <span class="identifier">factor</span><span class="special">)</span> <span class="special">|</span> <span class="special">(</span><span class="char">'/'</span> <span class="identifier">factor</span><span class="special">))*</span>
57<span class="identifier">expression</span>  <span class="special">::=</span> <span class="identifier">term</span> <span class="special">((</span><span class="char">'+'</span> <span class="identifier">term</span><span class="special">)</span> <span class="special">|</span> <span class="special">(</span><span class="char">'-'</span> <span class="identifier">term</span><span class="special">))*</span>
58</pre>
59<p>
60      is approximated using facilities of Spirit's <span class="emphasis"><em>X3</em></span> as seen
61      in this code snippet:
62    </p>
63<pre class="programlisting"><span class="identifier">group</span>       <span class="special">=</span> <span class="char">'('</span> <span class="special">&gt;&gt;</span> <span class="identifier">expression</span> <span class="special">&gt;&gt;</span> <span class="char">')'</span><span class="special">;</span>
64<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>
65<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="char">'*'</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="char">'/'</span> <span class="special">&gt;&gt;</span> <span class="identifier">factor</span><span class="special">));</span>
66<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="char">'+'</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="char">'-'</span> <span class="special">&gt;&gt;</span> <span class="identifier">term</span><span class="special">));</span>
67</pre>
68<p>
69      Through the magic of expression templates, this is perfectly valid and executable
70      C++ code. The production rule <code class="computeroutput"><span class="identifier">expression</span></code>
71      is, in fact, an object that has a member function <code class="computeroutput"><span class="identifier">parse</span></code>
72      that does the work given a source code written in the grammar that we have
73      just declared. Yes, it's a calculator. We shall simplify for now by skipping
74      the type declarations and the definition of the rule <code class="computeroutput"><span class="identifier">integer</span></code>
75      invoked by <code class="computeroutput"><span class="identifier">factor</span></code>. Now, the
76      production rule <code class="computeroutput"><span class="identifier">expression</span></code>
77      in our grammar specification, traditionally called the <code class="computeroutput"><span class="identifier">start</span></code>
78      symbol, can recognize inputs such as:
79    </p>
80<pre class="programlisting"><span class="number">12345</span>
81<span class="special">-</span><span class="number">12345</span>
82<span class="special">+</span><span class="number">12345</span>
83<span class="number">1</span> <span class="special">+</span> <span class="number">2</span>
84<span class="number">1</span> <span class="special">*</span> <span class="number">2</span>
85<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>
86<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>
87<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>
88<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>
89<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>
90<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>
91<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>
92</pre>
93<p>
94      Certainly we have modified the original EBNF syntax. This is done to conform
95      to C++ syntax rules. Most notably we see the abundance of shift &gt;&gt; operators.
96      Since there are no juxtaposition operators in C++, it is simply not possible
97      to write something like:
98    </p>
99<pre class="programlisting"><span class="identifier">a</span> <span class="identifier">b</span>
100</pre>
101<p>
102      as seen in math syntax, for example, to mean multiplication or, in our case,
103      as seen in EBNF syntax to mean sequencing (b should follow a). <span class="emphasis"><em>Spirit.X3</em></span>
104      uses the shift <code class="computeroutput"><span class="special">&gt;&gt;</span></code> operator
105      instead for this purpose. We take the <code class="computeroutput"><span class="special">&gt;&gt;</span></code>
106      operator, with arrows pointing to the right, to mean "is followed by".
107      Thus we write:
108    </p>
109<pre class="programlisting"><span class="identifier">a</span> <span class="special">&gt;&gt;</span> <span class="identifier">b</span>
110</pre>
111<p>
112      The alternative operator <code class="computeroutput"><span class="special">|</span></code> and
113      the parentheses <code class="computeroutput"><span class="special">()</span></code> remain as is.
114      The assignment operator <code class="computeroutput"><span class="special">=</span></code> is used
115      in place of EBNF's <code class="computeroutput"><span class="special">::=</span></code>. Last but
116      not least, the Kleene star <code class="computeroutput"><span class="special">*</span></code>,
117      which in this case is a postfix operator in EBNF becomes a prefix. Instead
118      of:
119    </p>
120<pre class="programlisting"><span class="identifier">a</span><span class="special">*</span> <span class="comment">//... in EBNF syntax,</span>
121</pre>
122<p>
123      we write:
124    </p>
125<pre class="programlisting"><span class="special">*</span><span class="identifier">a</span> <span class="comment">//... in Spirit.</span>
126</pre>
127<p>
128      since there are no postfix stars, <code class="computeroutput"><span class="special">*</span></code>,
129      in C/C++. Finally, we terminate each rule with the ubiquitous semi-colon,
130      <code class="computeroutput"><span class="special">;</span></code>.
131    </p>
132<div class="footnotes">
133<br><hr style="width:100; text-align:left;margin-left: 0">
134<div id="ftn.spirit_x3.introduction.f0" class="footnote"><p><a href="#spirit_x3.introduction.f0" class="para"><sup class="para">[1] </sup></a>
135        <a href="http://www.cl.cam.ac.uk/%7Emgk25/iso-14977.pdf" target="_top">ISO-EBNF</a>
136      </p></div>
137</div>
138</div>
139<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
140<td align="left"></td>
141<td align="right"><div class="copyright-footer">Copyright © 2001-2018 Joel de Guzman,
142      Hartmut Kaiser<p>
143        Distributed under the Boost Software License, Version 1.0. (See accompanying
144        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>)
145      </p>
146</div></td>
147</tr></table>
148<hr>
149<div class="spirit-nav">
150<a accesskey="p" href="preface.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="include.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
151</div>
152</body>
153</html>
154