Bonsai
======
| Bonsai is an attempt to provide a miniature and refined representation
for the
| often cumbersome **syntax trees** and **program models**.
| This idea, of providing a *smaller tree* that is more or less the same
thing,
| is where the name comes from.
| This work started as part of an analysis tool that I am developing for
my own
| research. I am interested in analysing `ROS`_
| robotics applications, which are often written in C++.
| Since free C++ analysis tools are *rather scarce*, I tried
| to come up with my own, using the Python bindings of the ``clang``
compiler.
| At the moment of this writing, I am aware that these bindings are
incomplete
| in terms of AST information they provide.
| As this analysis tool developed, I realized that the C++ analysis
features
| are independent of ROS or any other framework, and that this kind of
tool
| might be useful for someone else, either as is, or as a starting point
for
| something else.
Features
--------
| Bonsai provides an interface to represent, analyse or manipulate
programs.
| The model it uses is abstract enough to serve as a basis for specific
language
| implementations, although it focuses more on
imperative/object-oriented
| languages for now.
What to expect from **bonsai**:
- classes for the different **entities of a program** (e.g. variables,
functions, etc.);
- extended classes for **specific programming languages** (only C++ for
now);
- **parser implementations**, able to take a file and produce a model
(e.g. ``clang`` for C++);
- extensible interface to **manipulate and query** the resulting model
(e.g. find calls for a function);
- a console script to use as a standalone application.
Installation
------------
| Here are some instructions to help you get bonsai.
| Bonsai has been tested with *Linux Ubuntu* and *Python 2.7*,
| but the platform should not make much of a difference.
| Dependencies are minimal, and depend on what you want to analyse.
| Since at the moment there is only a single implementation for C++
| using clang 3.8, you will need to install ``libclang`` and the
| `clang.cindex bindings`_
| (``pip install clang``) to parse C++ files. Skip this if you want to
use
| the library in any other way.
Method 1: Running Without Installation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Open a terminal, and move to a directory where you want to clone this
| repository.
.. code:: bash
git clone https://github.com/git-afsantos/bonsai.git
| There is an executable script in the root of this repository to help
you get started.
| It allows you to run bonsai without installing it. Make sure that your
terminal is at
| the root of the repository.
.. code:: bash
cd bonsai
python bonsai-runner.py <args>
You can also run it with the executable package syntax.
.. code:: bash
python -m bonsai <args>
Method 2: Installing Bonsai on Your Machine
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Bonsai is now available on `PyPi`_.
| You can install it from source or from a wheel.
.. code:: bash
[sudo] pip install bonsai-code
| The above command will install bonsai for you. Alternatively, download
and extract its
| source, move to the project’s root directory, and then execute the
following.
.. code:: bash
python setup.py install
| After installation, you should be able to run the command ``bonsai``
in your terminal
| from anywhere.
Examples
--------
| The ``cpp_example.py`` script at the root of this repository is a
small example on
| how to parse a C++ file and then find all references to a variable
``a`` in that file.
| In it, you can see parser creation
.. code:: python
parser = CppAstParser(workspace = "examples/cpp")
| access to the global (top level, or root) scope of the program, and
obtaining
| a pretty string representation of everything that goes in it
.. code:: python
parser.global_scope.pretty_str()
| getting a list of all references to variable ``a``, starting the
search from
| the top of the program (global scope)
.. code:: python
CodeQuery(parser.global_scope).all_references.where_name("a").get()
| and accessing diverse properties from the returned ``CodeReference``
objects,
| such as file line and column (``cppobj.line``, ``cppobj.column``), the
type of the
| object (``cppobj.result``), what is it a reference of
(``cppobj.reference``,
| in this case a ``CodeVariable``) and an attempt to interpret the
program and
| resolve the reference to a concrete value
(``resolve_reference(cppobj)``).
| Do note that **resolving expressions and references is still
experimental**,
| and more often that not will not be able to produce anything useful.
| This is the pretty string output for a program that defines a class
``C``
| and a couple of functions.
::
class C:
C():
[declaration]
void m(int a):
[declaration]
int x_ = None
C():
x_ = 0
void m(int a):
a = (a + 2) * 3
this.x_ = a
int main(int argc, char ** argv):
C c = new C()
c.m(42)
C * c1 = new C()
C * c2 = new C()
new C()
delete(c1)
delete(c2)
return 0
| The pretty string representation, as seen, is a sort of
pseudo-language, inspired
| in the Python syntax, even though the parsed program is originally in
C++.
| For more details on what you can get from the various program
entities, check out
| the source for the abstract model and then the language-specific
| implementation of your choice.
.. _ROS: http://www.ros.org/
.. _clang.cindex bindings: https://github.com/llvm-mirror/clang/tree/master/bindings/python
.. _PyPi: https://pypi.python.org/pypi/bonsai-code