1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>The Parse Tree Module</title><link rel="stylesheet" href="synopsis.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.65.1"><link rel="home" href="index.html" title="Synopsis Developer's Guide"><link rel="up" href="cxx.html" title="Chapter3.The C++ API"><link rel="previous" href="cxx.html" title="Chapter3.The C++ API"><link rel="next" href="symbol-lookup.html" title="The Symbol Lookup Module"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">The Parse Tree Module</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="cxx.html">Prev</a></td><th width="60%" align="center">Chapter3.The C++ API</th><td width="20%" align="right"><a accesskey="n" href="symbol-lookup.html">Next</a></td></tr></table></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ptree"></a>The Parse Tree Module</h2></div></div><div></div></div><p>
The parser's principal role is to generate a parse tree. It does that by
following language-specific production rules that are followed after
encountering lexical tokens that are provided by a lexer.
</p><p>
By means of construction flags it is possible to tell the lexer to accept
e.g. 'class' as a keyword (C++) or as an identifier (C). Similarly, it is
possible to configure the parser for particular rules.
</p><p>
The parse tree itself is a lisp-like structure. All nodes subclass
<span class="type">PTree::Atom</span> (for terminals) or <span class="type">PTree::List</span>
(for non-terminals). A <span class="type">Visitor</span> allows to traverse the parse
tree based on the real run-time types of the individual nodes (there are
about 120 different <span class="type">PTree::Node</span> types).
</p><div class="mediaobject"><img src="images/parser-scheme.png"></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="encoding"></a>The Encoding class</h3></div></div><div></div></div><p>
The C++ grammar makes it quite hard to recover certain semantic information
from syntactic structure. For example, in a simple declaration individual
declarators may carry part of the type information for the variables they
declare. For example,
</p><pre class="programlisting">
char *a, b, c[3];
</pre><p>
three declarators <span class="emphasis"><em>a</em></span>, <span class="emphasis"><em>b</em></span>, and
<span class="emphasis"><em>c</em></span>. The first has type <tt class="code">char *</tt>, the second
<tt class="code">char</tt>, the third <tt class="code">char[3]</tt>. In order to avoid the
need to analyze the whole declaration to extract the type of a declarator,
the parser attaches the type and name to declarators.
</p><p>
A similar argument applies to other cases, where non-local information
is encoded into a node's <tt class="code">encoded_name</tt> and <tt class="code">encoded_type</tt>
member.
</p><p>
The Encoding class needs to be able to represent full type names, and
thus it seems sensible to use a mangling similar (or even identical !)
to the one developed as part of the C++ ABI standard (see
<a href="http://www.codesourcery.com/cxx-abi/abi.html#mangling" target="_top">C++ ABI</a>).
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="ptree-display"></a>PTree::Display</h3></div></div><div></div></div><p>
Parse Trees tend to grow quickly, and it becomes quickly hard to debug them by
simply traversing the list. Thus, the <tt class="code">PTree</tt> module provides a simple
means to print a (sub-)tree to an output stream.
</p><p>
</p><pre class="programlisting">
PTree::display(node, std::cout, false, false);
</pre><p>
will print the tree referred to by <tt class="varname">node</tt> to <tt class="varname">std::cout</tt>.
The third parameter is a flag indicating whether the encodings should be printed, too.
The fourth parameter indicates, whether the actual C++ type of the node being printed should
be included in the output.
</p><p>
Since this API turned out to be rather useful, there is a stand-alone applet that just
generates a parse tree and then prints it out using the above function.
</p><pre class="programlisting">
display-ptree [-g <output>] [-d] [-r] [-e] <input>
</pre><p>
The available options are:
</p><div class="variablelist"><dl><dt><span class="term">-g <tt class="option">filename</tt></span></dt><dd><p>Generate a <span class="emphasis"><em>dot</em></span> graph and write it to the given file.</p></dd><dt><span class="term">-d</span></dt><dd><p>Print debug information (in particular traces) during the parsing.</p></dd><dt><span class="term">-r</span></dt><dd><p>Print the C++ type of the parse tree nodes.</p></dd><dt><span class="term">-e</span></dt><dd><p>Print encoded names / types for nodes such as names, declarators, etc..</p></dd></dl></div></div></div><div class="navfooter"><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="cxx.html">Prev</a></td><td width="20%" align="center"><a accesskey="u" href="cxx.html">Up</a></td><td width="40%" align="right"><a accesskey="n" href="symbol-lookup.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter3.The C++ API</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">The Symbol Lookup Module</td></tr></table></div></body></html>
|