Introduction
This tutorial is about developping software that embed the B Compiler library, ranging from metrics computation tool to code generator.
Ready for developping with B Compiler Library
The easiest way to proceed is to develop software in the directory that hosts the B Compiler. There are few steps to follow in order to be ready for developping with the B Compiler Library:
- create a new directory (for example: MyExample)
- edit the CMakeLists.txt file. It should read like:
project(bcomp) cmake_minimum_required(VERSION 2.4) add_subdirectory(STUB_DECOMPILER) add_subdirectory(RESOURCES) add_subdirectory(B_COMPILER) add_subdirectory(FIND_SPEC)
Add the following line:
add_subdirectory(MyExample)
- in the MyExample directory, create the CMakeLists.txt file and copy the following in it:
project(MyExample) include_directories(${BCOMP_SOURCE_DIR} ${DECOMP_SOURCE_DIR} ${RESOURCES_SOURCE_DIR} ) add_executable(MyExample MyExample.cpp) target_link_libraries(MyExample BCOMP STUB_DECOMP RES)
- in the MyExample directory, create the MyExample.cpp file and copy the following in it:
#include <c_port.h> #include <c_api.h> #include <c_path.h> #include <iostream> using namespace std; int function main(int argc, char* argv[]) { const string filename=argv[1]; cout << "Reading file: " << argv[1] << endl; T_betree *betree= compiler_syntax_analysis(filename.c_str()); }
To generate MyExample application:
- go to the directory that hosts the B Compiler (the one that contains the ReadMe.txt file).
- execute the command:
cmake -G "MinGW Makefiles"
You should get the following messages
-- Configuring done -- Generating done -- Build files have been written to: D:/DEV/TOOLS/bcomp
- execute the command:
make
You should get the following messages
[ 0%] Built target STUB_DECOMP [ 8%] Built target RES [ 97%] Built target BCOMP [ 98%] Built target BCOMP_EXE [ 99%] Built target find_spec Scanning dependencies of target MyExample [100%] Building CXX object MyExample/CMakeFiles/MyExample.dir/MyExample.obj Linking CXX executable MyExample.exe [100%] Built target MyExample
The MyExample executable file is located in the MyExample directory. MyExample requires one parameter that is the name of a B model which will be syntactly analyzed. If nothing is displayed then the B model is correct.
Navigating operations
Once a betree has been successfully built from a B model, it is possible to navigate it. In this section, navigation among operations is presented.
In the previous example, a betree is constructed when the function compiler_syntax_analysis is called. From that betree, we would like to get a reference to the top level machine:
T_machine *mch = betree->get_root();
This machine is then used to navigate operations:
T_op* operation=mch->get_operations(); while (operation != NULL) { string op_name=operation->get_op_name()->get_value(); cout << "Operation name : " << op_name << endl; operation = (T_op*)operation->get_next(); }
The resulting MyExample.cpp file is then compiled successfully.
Applied on the M1.mch model
MyExampleMyExample.exe M1.mch
the following messages are displayed:
Reading file: M1.mch Operation name : OP1 Operation name : OP2
Navigating substitutions
In this section, navigation among substitutions is presented.
In the previous example, operations are browsed sequentiall, through the get_next() function.
This operation is used to navigate substitutions:
T_substitution* subst=operation->get_body(); T_item* it_subst=(T_item*) subst; cout << " Substitution: "; while (it_subst!=NULL) { cout << it_subst->get_class_name(); it_subst=it_subst->get_next(); } cout << endl;
The execution of MyExample on M1.mch leads to the following messages:
Reading file: M1.mch Operation name : OP1 Substitution: T_begin Operation name : OP2 Substitution: T_select
The complete MyExample.cpp file is listed below:
#include <c_port.h> #include <c_api.h> #include <c_path.h> #include <iostream> using namespace std; int function main(int argc, char* argv[]) { const string filename=argv[1]; cout << "Reading file: " << argv[1] << endl; T_betree *betree= compiler_syntax_analysis(filename.c_str()); T_machine *mch = betree->get_root(); T_op* operation=mch->get_operations(); while (operation != NULL) { string op_name=operation->get_op_name()->get_value(); cout << "Operation name : " << op_name << endl; T_substitution* subst=operation->get_body(); T_item* it_subst=(T_item*) subst; cout << " Substitution: "; while (it_subst!=NULL) { cout << it_subst->get_class_name(); it_subst=it_subst->get_next(); } cout << endl; operation = (T_op*)operation->get_next(); } }