Moved to header
parent
f035b12f46
commit
0e48e2ff0b
131
wrap/Class.h
131
wrap/Class.h
|
@ -19,6 +19,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "spirit.h"
|
||||
#include "Template.h"
|
||||
#include "Constructor.h"
|
||||
#include "Deconstructor.h"
|
||||
|
@ -26,6 +27,18 @@
|
|||
#include "StaticMethod.h"
|
||||
#include "TypeAttributesTable.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#endif
|
||||
#include <boost/lambda/bind.hpp>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
namespace bl = boost::lambda;
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
@ -145,5 +158,123 @@ private:
|
|||
void comment_fragment(FileWriter& proxyFile) const;
|
||||
};
|
||||
|
||||
/* ************************************************************************* */
|
||||
// http://boost-spirit.com/distrib/spirit_1_8_2/libs/spirit/doc/grammar.html
|
||||
struct ClassGrammar: public classic::grammar<ClassGrammar> {
|
||||
|
||||
Class& result_; ///< successful parse will be placed in here
|
||||
|
||||
/// Construct type grammar and specify where result is placed
|
||||
ClassGrammar(Class& result) :
|
||||
result_(result) {
|
||||
}
|
||||
|
||||
/// Definition of type grammar
|
||||
template<typename ScannerT>
|
||||
struct definition: BasicRules<ScannerT> {
|
||||
|
||||
using BasicRules<ScannerT>::name_p;
|
||||
using BasicRules<ScannerT>::className_p;
|
||||
using BasicRules<ScannerT>::comments_p;
|
||||
|
||||
// NOTE: allows for pointers to all types
|
||||
ArgumentList args;
|
||||
ArgumentListGrammar argumentList_g;
|
||||
|
||||
Constructor constructor0, constructor;
|
||||
|
||||
ReturnValue retVal0, retVal;
|
||||
ReturnValueGrammar returnValue_g;
|
||||
|
||||
// template<CALIBRATION = {gtsam::Cal3DS2}>
|
||||
Template methodTemplate, classTemplate;
|
||||
TemplateGrammar methodTemplate_g, classTemplate_g;
|
||||
|
||||
std::string methodName;
|
||||
bool isConst, T, F;
|
||||
|
||||
// Parent class
|
||||
Qualified possibleParent;
|
||||
TypeGrammar classParent_p;
|
||||
|
||||
classic::rule<ScannerT> templateList_p, constructor_p, methodName_p,
|
||||
method_p, staticMethodName_p, static_method_p, functions_p, class_p;
|
||||
|
||||
definition(ClassGrammar const& self) :
|
||||
argumentList_g(args), returnValue_g(retVal), //
|
||||
methodTemplate_g(methodTemplate), classTemplate_g(classTemplate), //
|
||||
T(true), F(false), classParent_p(possibleParent) {
|
||||
|
||||
using namespace classic;
|
||||
bool verbose = false; // TODO
|
||||
|
||||
// template<POSE, POINT>
|
||||
templateList_p = (str_p("template") >> '<'
|
||||
>> name_p[push_back_a(self.result_.templateArgs)]
|
||||
>> *(',' >> name_p[push_back_a(self.result_.templateArgs)]) >> '>');
|
||||
|
||||
// parse class constructor
|
||||
constructor_p =
|
||||
(className_p >> argumentList_g >> ';' >> !comments_p)[bl::bind(
|
||||
&Constructor::push_back, bl::var(constructor), bl::var(args))][clear_a(
|
||||
args)];
|
||||
|
||||
// TODO why is this not used anywhere?
|
||||
// vector<string> namespaces_return; /// namespace for current return type
|
||||
// Rule namespace_ret_p = namespace_p[push_back_a(namespaces_return)]
|
||||
// >> str_p("::");
|
||||
|
||||
methodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')];
|
||||
|
||||
// gtsam::Values retract(const gtsam::VectorValues& delta) const;
|
||||
method_p = !methodTemplate_g
|
||||
>> (returnValue_g >> methodName_p[assign_a(methodName)]
|
||||
>> argumentList_g >> !str_p("const")[assign_a(isConst, T)] >> ';'
|
||||
>> *comments_p) //
|
||||
[bl::bind(&Class::addMethod, bl::var(self.result_), verbose,
|
||||
bl::var(isConst), bl::var(methodName), bl::var(args),
|
||||
bl::var(retVal), bl::var(methodTemplate))] //
|
||||
[assign_a(retVal, retVal0)] //
|
||||
[clear_a(args)][clear_a(methodTemplate)] //
|
||||
[assign_a(isConst, F)];
|
||||
|
||||
staticMethodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')];
|
||||
|
||||
static_method_p = (str_p("static") >> returnValue_g
|
||||
>> staticMethodName_p[assign_a(methodName)] >> argumentList_g >> ';'
|
||||
>> *comments_p) //
|
||||
[bl::bind(&StaticMethod::addOverload,
|
||||
bl::var(self.result_.static_methods)[bl::var(methodName)],
|
||||
bl::var(methodName), bl::var(args), bl::var(retVal), boost::none,
|
||||
verbose)] //
|
||||
[assign_a(retVal, retVal0)][clear_a(args)];
|
||||
|
||||
functions_p = constructor_p | method_p | static_method_p;
|
||||
|
||||
// parse a full class
|
||||
class_p = (!(classTemplate_g[push_back_a(self.result_.templateArgs,
|
||||
classTemplate.argName())] | templateList_p)
|
||||
>> !(str_p("virtual")[assign_a(self.result_.isVirtual, true)])
|
||||
>> str_p("class") >> className_p[assign_a(self.result_.name_)]
|
||||
>> ((':' >> classParent_p >> '{')[bl::bind(&Class::assignParent,
|
||||
bl::var(self.result_), bl::var(possibleParent))][clear_a(
|
||||
possibleParent)] | '{') >> *(functions_p | comments_p)
|
||||
>> str_p("};")) //
|
||||
[bl::bind(&Constructor::initializeOrCheck, bl::var(constructor),
|
||||
bl::var(self.result_.name_), boost::none, verbose)][assign_a(
|
||||
self.result_.constructor, constructor)] //
|
||||
[assign_a(self.result_.deconstructor.name, self.result_.name_)] //
|
||||
[clear_a(classTemplate)] //
|
||||
[assign_a(constructor, constructor0)];
|
||||
}
|
||||
|
||||
classic::rule<ScannerT> const& start() const {
|
||||
return class_p;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
// ClassGrammar
|
||||
|
||||
} // \namespace wrap
|
||||
|
||||
|
|
|
@ -82,155 +82,6 @@ TEST( Class, TemplatedMethods ) {
|
|||
EXPECT(cls.exists(name+"Point3"));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
#include "../Module.h"
|
||||
#include "../FileWriter.h"
|
||||
#include "../TypeAttributesTable.h"
|
||||
#include "../utilities.h"
|
||||
|
||||
//#define BOOST_SPIRIT_DEBUG
|
||||
#include "../spirit.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#endif
|
||||
#include <boost/lambda/bind.hpp>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#include <boost/lambda/construct.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
using namespace wrap;
|
||||
using namespace BOOST_SPIRIT_CLASSIC_NS;
|
||||
namespace bl = boost::lambda;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
// http://boost-spirit.com/distrib/spirit_1_8_2/libs/spirit/doc/grammar.html
|
||||
struct ClassGrammar: public classic::grammar<ClassGrammar> {
|
||||
|
||||
Class& result_; ///< successful parse will be placed in here
|
||||
|
||||
/// Construct type grammar and specify where result is placed
|
||||
ClassGrammar(Class& result) :
|
||||
result_(result) {
|
||||
}
|
||||
|
||||
/// Definition of type grammar
|
||||
template<typename ScannerT>
|
||||
struct definition: BasicRules<ScannerT> {
|
||||
|
||||
using BasicRules<ScannerT>::name_p;
|
||||
using BasicRules<ScannerT>::className_p;
|
||||
using BasicRules<ScannerT>::comments_p;
|
||||
|
||||
// NOTE: allows for pointers to all types
|
||||
ArgumentList args;
|
||||
ArgumentListGrammar argumentList_g;
|
||||
|
||||
Constructor constructor0, constructor;
|
||||
|
||||
ReturnValue retVal0, retVal;
|
||||
ReturnValueGrammar returnValue_g;
|
||||
|
||||
// template<CALIBRATION = {gtsam::Cal3DS2}>
|
||||
Template methodTemplate, classTemplate;
|
||||
TemplateGrammar methodTemplate_g, classTemplate_g;
|
||||
|
||||
string methodName;
|
||||
bool isConst, T, F;
|
||||
|
||||
// Parent class
|
||||
Qualified possibleParent;
|
||||
TypeGrammar classParent_p;
|
||||
|
||||
classic::rule<ScannerT> templateList_p, constructor_p, methodName_p,
|
||||
method_p, staticMethodName_p, static_method_p, functions_p, class_p;
|
||||
|
||||
definition(ClassGrammar const& self) :
|
||||
argumentList_g(args), returnValue_g(retVal), //
|
||||
methodTemplate_g(methodTemplate), classTemplate_g(classTemplate), //
|
||||
T(true), F(false), classParent_p(possibleParent) {
|
||||
|
||||
using namespace classic;
|
||||
bool verbose = false; // TODO
|
||||
|
||||
// template<POSE, POINT>
|
||||
templateList_p = (str_p("template") >> '<'
|
||||
>> name_p[push_back_a(self.result_.templateArgs)]
|
||||
>> *(',' >> name_p[push_back_a(self.result_.templateArgs)]) >> '>');
|
||||
|
||||
// parse class constructor
|
||||
constructor_p =
|
||||
(className_p >> argumentList_g >> ';' >> !comments_p)[bl::bind(
|
||||
&Constructor::push_back, bl::var(constructor), bl::var(args))][clear_a(
|
||||
args)];
|
||||
|
||||
// TODO why is this not used anywhere?
|
||||
// vector<string> namespaces_return; /// namespace for current return type
|
||||
// Rule namespace_ret_p = namespace_p[push_back_a(namespaces_return)]
|
||||
// >> str_p("::");
|
||||
|
||||
methodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')];
|
||||
|
||||
// gtsam::Values retract(const gtsam::VectorValues& delta) const;
|
||||
method_p = !methodTemplate_g
|
||||
>> (returnValue_g >> methodName_p[assign_a(methodName)]
|
||||
>> argumentList_g >> !str_p("const")[assign_a(isConst, T)] >> ';'
|
||||
>> *comments_p) //
|
||||
[bl::bind(&Class::addMethod, bl::var(self.result_), verbose,
|
||||
bl::var(isConst), bl::var(methodName), bl::var(args),
|
||||
bl::var(retVal), bl::var(methodTemplate))] //
|
||||
[assign_a(retVal, retVal0)] //
|
||||
[clear_a(args)][clear_a(methodTemplate)] //
|
||||
[assign_a(isConst, F)];
|
||||
|
||||
staticMethodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')];
|
||||
|
||||
static_method_p = (str_p("static") >> returnValue_g
|
||||
>> staticMethodName_p[assign_a(methodName)] >> argumentList_g >> ';'
|
||||
>> *comments_p) //
|
||||
[bl::bind(&StaticMethod::addOverload,
|
||||
bl::var(self.result_.static_methods)[bl::var(methodName)],
|
||||
bl::var(methodName), bl::var(args), bl::var(retVal), boost::none,
|
||||
verbose)] //
|
||||
[assign_a(retVal, retVal0)][clear_a(args)];
|
||||
|
||||
functions_p = constructor_p | method_p | static_method_p;
|
||||
|
||||
// parse a full class
|
||||
class_p = (!(classTemplate_g[push_back_a(self.result_.templateArgs,
|
||||
classTemplate.argName())] | templateList_p)
|
||||
>> !(str_p("virtual")[assign_a(self.result_.isVirtual, true)])
|
||||
>> str_p("class") >> className_p[assign_a(self.result_.name_)]
|
||||
>> ((':' >> classParent_p >> '{')[bl::bind(&Class::assignParent,
|
||||
bl::var(self.result_), bl::var(possibleParent))][clear_a(
|
||||
possibleParent)] | '{') >> *(functions_p | comments_p)
|
||||
>> str_p("};")) //
|
||||
[bl::bind(&Constructor::initializeOrCheck, bl::var(constructor),
|
||||
bl::var(self.result_.name_), boost::none, verbose)][assign_a(
|
||||
self.result_.constructor, constructor)] //
|
||||
[assign_a(self.result_.deconstructor.name, self.result_.name_)] //
|
||||
[clear_a(classTemplate)] //
|
||||
[assign_a(constructor, constructor0)];
|
||||
}
|
||||
|
||||
classic::rule<ScannerT> const& start() const {
|
||||
return class_p;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
// ClassGrammar
|
||||
|
||||
//******************************************************************************
|
||||
TEST( Class, Grammar ) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue