Как использовать Spirit X3 парсинг в класс с конструктором, содержащим параметры? - PullRequest
1 голос
/ 31 октября 2019

Я новичок в использовании Spirit x3, я прочитал какой-то документ с официального сайта или из других репозиториев github. Но я не могу найти, как разобрать в класс с параметрами. Я ссылался на предыдущий вопрос: Разбор Boost-Spirit (X3) без конструкторов по умолчанию

Я написал пример для его тестирования, я представлю свои коды в следующей области. Моя боль состоит в том, как использовать x3 :: _ attr и как передать проанализированные параметры в конструктор класса?

#include <boost/spirit/home/x3.hpp>
#include  <iostream>
#include <vector>

 struct MyPair {
  MyPair(int x, int y) : mx(x), my(y) {};
  int mx;
  int my;
  };

 class MyDu {
   public:
    MyDu() {};
    MyDu(int x, int y) : mx(x), my(y) {};
     int mx;
     int my;
  };

  int main()
{
namespace x3 = boost::spirit::x3;
using x3::int_;

std::vector<MyPair> pairs;
MyDu myDu;
char const *first = "11:22", *last = first + std::strlen(first);

//auto pair = x3::rule<struct pair_, std::vector<MyPair> >{}
//  = (int_ >> ':' >> int_)
//  [([&](auto& ctx) {
//  auto& attr = x3::_attr(ctx);
//  using boost::fusion::at_c;
//  return x3::_val(ctx).emplace_back(at_c<0>(attr), at_c<1>(attr));
//      })]
//;
auto pair = x3::rule<class MyDu_, MyDu >{}
    = (int_ >> ':' >> int_)
    [([&](auto& ctx) {
    auto& attr = x3::_attr(ctx);
    using boost::fusion::at_c;
    //return x3::_val(ctx)(at_c<0>(attr), at_c<1>(attr));
    ctx = MyDu(at_c<0>(attr), at_c<1>(attr));
    return x3::_val(ctx);
        })]
;

//bool parsed_some = parse(first, last, pair % ',', pairs);
bool parsed_some = parse(first, last, pair, myDu);

if (parsed_some) {
    std::cout << "Parsed the following pairs" << std::endl;
    //for (auto& p : pairs) {
    //  std::cout << p.mx << ":" << p.my << std::endl;
    //}
    std::cout<<myDu.mx<<","<<myDu.my<<std::endl;
}

system("pause");

}

Любой, кто может исправить мою ошибку и проанализировать вкласс в моем коде? Спасибо!

Ответы [ 2 ]

1 голос
/ 01 ноября 2019

Возможно, вы упустили способ присвоения значению правила, используя _val:

Live On Coliru

#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <vector>

struct MyDu {
    MyDu(int x, int y) : mx(x), my(y){};
    int mx;
    int my;
};

int main() {
    namespace x3 = boost::spirit::x3;
    using x3::int_;

    MyDu myDu{1,2};
    std::string const s = "11:22";

    auto assign = [](auto& ctx) {
        using boost::fusion::at_c;
        auto& attr = x3::_attr(ctx);

        x3::_val(ctx) = MyDu(at_c<0>(attr), at_c<1>(attr));
    };

    auto pair = x3::rule<class MyDu_, MyDu>{} = (int_ >> ':' >> int_)[assign];

    if (parse(begin(s), end(s), pair, myDu)) {
        std::cout << "Parsed: " << myDu.mx << ", " << myDu.my << "\n";
    }
}

Отпечатки

Parsed: 11, 22
0 голосов
/ 01 ноября 2019

О, фантастика! Большое спасибо, sehe, вы помогаете мне решить проблему, которая беспокоит меня некоторое время. На самом деле я не могу найти документ по духу, как использовать attr, я только нахожу документ из "Рубен-Ван-Боксем-Parsing-CSS-in-C-with-Boost-Spirit-X3",

_val: ссылка на атрибут самого внутреннего правила, вызывающего _where: диапазон итератора синтаксического анализатора для входного потока _attr: ссылка на apassribute синтаксического анализатора _pass: ссылка на флаг bool, который можно использовать для принудительного применения синтаксического анализаторане может

не могли бы вы поделиться информацией об этих параметрах. Еще раз большое спасибо!

...