\section{gp\_\-parse\_\-tree Namespace Reference} \label{namespacegp__parse__tree}\index{gp_parse_tree@{gp\_\-parse\_\-tree}} Parse\_\-tree and subtree classes (c) copyright Maarten Keijzer 1999, 2000. \subsection*{Classes} \begin{CompactItemize} \item class {\bf gp\_\-parse\_\-tree::Mem\-Pool} \begin{CompactList}\small\item\em Pool allocator for the subtree and parse tree classes (homebrew and not compliant to ANSI allocator requirements) (c) copyright Maarten Keijzer 1999, 2000. \item\end{CompactList}\item struct {\bf gp\_\-parse\_\-tree::Mem\-Pool::Link} \item struct {\bf gp\_\-parse\_\-tree::Mem\-Pool::Chunk} \item class {\bf gp\_\-parse\_\-tree::Node\_\-alloc$<$ T $>$} \item class {\bf gp\_\-parse\_\-tree::Standard\_\-alloc$<$ T $>$} \item class {\bf gp\_\-parse\_\-tree::Standard\_\-Node\_\-alloc$<$ T $>$} \item class {\bf gp\_\-parse\_\-tree::Tree\_\-alloc$<$ T $>$} \item class {\bf gp\_\-parse\_\-tree::parse\_\-tree$<$ T $>$} \item class {\bf gp\_\-parse\_\-tree::parse\_\-tree$<$ T $>$::subtree} \item class {\bf gp\_\-parse\_\-tree::parse\_\-tree$<$ T $>$::base\_\-iterator} \item class {\bf gp\_\-parse\_\-tree::parse\_\-tree$<$ T $>$::iterator} \item class {\bf gp\_\-parse\_\-tree::parse\_\-tree$<$ T $>$::embedded\_\-iterator} \item class {\bf gp\_\-parse\_\-tree::parse\_\-tree$<$ T $>$::base\_\-const\_\-iterator} \item class {\bf gp\_\-parse\_\-tree::parse\_\-tree$<$ T $>$::const\_\-iterator} \item class {\bf gp\_\-parse\_\-tree::parse\_\-tree$<$ T $>$::embedded\_\-const\_\-iterator} \end{CompactItemize} \subsection*{Functions} \begin{CompactItemize} \item template$<$class T$>$ void {\bf do\_\-the\_\-swap} (T \&a, T \&b)\label{namespacegp__parse__tree_a0} \begin{CompactList}\small\item\em This ones defined because gcc does not always implement namespaces. \item\end{CompactList}\end{CompactItemize} \subsection{Detailed Description} Parse\_\-tree and subtree classes (c) copyright Maarten Keijzer 1999, 2000. Permission to copy, use, modify, sell and distribute this software is granted provided this copyright notice appears in all copies. This software is provided \char`\"{}as is\char`\"{} without express or implied warranty, and with no claim as to its suitability for any purpose. Permission to modify the code and to distribute modified code is granted, provided the above notices as well as this one are retained, and a notice that the code was modified is included with the above copyright notice. Usage information. class Node (your node in the tree) must have the following implemented: Arity $\ast$$\ast$$\ast$$\ast$$\ast$$\ast$ int arity(void) const Note: the default constructor of a Node should provide a Node with arity 0! Evaluation $\ast$$\ast$$\ast$$\ast$$\ast$$\ast$ A parse\_\-tree is evaluated through one of it's apply() members: 1) parse\_\-tree::apply(Ret\-Val) is the simplest evaluation, it will call Ret\-Val Node::operator()(Ret\-Val, subtree$<$Node, Ret\-Val$>$::const\_\-iterator) (Unfortunately the first Ret\-Val argument is mandatory (although you might not need it. This is because MSVC does not support member template functions properly. If it cannot deduce the template arguments (as is the case in templatizing over return value) you are not allowed to specify them. calling tree.apply$<$double$>$() would result in a syntax error. That is why you have to call tree.apply(double()) instead.) 2) parse\_\-tree::apply(Ret\-Val v, It values) will call: Ret\-Val Node::operator()(Ret\-Val, subtree$<$... , It values) where It is whatever type you desire (most of the time this will be a std::vector containing the values of your variables); 3) parse\_\-tree::apply(Ret\-Val, It values, It2 more\-Values) will call: Ret\-Val Node::operator()(Ret\-Val, subtree$<$... , It values, It2 more\-Values) although I do not see the immediate use of this, however... 4) parse\_\-tree::apply(Ret\-Val, It values, It2 args, It3 adfs) that calls: Ret\-Val Node::operator()(subtree$<$... , It values, It2 args, It3 adfs) can be useful for implementing adfs. In general it is a good idea to leave the specifics of the arguments open so that different ways of evaluation remain possible. Implement the simplest eval as: template $<$class it=\char`\"{}\char`\"{}$>$ Ret\-Val operator()(Ret\-Val dummy, It begin) const Internal Structure $\ast$$\ast$$\ast$$\ast$$\ast$$\ast$ A parse\_\-tree has two template arguments: the Node and the Return\-Value produced by evaluating the node. The structure of the tree is defined through a subtree class that has the same two template arguments. The nodes are stored in a tree like : node4 / $\backslash$ node3 node2 / $\backslash$ node1 node0 where nodes 2 and 4 have arity 2 and nodes 0,1 and 3 arity 0 (terminals) The nodes are subtrees, containing the structure of the tree, together with its size and depth. They contain a Node, the user defined template argument. To access these nodes from a subtree, use operator-$>$ or operator$\ast$. The numbers behind the nodes define a reverse-polish or postfix traversel through the tree. The parse\_\-tree defines iterators on the tree such that tree.begin() points at the subtree at node0 and tree.back() returns the subtree at node4, the complete tree Likewise operator[] is defined on the tree, such that: tree[0] will return the subtree at node0, while tree[2] will return the subtree at node2 Assigments of subtrees is protected so that the code: tree[2] = tree[0]; will not crash and result in a tree structured as: node4 / $\backslash$ node3 node0 Note that the rank numbers no longer specify their place in the tree: tree[0] still points at node0, but tree[1] now points to node3 and tree[2] points at the root node4 Embedded iterators are implemented to iterate over nodes rather than subtrees. So an easy way to copy your tree to a std::vector is: std::vector$<$Node$>$ vec(tree.size()); copy(tree.ebegin(), tree.eend(), vec.begin()); You can also copy it to an std::ostream\_\-iterator with this technique, given that your Node implements an appropriate operator$<$$<$. Reinitializing a tree with the std::vector is also simple: tree.clear(); copy(vec.begin(), vec.end(), back\_\-inserter(tree)); or from an std::istream: copy(std::istream\_\-iterator$<$T$>$(my\_\-stream), std::istream\_\-iterator$<$T$>$(), back\_\-inserter(tree)); Note that the back\_\-inserter must be used as there is no resize member in the parse\_\-tree. back\_\-inserter will use the push\_\-back member from the parse\_\-tree