За последние пару недель я многое узнал об этом, но недостаточно. Код ниже компилируется и запускается, но код в TEST_ADAPT
неполный, я не уверен, как установить соединение.
Цель состоит в том, чтобы выполнить синтаксический анализ в контейнере плоскости jane, который не имеет зависимости от варианта. Я понял, что могу получить набор ссылок на свое хранилище, которое духу нравится достаточно хорошо. (см. TEST_REF
). Оператор клини ищет единый последовательный контейнер, но с набором альтернатив, который не представляется возможным. Поэтому я думаю, что мне нужно передать что-то, что является прокси-сервером для этого контейнера, но имеет механизм для определения местоположения в кортеже целевых ссылок.
Я думаю, для меня будет отличным упражнением написать это ContainerAdaptor
, даже если это неправильный подход к этому. Поэтому мне интересно, в правильном ли я поле или на правильном пути.
Лучшее, что я могу сделать, - это использовать метод TEST_VECT
и передать вектор, чтобы скопировать данные в мой контейнер ALL
. Но это просто неправильно.
Обновление:
Я сделал Target::All
fusion адаптированным и сделал ContainerAdaptor
частично функциональным. Достаточно, чтобы оператор клини принял это. Я должен иметь возможность подключиться к объекту Target :: All, может быть ...
#include <iostream>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/adapted.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
//parse kleene operator to a set of alternatives, adaptor? with spirit x3
#define TEST_VECT
#define TEST_REF
#define TEST_ADAPT
// l.......................................................................
namespace Target {
struct Int
{
int int_val;
};
using IntVect = std::vector<Int>;
struct Word
{
std::string word_val;
};
using WordVect = std::vector<Word>;
struct All
{
IntVect int_vect;
WordVect word_vect;
};
}
BOOST_FUSION_ADAPT_STRUCT(Target::Int, int_val)
BOOST_FUSION_ADAPT_STRUCT(Target::Word, word_val)
BOOST_FUSION_ADAPT_STRUCT(Target::All, int_vect, word_vect)
std::ostream& operator << (std::ostream& o, const Target::Int& in) { o << in.int_val; return o; }
std::ostream& operator << (std::ostream& o, const Target::Word& in) { o << in.word_val; return o; }
std::ostream& operator << (std::ostream& o, const Target::IntVect& in) { for( auto& i : in ) o << i << " "; return o; }
std::ostream& operator << (std::ostream& o, const Target::WordVect& in) { for (auto& i : in) o << i << " "; return o; }
#define DEF_RULE( RuleName, Attr ) static auto const RuleName = rule<struct Attr##_def, Attr>( #RuleName )
namespace Target {
using namespace boost::spirit::x3;
auto const bare_word = lexeme[+char_("a-z")];
DEF_RULE(int_rule, Int) = int_;
DEF_RULE(word_rule, Word) = bare_word;
auto const int_vect_rule= "int" >> *int_rule;
auto const word_vect_rule= "word" >> *(word_rule - "int");
//another test
DEF_RULE(f_int_vect_rule, IntVect) = int_vect_rule;
DEF_RULE(f_word_vect_rule, IntVect) = word_vect_rule;
}//namespace Target
namespace Target {
struct Printer {
Printer(std::ostream& out) : out(out) {};
using result_type = void;
void operator()(const IntVect& expression) {
out << "IntVect: ";
for (auto& t : expression)
out << t << " ";
out << std::endl;
}
void operator()(const WordVect& expression) {
out << "Word: ";
for (auto& t : expression)
out << t << " ";
out << std::endl;
}
private:
std::ostream& out;
};
}//namespace Target
template<class Arg>
class ContainerAdaptor
{
public:
ContainerAdaptor(Arg& arg) :arg(arg) { }
typedef boost::spirit::x3::variant<Target::IntVect,Target::WordVect> value_type;
typedef size_t size_type;
struct Vis : public boost::static_visitor<>
{
void operator()(const Target::IntVect & i) const
{
std::cout << i << std::endl;
}
void operator()(const Target::WordVect & i) const
{
std::cout << i << std::endl;
}
};
void insert(value_type* e, const value_type& v) {
std::cout << "haha! ";
boost::apply_visitor(Vis(), v);
}
value_type* end() { return nullptr; }
value_type* begin() { return nullptr; }
size_t size;
private:
Arg & arg;
};
int main()
{
using namespace Target;
std::string thestr("word test more int 1 2 3 4 word this and that int 5 4 int 99 22");
std::string::iterator end = thestr.end();
#if defined(TEST_ADAPT)
{
std::cout << "\nTEST_ADAPT\n";
std::string::iterator begin = thestr.begin();
All all;
auto fwd = std::forward_as_tuple(all.word_vect, all.int_vect);
ContainerAdaptor<All>attr( all );
phrase_parse(begin, end, *( int_vect_rule | word_vect_rule), space, attr);
Printer printer(std::cout);
}
#endif
#if defined(TEST_VECT)
{
std::cout << "TEST_VECT\n";
std::string::iterator begin = thestr.begin();
using Vars = variant<Target::IntVect, Target::WordVect>;
std::vector< Vars > a_vect;
bool r = phrase_parse(begin, end, *( int_vect_rule | word_vect_rule), space, a_vect);
Printer printer(std::cout);
for (auto& i : a_vect)
i.apply_visitor(printer);
}
#endif
#if defined(TEST_REF)
{
std::cout << "\nTEST_REF\n";
std::string::iterator begin = thestr.begin();
All all;
auto fwd = std::forward_as_tuple(all.word_vect,all.int_vect);
phrase_parse(begin, end, word_vect_rule >> int_vect_rule, space, fwd);
Printer printer(std::cout);
std::_For_each_tuple_element(fwd, printer);
}
#endif
return 0;
}